import type { AnalysisContext, NodeName, Ref } from '@hey-api/codegen-core'; import { ref } from '@hey-api/codegen-core'; import { py } from '../../py-compiler'; import type { MaybePyDsl } from '../base'; import { PyDsl } from '../base'; import { ArgsMixin } from '../mixins/args'; import { ExprMixin } from '../mixins/expr'; import { f } from '../utils/factories'; export type CallArgs = ReadonlyArray; export type CallCallee = NodeName | MaybePyDsl; export type CallCtor = (callee: CallCallee, ...args: CallArgs) => CallPyDsl; const Mixed = ArgsMixin(ExprMixin(PyDsl)); export class CallPyDsl extends Mixed { readonly '~dsl' = 'CallPyDsl'; protected _callee: Ref; constructor(callee: CallCallee, ...args: CallArgs) { super(); this._callee = ref(callee); this.args(...args); } override analyze(ctx: AnalysisContext): void { super.analyze(ctx); ctx.analyze(this._callee); } /** Returns true when all required builder calls are present. */ get isValid(): boolean { return !this.missingRequiredCalls().length; } override toAst() { this.$validate(); return py.factory.createCallExpression(this.$node(this._callee!), this.$args()); } $validate(): asserts this is this & { _callee: MaybePyDsl; } { const missing = this.missingRequiredCalls(); if (!missing.length) return; throw new Error(`Call expression missing ${missing.join(' and ')}`); } private missingRequiredCalls(): ReadonlyArray { const missing: Array = []; if (!this._callee) missing.push('callee'); return missing; } } f.call.set((...args) => new CallPyDsl(...args));