fork of hey-api/openapi-ts because I need some additional things
1import type { AnalysisContext } from '@hey-api/codegen-core';
2
3import { py } from '../../ts-python';
4import type { MaybePyDsl } from '../base';
5import { PyDsl } from '../base';
6import type { DoExpr } from '../mixins/do';
7import { BlockPyDsl } from './block';
8
9const Mixed = PyDsl<py.ForStatement>;
10
11export class ForPyDsl extends Mixed {
12 readonly '~dsl' = 'ForPyDsl';
13
14 protected _body?: Array<DoExpr>;
15 protected _else?: Array<DoExpr>;
16 protected _iterable?: MaybePyDsl<py.Expression>;
17 protected _target?: MaybePyDsl<py.Expression>;
18
19 constructor(
20 target: MaybePyDsl<py.Expression>,
21 iterable: MaybePyDsl<py.Expression>,
22 ...body: Array<DoExpr>
23 ) {
24 super();
25 this._target = target;
26 this._iterable = iterable;
27 this._body = body;
28 }
29
30 override analyze(ctx: AnalysisContext): void {
31 super.analyze(ctx);
32
33 if (this._target) ctx.analyze(this._target);
34 if (this._iterable) ctx.analyze(this._iterable);
35
36 if (this._body) {
37 ctx.pushScope();
38 try {
39 for (const stmt of this._body) ctx.analyze(stmt);
40 } finally {
41 ctx.popScope();
42 }
43 }
44
45 if (this._else) {
46 ctx.pushScope();
47 try {
48 for (const stmt of this._else) ctx.analyze(stmt);
49 } finally {
50 ctx.popScope();
51 }
52 }
53 }
54
55 /** Returns true when all required builder calls are present. */
56 get isValid(): boolean {
57 return this.missingRequiredCalls().length === 0;
58 }
59
60 body(...items: Array<DoExpr>): this {
61 this._body = items;
62 return this;
63 }
64
65 else(...items: Array<DoExpr>): this {
66 this._else = items;
67 return this;
68 }
69
70 override toAst(): py.ForStatement {
71 this.$validate();
72
73 const body = new BlockPyDsl(...this._body!).$do();
74 const elseBlock = this._else ? new BlockPyDsl(...this._else).$do() : undefined;
75
76 return py.factory.createForStatement(
77 this.$node(this._target!) as py.Expression,
78 this.$node(this._iterable!) as py.Expression,
79 [...body],
80 elseBlock ? [...elseBlock] : undefined,
81 );
82 }
83
84 $validate(): asserts this is this & {
85 _body: Array<DoExpr>;
86 _iterable: MaybePyDsl<py.Expression>;
87 _target: MaybePyDsl<py.Expression>;
88 } {
89 const missing = this.missingRequiredCalls();
90 if (missing.length === 0) return;
91 throw new Error(`For statement missing ${missing.join(' and ')}`);
92 }
93
94 private missingRequiredCalls(): ReadonlyArray<string> {
95 const missing: Array<string> = [];
96 if (!this._target) missing.push('target');
97 if (!this._iterable) missing.push('iterable');
98 if (!this._body || this._body.length === 0) missing.push('body');
99 return missing;
100 }
101}