fork of hey-api/openapi-ts because I need some additional things
1import type { AnalysisContext, NodeName, NodeNameSanitizer } from '@hey-api/codegen-core';
2import { isSymbol } from '@hey-api/codegen-core';
3
4import { py } from '../../py-compiler';
5import { PyDsl } from '../base';
6import { DecoratorMixin } from '../mixins/decorator';
7import { DoMixin } from '../mixins/do';
8import { DocMixin } from '../mixins/doc';
9import { LayoutMixin } from '../mixins/layout';
10import { AsyncMixin, ExportMixin } from '../mixins/modifiers';
11import { ParamMixin } from '../mixins/param';
12import { ReturnsMixin } from '../mixins/returns';
13import { safeRuntimeName } from '../utils/name';
14
15const Mixed = AsyncMixin(
16 DecoratorMixin(
17 DocMixin(
18 DoMixin(ExportMixin(LayoutMixin(ParamMixin(ReturnsMixin(PyDsl<py.FunctionDeclaration>))))),
19 ),
20 ),
21);
22
23export class FuncPyDsl extends Mixed {
24 readonly '~dsl' = 'FuncPyDsl';
25 override readonly nameSanitizer: NodeNameSanitizer;
26
27 constructor(
28 name: NodeName,
29 fn?: (f: FuncPyDsl) => void,
30 options?: { nameSanitizer?: NodeNameSanitizer },
31 ) {
32 super();
33 this.nameSanitizer = options?.nameSanitizer ?? safeRuntimeName;
34 this.name.set(name);
35 if (isSymbol(name)) {
36 name.setKind('function');
37 }
38 fn?.(this);
39 }
40
41 override analyze(ctx: AnalysisContext): void {
42 ctx.pushScope();
43 try {
44 super.analyze(ctx);
45 ctx.analyze(this.name);
46 } finally {
47 ctx.popScope();
48 }
49 }
50
51 /** Returns true when all required builder calls are present. */
52 get isValid(): boolean {
53 return !this.missingRequiredCalls().length;
54 }
55
56 override toAst() {
57 this.$validate();
58 return py.factory.createFunctionDeclaration(
59 this.name.toString(),
60 this.$params(),
61 this.$returns(),
62 this.$do(),
63 this.$decorators(),
64 this.$docs(),
65 this.modifiers,
66 );
67 }
68
69 $validate(): asserts this {
70 const missing = this.missingRequiredCalls();
71 if (!missing.length) return;
72 throw new Error(`Function declaration missing ${missing.join(' and ')}`);
73 }
74
75 private missingRequiredCalls(): ReadonlyArray<string> {
76 const missing: Array<string> = [];
77 if (!this.name.toString()) missing.push('name');
78 return missing;
79 }
80}