fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #3510 from hey-api/fix/py-dsl-decorator

fix: correctly render decorators

authored by

Lubos and committed by
GitHub
32edd131 02e5991d

+39 -41
+10 -12
packages/openapi-python/src/plugins/@hey-api/sdk/v1/node.ts
··· 68 68 plugin.config.operations.methodName.casing ?? 'camelCase', 69 69 ); 70 70 const memberName = plugin.symbol(memberNameStr); 71 + const cachedProp = plugin.external('functools.cached_property'); 72 + 71 73 return [ 72 - $.func( 73 - memberName, 74 - (f) => f.returns('None'), 75 - // f.returns(refChild).do( 76 - // $('this') 77 - // .attr(privateName) 78 - // .nullishAssign( 79 - // $.new(refChild).args($.object().prop('client', $('this').attr('client'))), 80 - // ) 81 - // .return(), 82 - // ), 83 - ), 74 + $.func(memberName) 75 + .decorator(cachedProp) 76 + .returns(refChild) 77 + .do( 78 + $(refChild) 79 + .call($.kwarg('client', $('self').attr('client'))) 80 + .return(), 81 + ), 84 82 ]; 85 83 } 86 84
+8
packages/openapi-python/src/plugins/@hey-api/sdk/v1/plugin.ts
··· 20 20 }, 21 21 }); 22 22 23 + plugin.symbol('cached_property', { 24 + external: 'functools', 25 + meta: { 26 + category: 'external', 27 + resource: 'functools.cached_property', 28 + }, 29 + }); 30 + 23 31 const structure = new StructureModel(); 24 32 const shell = createShell(plugin); 25 33 const strategy = resolveStrategy(plugin);
+2 -2
packages/openapi-python/src/py-dsl/decl/func.ts
··· 19 19 override readonly nameSanitizer = safeRuntimeName; 20 20 21 21 protected _parameters: Array<py.FunctionParameter> = []; 22 - protected _returnType?: py.Expression; 22 + protected _returnType?: NodeName | py.Expression; 23 23 24 24 constructor(name: NodeName, fn?: (f: FuncPyDsl) => void) { 25 25 super(); ··· 56 56 return this; 57 57 } 58 58 59 - returns(returnType: string | py.Expression): this { 59 + returns(returnType: NodeName | py.Expression): this { 60 60 this._returnType = 61 61 typeof returnType === 'string' ? py.factory.createIdentifier(returnType) : returnType; 62 62 return this;
+19 -27
packages/openapi-python/src/py-dsl/mixins/decorator.ts
··· 4 4 import type { MaybePyDsl } from '../base'; 5 5 import type { BaseCtor, MixinCtor } from './types'; 6 6 7 + type DecoratorInput = { 8 + args: ReadonlyArray<MaybePyDsl<py.Expression>>; 9 + name: NodeName | MaybePyDsl<py.Expression>; 10 + }; 11 + 7 12 export interface DecoratorMethods extends Node { 8 13 $decorators(): ReadonlyArray<py.Expression>; 9 - decorator( 10 - name: NodeName | MaybePyDsl<py.Expression>, 11 - ...args: ReadonlyArray<MaybePyDsl<py.Expression>> 12 - ): this; 14 + decorator(name: DecoratorInput['name'], ...args: DecoratorInput['args']): this; 13 15 } 14 16 15 17 export function DecoratorMixin<T extends py.Node, TBase extends BaseCtor<T>>(Base: TBase) { 16 18 abstract class Decorator extends Base { 17 - protected decorators: Array<py.Expression> = []; 19 + protected _decorators: Array<DecoratorInput> = []; 18 20 19 21 override analyze(ctx: AnalysisContext): void { 20 22 super.analyze(ctx); 21 - for (const decorator of this.decorators) { 22 - ctx.analyze(decorator); 23 + for (const decorator of this._decorators) { 24 + ctx.analyze(decorator.name); 25 + for (const arg of decorator.args) { 26 + ctx.analyze(arg); 27 + } 23 28 } 24 29 } 25 30 26 - protected decorator( 27 - name: NodeName | MaybePyDsl<py.Expression>, 28 - ...args: ReadonlyArray<MaybePyDsl<py.Expression>> 29 - ): this { 30 - const nameNode = 31 - typeof name === 'string' || isPyNode(name) 32 - ? name 33 - : py.factory.createIdentifier(String(name)); 34 - const decoratorExpr = args.length 35 - ? py.factory.createCallExpression( 36 - nameNode as py.Expression, 37 - args.map((a) => this.$node(a)), 38 - ) 39 - : (nameNode as py.Expression); 40 - this.decorators.push(decoratorExpr); 31 + protected decorator(name: DecoratorInput['name'], ...args: DecoratorInput['args']): this { 32 + this._decorators.push({ args, name }); 41 33 return this; 42 34 } 43 35 44 36 protected $decorators(): ReadonlyArray<py.Expression> { 45 - return this.decorators; 37 + return this._decorators.map((decorator) => 38 + decorator.args.length > 0 39 + ? py.factory.createCallExpression(this.$node(decorator.name), this.$node(decorator.args)) 40 + : this.$node(decorator.name), 41 + ); 46 42 } 47 43 } 48 44 49 45 return Decorator as unknown as MixinCtor<TBase, DecoratorMethods>; 50 46 } 51 - 52 - function isPyNode(value: unknown): value is { toAst(): unknown } { 53 - return typeof value === 'object' && value !== null && 'toAst' in value; 54 - }