fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 91 lines 2.4 kB view raw
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}