fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 101 lines 2.6 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.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}