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.WhileStatement>;
10
11export class WhilePyDsl extends Mixed {
12 readonly '~dsl' = 'WhilePyDsl';
13
14 protected _body?: Array<DoExpr>;
15 protected _condition?: MaybePyDsl<py.Expression>;
16 protected _else?: Array<DoExpr>;
17
18 constructor(condition: MaybePyDsl<py.Expression>, ...body: Array<DoExpr>) {
19 super();
20 this._condition = condition;
21 this._body = body;
22 }
23
24 override analyze(ctx: AnalysisContext): void {
25 super.analyze(ctx);
26
27 if (this._condition) ctx.analyze(this._condition);
28
29 if (this._body) {
30 ctx.pushScope();
31 try {
32 for (const stmt of this._body) ctx.analyze(stmt);
33 } finally {
34 ctx.popScope();
35 }
36 }
37
38 if (this._else) {
39 ctx.pushScope();
40 try {
41 for (const stmt of this._else) ctx.analyze(stmt);
42 } finally {
43 ctx.popScope();
44 }
45 }
46 }
47
48 /** Returns true when all required builder calls are present. */
49 get isValid(): boolean {
50 return this.missingRequiredCalls().length === 0;
51 }
52
53 body(...items: Array<DoExpr>): this {
54 this._body = items;
55 return this;
56 }
57
58 else(...items: Array<DoExpr>): this {
59 this._else = items;
60 return this;
61 }
62
63 override toAst(): py.WhileStatement {
64 this.$validate();
65
66 const body = new BlockPyDsl(...this._body!).$do();
67 const elseBlock = this._else ? new BlockPyDsl(...this._else).$do() : undefined;
68
69 return py.factory.createWhileStatement(
70 this.$node(this._condition!) as py.Expression,
71 [...body],
72 elseBlock ? [...elseBlock] : undefined,
73 );
74 }
75
76 $validate(): asserts this is this & {
77 _body: Array<DoExpr>;
78 _condition: MaybePyDsl<py.Expression>;
79 } {
80 const missing = this.missingRequiredCalls();
81 if (missing.length === 0) return;
82 throw new Error(`While statement missing ${missing.join(' and ')}`);
83 }
84
85 private missingRequiredCalls(): ReadonlyArray<string> {
86 const missing: Array<string> = [];
87 if (!this._condition) missing.push('condition');
88 if (!this._body || this._body.length === 0) missing.push('body');
89 return missing;
90 }
91}