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