diff --git a/arkoala-arkts/libarkts/generator/options.json5 b/arkoala-arkts/libarkts/generator/options.json5 index 781e953224d7238513b9ba0047a6813be84e31c1..fd29d747dda5d4b191762a4c671ca2839004a9b4 100644 --- a/arkoala-arkts/libarkts/generator/options.json5 +++ b/arkoala-arkts/libarkts/generator/options.json5 @@ -78,6 +78,25 @@ types: ["returnType"] } ] + }, + { + name: "ArrowFunctionExpression", + methods: [ + { + name: "FunctionConst", + types: ["returnType"] + } + ] + }, + { + name: "ETSParameterExpression", + methods: [ + { + name: "IdentConst", + types: ["returnType"] + } + ] } + ] -} \ No newline at end of file +} diff --git a/arkoala-arkts/libarkts/plugins/src/builder-lambda-transformer.ts b/arkoala-arkts/libarkts/plugins/src/builder-lambda-transformer.ts index cd7679c5399ed29bb95df41552df616a2b57865f..a898d56df3f4bbee4c6bcf3e8627587359cb99ef 100644 --- a/arkoala-arkts/libarkts/plugins/src/builder-lambda-transformer.ts +++ b/arkoala-arkts/libarkts/plugins/src/builder-lambda-transformer.ts @@ -27,7 +27,7 @@ function getLambdaArg(lambdaBody: arkts.Expression, typeName: string|undefined): ] ) - const param = arkts.factory.createParameterDeclaration( + const param = arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( builderLambdaInstanceName, // TODO: it should be the return type of the function annotated with the @BuilderLambda @@ -194,10 +194,11 @@ function builderLambdaReplace(leaf: arkts.CallExpression): arkts.Identifier|arkt function builderLambdaBodyRewrite(node: arkts.AstNode): arkts.AstNode { if (!arkts.isArrowFunctionExpression(node)) return node; - const scriptFunc: arkts.ScriptFunction = node.scriptFunction; - if (!scriptFunc || !scriptFunc.body) return node; + const scriptFunc = node.function; + if (!scriptFunc.body) return node; const body = scriptFunc.body; + if (!arkts.isBlockStatement(body)) return node; const statements: arkts.AstNode[] = body.statements.map((statement: arkts.AstNode) => { if ( arkts.isExpressionStatement(statement) @@ -213,7 +214,7 @@ function builderLambdaBodyRewrite(node: arkts.AstNode): arkts.AstNode { const updateFunc: arkts.ScriptFunction = arkts.factory.updateScriptFunction( scriptFunc, updateBody, - scriptFunc.scriptFunctionFlags, + scriptFunc.flags, scriptFunc.modifiers, false, undefined, diff --git a/arkoala-arkts/libarkts/plugins/src/struct-transformer.ts b/arkoala-arkts/libarkts/plugins/src/struct-transformer.ts index 9dd2ca83711401cc10baab5aa0eef1d4fdf3f830..03e554d1b8db56f6722a77c7c93c0feb6733c152 100644 --- a/arkoala-arkts/libarkts/plugins/src/struct-transformer.ts +++ b/arkoala-arkts/libarkts/plugins/src/struct-transformer.ts @@ -19,7 +19,7 @@ function isKnownMethodDefinition(method: arkts.MethodDefinition, name: string): } function createStyleArgInBuildMethod(className: string): arkts.ETSParameterExpression { - const styleLambdaParams: arkts.ETSParameterExpression = arkts.factory.createParameterDeclaration( + const styleLambdaParams: arkts.ETSParameterExpression = arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( 'instance', arkts.factory.createTypeReferencePart( @@ -51,8 +51,8 @@ function createStyleArgInBuildMethod(className: string): arkts.ETSParameterExpre optionalStyleLambda ); - const param = arkts.factory.createParameterDeclaration(styleParam, undefined); - param.annotations = [annotation("memo")]; + const param = arkts.factory.createETSParameterExpression(styleParam, undefined); + param.setAnnotations([annotation("memo")]); return param; } @@ -78,14 +78,14 @@ function createContentArgInBuildMethod(): arkts.ETSParameterExpression { optionalContentLambda ); - const param = arkts.factory.createParameterDeclaration(contentParam, undefined); - param.annotations = [annotation("memo")]; + const param = arkts.factory.createETSParameterExpression(contentParam, undefined); + param.setAnnotations([annotation("memo")]); return param; } function createInitializerArgInBuildMethod(className: string): arkts.ETSParameterExpression { - return arkts.factory.createParameterDeclaration( + return arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( 'initializers', arkts.factory.createTypeReference( @@ -120,7 +120,7 @@ function transformBuildMethod( const updateScriptFunction = arkts.factory.createScriptFunction( scriptFunction.body, - scriptFunction.scriptFunctionFlags, + scriptFunction.flags, scriptFunction.modifiers, false, undefined, @@ -129,7 +129,7 @@ function transformBuildMethod( undefined ); - updateScriptFunction.annotations = [annotation("memo")]; + updateScriptFunction.setAnnotations([annotation("memo")]); // TODO: Currently, just return method itself. Remove this once createMethodDefinition is ready. return arkts.factory.createMethodDefinition( diff --git a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts index 61615cd40087f0bafb060ee33a207872c8991969..ae8789a19544040937d2ee50c89849e1fe645871 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts @@ -15,23 +15,28 @@ import { updateNodeByNode } from "../utilities/private" import { - ArrowFunctionExpression, CallExpression, EtsImportDeclaration, - ETSParameterExpression, EtsScript, FunctionDeclaration, FunctionExpression, MethodDefinition, NumberLiteral, - ScriptFunction, StructDeclaration, VariableDeclaration, VariableDeclarator } from "../types" + +// TODO: remove +import { + createScriptFunction_TMP, + createETSParameterExpression_TMP +} from "../types" + import { AstNode } from "../peers/AstNode" import { AnnotationUsage, + ArrowFunctionExpression, BinaryExpression, BlockStatement, ClassDefinition, @@ -56,7 +61,8 @@ import { TSTypeParameter, TSTypeParameterDeclaration, TypeNode, - UndefinedLiteral + UndefinedLiteral, + ETSParameterExpression } from "../../generated" import { factory as generatedFactory } from "../../generated/factory" @@ -108,16 +114,16 @@ export const factory = { return compose(BlockStatement.createBlockStatement) }, get createArrowFunction() { - return ArrowFunctionExpression.create + return ArrowFunctionExpression.createArrowFunctionExpression }, get updateArrowFunction() { - return compose(ArrowFunctionExpression.create) + return compose(ArrowFunctionExpression.createArrowFunctionExpression) }, get createScriptFunction() { - return ScriptFunction.create + return createScriptFunction_TMP }, get updateScriptFunction() { - return compose(ScriptFunction.create) + return compose(createScriptFunction_TMP) }, get createStringLiteral() { return StringLiteral.create1StringLiteral @@ -137,11 +143,11 @@ export const factory = { get updateNumericLiteral() { return compose(NumberLiteral.create) }, - get createParameterDeclaration() { - return ETSParameterExpression.create + get createETSParameterExpression() { + return createETSParameterExpression_TMP }, - get updateParameterDeclaration() { - return compose(ETSParameterExpression.create) + get updateETSParameterExpression() { + return compose(createETSParameterExpression_TMP) }, get createTypeParameter() { return TSTypeParameter.createTSTypeParameter @@ -304,5 +310,5 @@ export const factory = { }, get updateThisExpression() { return compose(ThisExpression.createThisExpression) - } + }, } diff --git a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts index 5872d0b5d604640b013356a1ef384c99bc6fdebb..6a721ae0c33cc0203dbd6c5c71d11ac3f9c02a0c 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts @@ -1,13 +1,10 @@ import { - ArrowFunctionExpression, CallExpression, EtsImportDeclaration, - ETSParameterExpression, EtsScript, FunctionDeclaration, FunctionExpression, MethodDefinition, - ScriptFunction, StructDeclaration, VariableDeclaration, VariableDeclarator @@ -30,10 +27,6 @@ export function isEtsScript(node: AstNode): node is EtsScript { return node instanceof EtsScript } -export function isArrowFunctionExpression(node: AstNode): node is ArrowFunctionExpression { - return node instanceof ArrowFunctionExpression -} - export function isStructDeclaration(node: AstNode): node is StructDeclaration { return node instanceof StructDeclaration } @@ -42,18 +35,10 @@ export function isFunctionExpression(node: AstNode): node is FunctionExpression return node instanceof FunctionExpression } -export function isEtsParameterExpression(node: AstNode): node is ETSParameterExpression { - return node instanceof ETSParameterExpression -} - export function isVariableDeclaration(node: AstNode): node is VariableDeclaration { return node instanceof VariableDeclaration } -export function isScriptFunction(node: AstNode): node is ScriptFunction { - return node instanceof ScriptFunction -} - export function isEtsImportDeclaration(node: AstNode): node is EtsImportDeclaration { return node instanceof EtsImportDeclaration } diff --git a/arkoala-arkts/libarkts/src/arkts-api/index.ts b/arkoala-arkts/libarkts/src/arkts-api/index.ts index 31c8f73d214c948cbe92c0ed84d3ac19b95a4e86..69a9e9a360ae9ed89e805fa735bca6fcf91e411d 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/index.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/index.ts @@ -43,6 +43,9 @@ export * from "../generated/peers/TSThisType" export * from "../generated/peers/ExpressionStatement" export * from "../generated/peers/IfStatement" export * from "../generated/peers/MemberExpression" +export * from "../generated/peers/ArrowFunctionExpression" +export * from "../generated/peers/ScriptFunction" +export * from "../generated/peers/ETSParameterExpression" export * from "./types" export * from "./utilities/private" diff --git a/arkoala-arkts/libarkts/src/arkts-api/types.ts b/arkoala-arkts/libarkts/src/arkts-api/types.ts index f84a2f3f85d21c6f6cc6f2e9374e89a694da30aa..f6ec37d975b9868e46377787c7fe82d628ac83e1 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/types.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/types.ts @@ -54,7 +54,10 @@ import { StringLiteral, TSTypeParameterDeclaration, TSTypeParameterInstantiation, - TypeNode + TypeNode, + AnnotatedExpression, + ETSParameterExpression, + ScriptFunction, } from "../generated" export class EtsScript extends AstNode { @@ -181,140 +184,52 @@ export class NumberLiteral extends Literal { readonly value: number = 0.0 } -export class ScriptFunction extends AstNode { - constructor(peer: KPtr) { - assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION) - super(peer) - this.parameters = unpackNodeArray(global.generatedEs2panda._ScriptFunctionParams(global.context, this.peer)) - this.typeParamsDecl = unpackNode(global.generatedEs2panda._ScriptFunctionTypeParams(global.context, this.peer)) - this.returnTypeAnnotation = unpackNode(global.generatedEs2panda._ScriptFunctionReturnTypeAnnotation(global.context, this.peer)) - this.body = unpackNode(global.generatedEs2panda._ScriptFunctionBody(global.context, this.peer)) - // this.signature = unpackNode(global.generatedEs2panda._ScriptFunctionSignature(global.context, this.peer)) - // this.declare = global.generatedEs2panda._ScriptFunctionDeclareConst(global.context, this.peer) - this.ident = unpackNode(global.generatedEs2panda._ScriptFunctionId(global.context, this.peer)) - - this.scriptFunctionFlags = this._correctScriptFunctionFlags() - } - - static create( - body: AstNode | undefined, - functionFlags: Es2pandaScriptFunctionFlags, - modifierFlags: Es2pandaModifierFlags, - declare: boolean, - ident: Identifier | undefined, - parameters: ETSParameterExpression[]|undefined, - typeParamsDecl: TSTypeParameterDeclaration|undefined, - returnTypeAnnotation: TypeNode|undefined, - annotations?: AnnotationUsage[], - ): ScriptFunction { - const peer = global.generatedEs2panda._CreateScriptFunction( - global.context, - passNode(body), - FunctionSignature.createFunctionSignature( - typeParamsDecl, - parameters ?? [], - returnTypeAnnotation, - false - ).peer, - functionFlags, - modifierFlags - ) - if (ident !== undefined) { - global.generatedEs2panda._ScriptFunctionSetIdent(global.context, peer, ident.peer) - } - const res = new ScriptFunction(peer) - if (annotations) { - res.annotations = annotations - } - return res - } - - setIdent(id: Identifier): ScriptFunction { - assertValidPeer(id.peer, Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER); - global.generatedEs2panda._ScriptFunctionSetIdent(global.context, this.peer, id.peer); - return this; - } - - protected override dumpMessage(): string { - const scriptFunctionFlags = global.generatedEs2panda._ScriptFunctionFlagsConst(global.context, this.peer) - return ` ` - } - - private _correctScriptFunctionFlags(): KInt { - let flags: KInt = global.generatedEs2panda._ScriptFunctionFlagsConst(global.context, this.peer) - if (this._hasReturn()) { - flags |= Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_HAS_RETURN - global.generatedEs2panda._ScriptFunctionAddFlag(global.context, this.peer, Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_HAS_RETURN) - } - if (this._isAsync()) { - flags |= Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ASYNC - global.generatedEs2panda._ScriptFunctionAddFlag(global.context, this.peer, Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ASYNC) - } - return flags - } - - private _hasReturn(): boolean { - if (this.body === undefined) { - return false - } - let hasReturn: boolean = false - // TODO: goes through whole subtree, optimizable (unnecessary now) - this.body.getSubtree().forEach( - (node: AstNode) => { - hasReturn = hasReturn || nodeType(node) === Es2pandaAstNodeType.AST_NODE_TYPE_RETURN_STATEMENT - } - ) - return hasReturn - } - - private _isAsync(): boolean { - return (this.modifiers & Es2pandaModifierFlags.MODIFIER_FLAGS_ASYNC) !== 0 - } - - readonly parameters: ETSParameterExpression[] - readonly typeParamsDecl?: TSTypeParameterDeclaration - readonly returnTypeAnnotation: TypeNode | undefined - readonly body?: BlockStatement - // readonly signature: FunctionSignature - readonly scriptFunctionFlags: KInt - readonly ident?: Identifier - - get annotations(): AnnotationUsage[] { - return unpackNodeArray(global.generatedEs2panda._ScriptFunctionAnnotations( - global.context, - this.peer - )) - } - - set annotations(newAnnotations: AnnotationUsage[]) { - global.generatedEs2panda._ScriptFunctionSetAnnotations( - global.context, - this.peer, - passNodeArray(newAnnotations), - newAnnotations.length - ); - } +export function createScriptFunction_TMP( + body: AstNode | undefined, + functionFlags: Es2pandaScriptFunctionFlags, + modifierFlags: Es2pandaModifierFlags, + declare: boolean, + ident: Identifier | undefined, + parameters: readonly Expression[] | undefined, + typeParamsDecl: TSTypeParameterDeclaration | undefined, + returnTypeAnnotation: TypeNode | undefined, + annotations?: readonly AnnotationUsage[], +): ScriptFunction { + const peer = global.generatedEs2panda._CreateScriptFunction( + global.context, + passNode(body), + FunctionSignature.createFunctionSignature( + typeParamsDecl, + parameters ?? [], + returnTypeAnnotation, + false + ).peer, + functionFlags, + modifierFlags + ) + if (ident !== undefined) { + global.generatedEs2panda._ScriptFunctionSetIdent(global.context, peer, ident.peer) + } + // return new ScriptFunction(peer); + const res = new ScriptFunction(peer) + if (annotations) { + res.setAnnotations(annotations) + } + return res } -export class ArrowFunctionExpression extends AstNode { - constructor(peer: KPtr) { - assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION) - super(peer) - this.scriptFunction = unpackNonNullableNode(global.generatedEs2panda._ArrowFunctionExpressionFunction(global.context, this.peer)) - } - - static create( - func: ScriptFunction, - ): ArrowFunctionExpression { - return new ArrowFunctionExpression( - global.generatedEs2panda._CreateArrowFunctionExpression( - global.context, - passNode(func) - ) +export function createETSParameterExpression_TMP(identOrSpread?: AnnotatedExpression, initializer?: Expression): ETSParameterExpression { + const identifier = identOrSpread as AnnotatedExpression + if (initializer !== undefined) { + return ETSParameterExpression.create1ETSParameterExpression( + identifier, + initializer, ) } - - readonly scriptFunction: ScriptFunction + return ETSParameterExpression.createETSParameterExpression( + identifier, + false + ) } export class FunctionDeclaration extends AstNode { @@ -391,68 +306,6 @@ export class FunctionExpression extends AstNode { readonly scriptFunction: ScriptFunction } -export class ETSParameterExpression extends Expression { - constructor(peer: KPtr) { - assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION) - super(peer) - this.identifier = unpackNonNullableNode(global.generatedEs2panda._ETSParameterExpressionIdent(global.context, this.peer)) - } - - static create( - identifier: Identifier, - initializer: AstNode | undefined - ): ETSParameterExpression { - if (initializer !== undefined) { - return new ETSParameterExpression( - global.generatedEs2panda._CreateETSParameterExpression1( - global.context, - passNode(identifier), - passNode(initializer), - ) - ) - } - return new ETSParameterExpression( - global.generatedEs2panda._CreateETSParameterExpression( - global.context, - passNode(identifier), - false - ) - ) - } - - get annotations(): AnnotationUsage[] { - return unpackNodeArray(global.generatedEs2panda._ETSParameterExpressionAnnotations( - global.context, - this.peer - )) - } - - set annotations(newAnnotations: AnnotationUsage[]) { - global.generatedEs2panda._ETSParameterExpressionSetAnnotations( - global.context, - this.peer, - passNodeArray(newAnnotations), - newAnnotations.length - ); - } - - get type(): AstNode | undefined { - return unpackNode(global.generatedEs2panda._ETSParameterExpressionTypeAnnotation(global.context, this.peer)) - } - - set type(t: AstNode | undefined) { - if (t === undefined) - return - global.generatedEs2panda._ETSParameterExpressionSetTypeAnnotation(global.context, this.peer, t.peer) - } - - get optional(): Boolean { - return global.generatedEs2panda._ETSParameterExpressionIsOptionalConst(global.context, this.peer) - } - - identifier: Identifier -} - export class StructDeclaration extends AstNode { constructor(peer: KPtr) { assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION) @@ -670,15 +523,12 @@ export class EtsImportDeclaration extends AstNode { const pairs: [Es2pandaAstNodeType, { new(peer: KNativePointer): AstNode }][] = [ [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE, EtsScript], - [Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER, Identifier], [Es2pandaAstNodeType.AST_NODE_TYPE_NUMBER_LITERAL, NumberLiteral], [Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_DECLARATION, FunctionDeclaration], [Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION, ScriptFunction], [Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_STATEMENT, BlockStatement], - [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, ETSParameterExpression], [Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PARAMETER_DECLARATION, TSTypeParameterDeclaration], [Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, CallExpression], - [Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, ArrowFunctionExpression], [Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION, StructDeclaration], [Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, MethodDefinition], [Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATION, VariableDeclaration], diff --git a/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts b/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts index f17453519184dd8f136267fdce03485ae57f4774..4e6345e6e566793d4d1f87aeb2d71db3bf045d17 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts @@ -17,10 +17,10 @@ import { global } from "../static/global" import { isNumber, throwError } from "../../utils" import { nullptr, withStringResult } from "@koalaui/interop" import { passNode, unpackNodeArray, unpackNonNullableNode } from "./private" -import { isFunctionDeclaration, isScriptFunction } from "../factory/nodeTests" +import { isFunctionDeclaration } from "../factory/nodeTests" import { Es2pandaContextState, Es2pandaModifierFlags } from "../../generated/Es2pandaEnums" import type { AstNode } from "../peers/AstNode" -import { ClassDefinition, isClassDefinition, type AnnotationUsage, isMemberExpression } from "../../generated" +import { ClassDefinition, isClassDefinition, type AnnotationUsage, isScriptFunction, isMemberExpression } from "../../generated" export function proceedToState(state: Es2pandaContextState): void { if (state <= global.es2panda._ContextState(global.context)) { diff --git a/arkoala-arkts/libarkts/src/arkts-api/visitor.ts b/arkoala-arkts/libarkts/src/arkts-api/visitor.ts index 4ad64d4c7a91f165c625ee598e665ef70c3b01df..41a7ad540401583614953e4dbe42af3e8b3e4b1a 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/visitor.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/visitor.ts @@ -16,7 +16,8 @@ import { factory } from "./factory/nodeFactory" import { Es2pandaModifierFlags, Es2pandaVariableDeclaratorFlag } from "../generated/Es2pandaEnums" import { AstNode } from "./peers/AstNode" -import { +import { + isArrowFunctionExpression, isBlockStatement, isConditionalExpression, isClassDeclaration, @@ -27,18 +28,17 @@ import { isTSInterfaceBody, isTSInterfaceDeclaration, isMemberExpression, + isScriptFunction, } from "../generated" import { - isArrowFunctionExpression, isCallExpression, isEtsImportDeclaration, isEtsScript, isFunctionDeclaration, isMethodDefinition, - isScriptFunction, isStructDeclaration, isVariableDeclaration, - isVariableDeclarator + isVariableDeclarator, } from "./factory/nodeTests" import { classDefinitionFlags } from "./utilities/public" @@ -191,12 +191,12 @@ export function visitEachChild( return factory.updateScriptFunction( node, nodeVisitor(node.body, visitor), - node.scriptFunctionFlags, + node.flags, Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, false, - nodeVisitor(node.ident, visitor), - nodesVisitor(node.parameters, visitor), - nodeVisitor(node.typeParamsDecl, visitor), + nodeVisitor(node.id, visitor), + nodesVisitor(node.params, visitor), + nodeVisitor(node.typeParams, visitor), nodeVisitor(node.returnTypeAnnotation, visitor), node.annotations ) @@ -273,7 +273,7 @@ export function visitEachChild( if (isArrowFunctionExpression(node)) { return factory.updateArrowFunction( node, - nodeVisitor(node.scriptFunction, visitor), + nodeVisitor(node.function, visitor), ) } if (isReturnStatement(node)) { diff --git a/arkoala-arkts/libarkts/src/generated/peers/ArrowFunctionExpression.ts b/arkoala-arkts/libarkts/src/generated/peers/ArrowFunctionExpression.ts index 86bc75dadfa42ed66371a41a84caf1b682a954e0..3203edcfbef156fad4850f37ca1bd25401ddd191 100644 --- a/arkoala-arkts/libarkts/src/generated/peers/ArrowFunctionExpression.ts +++ b/arkoala-arkts/libarkts/src/generated/peers/ArrowFunctionExpression.ts @@ -50,8 +50,8 @@ export class ArrowFunctionExpression extends Expression { static update1ArrowFunctionExpression(original?: ArrowFunctionExpression, other?: ArrowFunctionExpression): ArrowFunctionExpression { return new ArrowFunctionExpression(global.generatedEs2panda._UpdateArrowFunctionExpression1(global.context, passNode(original), passNode(other))) } - get function(): ScriptFunction | undefined { - return unpackNode(global.generatedEs2panda._ArrowFunctionExpressionFunctionConst(global.context, this.peer)) + get function(): ScriptFunction { + return unpackNonNullableNode(global.generatedEs2panda._ArrowFunctionExpressionFunctionConst(global.context, this.peer)) } get createTypeAnnotation(): TypeNode | undefined { return unpackNode(global.generatedEs2panda._ArrowFunctionExpressionCreateTypeAnnotation(global.context, this.peer)) diff --git a/arkoala-arkts/libarkts/src/generated/peers/ETSParameterExpression.ts b/arkoala-arkts/libarkts/src/generated/peers/ETSParameterExpression.ts index a55e5789cba6d3ef33301690aad84428106ebf1a..5d07c68dcefefee8769e021457e10e432f5d9bc1 100644 --- a/arkoala-arkts/libarkts/src/generated/peers/ETSParameterExpression.ts +++ b/arkoala-arkts/libarkts/src/generated/peers/ETSParameterExpression.ts @@ -55,8 +55,8 @@ export class ETSParameterExpression extends Expression { get name(): string { return unpackString(global.generatedEs2panda._ETSParameterExpressionNameConst(global.context, this.peer)) } - get ident(): Identifier | undefined { - return unpackNode(global.generatedEs2panda._ETSParameterExpressionIdentConst(global.context, this.peer)) + get ident(): Identifier { + return unpackNonNullableNode(global.generatedEs2panda._ETSParameterExpressionIdentConst(global.context, this.peer)) } /** @deprecated */ setIdent(ident?: Identifier): this { diff --git a/arkoala-arkts/libarkts/src/ts-api/factory/nodeFactory.ts b/arkoala-arkts/libarkts/src/ts-api/factory/nodeFactory.ts index ac08be17ed491302e0549f76396c5d31f81bad52..74e37288aeb641b2c906868a270c0eaa5135104a 100644 --- a/arkoala-arkts/libarkts/src/ts-api/factory/nodeFactory.ts +++ b/arkoala-arkts/libarkts/src/ts-api/factory/nodeFactory.ts @@ -432,7 +432,7 @@ export function createNodeFactory() { initializer?: Expression ): ParameterDeclaration { return new ParameterDeclaration( - arkts.factory.createParameterDeclaration( + arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( (name instanceof Identifier) ? name.node.name : name, type?.node @@ -462,7 +462,7 @@ export function createNodeFactory() { initializer?: Expression ): ParameterDeclaration { return new ParameterDeclaration( - arkts.factory.updateParameterDeclaration( + arkts.factory.updateETSParameterExpression( node.node, arkts.factory.createIdentifier( (name instanceof Identifier) ? name.node.name : name, diff --git a/arkoala-arkts/libarkts/test/arkts-api/functions/create.test.ts b/arkoala-arkts/libarkts/test/arkts-api/functions/create.test.ts index eab9974423e852a8d4cdb66d5854eacbed83fa27..632722f3c1b36ea3e93d49a3a1caf70d8445ee02 100644 --- a/arkoala-arkts/libarkts/test/arkts-api/functions/create.test.ts +++ b/arkoala-arkts/libarkts/test/arkts-api/functions/create.test.ts @@ -158,7 +158,7 @@ suite(util.basename(__filename), () => { 'foo' ), [ - arkts.factory.createParameterDeclaration( + arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( 'x', arkts.factory.createPrimitiveType( @@ -167,7 +167,7 @@ suite(util.basename(__filename), () => { ), undefined ), - arkts.factory.createParameterDeclaration( + arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( 'y', arkts.factory.createTypeReference( diff --git a/arkoala-arkts/libarkts/test/arkts-api/import-export/import.test.ts b/arkoala-arkts/libarkts/test/arkts-api/import-export/import.test.ts index 5c99e1ebdb27ecc196a1faecdc294786d3b40845..45ebb2efb57006c6e6ec0f8f2558c00112a33ee8 100644 --- a/arkoala-arkts/libarkts/test/arkts-api/import-export/import.test.ts +++ b/arkoala-arkts/libarkts/test/arkts-api/import-export/import.test.ts @@ -167,10 +167,10 @@ suite(util.basename(__filename), () => { ) ] ), - scriptFunction.scriptFunctionFlags, + scriptFunction.flags, scriptFunction.modifiers, false, - scriptFunction.ident, + scriptFunction.id, [], undefined, undefined diff --git a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts index 6f8a2488be9e28f327d3ff984dad58a3c9e45218..9e7a08651c589ad940a6b318e022c7cd78db5b72 100644 --- a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts +++ b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts @@ -31,9 +31,16 @@ function mayAddLastReturn(node: arkts.BlockStatement): boolean { !arkts.isThrowStatement(node.statements[node.statements.length - 1]) } +/** + * @deprecated + */ +function expression2ETSParameterExpressionArr(expr: readonly arkts.Expression[]): readonly arkts.ETSParameterExpression[] { + return expr as arkts.ETSParameterExpression[] +} + function updateFunctionBody( node: arkts.BlockStatement, - parameters: arkts.ETSParameterExpression[], + parameters: readonly arkts.ETSParameterExpression[], returnTypeAnnotation: arkts.TypeNode | undefined, stableThis: boolean, hash: arkts.NumberLiteral | arkts.StringLiteral @@ -46,7 +53,7 @@ function updateFunctionBody( stableThis ? arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID) : returnTypeAnnotation, hash, parameters.length ) - const memoParameters = parameters.map((name, id) => { return factory.createMemoParameterDeclarator(id, name.identifier.name) }) + const memoParameters = parameters.map((name, id) => { return factory.createMemoParameterDeclarator(id, name.ident.name) }) const memoParametersDeclaration = memoParameters.length ? [ arkts.factory.createVariableDeclaration( @@ -146,45 +153,47 @@ export class FunctionTransformer extends AbstractVisitor { scriptFunction: arkts.ScriptFunction, name: string = "", ): arkts.ScriptFunction { - if (!scriptFunction.body) { + if (!scriptFunction.body || !arkts.isBlockStatement(scriptFunction.body)) { return scriptFunction } const isStableThis = this.stable > 0 && scriptFunction.returnTypeAnnotation !== undefined && arkts.isTSThisType(scriptFunction.returnTypeAnnotation) const [body, memoParametersDeclaration, syntheticReturnStatement] = updateFunctionBody( scriptFunction.body, - scriptFunction.parameters, + expression2ETSParameterExpressionArr(scriptFunction.params), scriptFunction.returnTypeAnnotation, isStableThis, this.positionalIdTracker.id(name), ) const afterParameterTransformer = this.parameterTransformer - .withParameters(scriptFunction.parameters) + .withParameters(expression2ETSParameterExpressionArr(scriptFunction.params)) .skip(memoParametersDeclaration) .visitor(body) const afterReturnTransformer = this.returnTransformer .skip(syntheticReturnStatement) .rewriteThis(this.stable > 0) .visitor(afterParameterTransformer) - const updatedParameters = scriptFunction.parameters.map((param) => { + const updatedParameters = expression2ETSParameterExpressionArr(scriptFunction.params).map((param) => { if (hasMemoAnnotation(param)) { - if (param.type && arkts.isETSFunctionType(param.type)) { - param.type = factory.updateFunctionTypeWithMemoParameters(param.type) - } else if (param.type && arkts.isETSUnionType(param.type)) { - param.type = arkts.factory.updateUnionType( - param.type, - param.type.types.map((it) => { - if (arkts.isETSFunctionType(it)) { - return factory.updateFunctionTypeWithMemoParameters(it) - } - return it - }) + if (param.typeAnnotation && arkts.isETSFunctionType(param.typeAnnotation)) { + param.setTypeAnnotation(factory.updateFunctionTypeWithMemoParameters(param.typeAnnotation)) + } else if (param.typeAnnotation && arkts.isETSUnionType(param.typeAnnotation)) { + param.setTypeAnnotation( + arkts.factory.updateUnionType( + param.typeAnnotation, + param.typeAnnotation.types.map((it) => { + if (arkts.isETSFunctionType(it)) { + return factory.updateFunctionTypeWithMemoParameters(it) + } + return it + }) + ) ) } else { if (name) { - console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.identifier.name} of @memo-method ${name}`) + console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.ident.name} of @memo-method ${name}`) throw "Invalid @memo usage" } else { - console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.identifier.name} of anonymous @memo-method`) + console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.ident.name} of anonymous @memo-method`) throw "Invalid @memo usage" } } @@ -194,12 +203,12 @@ export class FunctionTransformer extends AbstractVisitor { return arkts.factory.updateScriptFunction( scriptFunction, afterReturnTransformer, - scriptFunction.scriptFunctionFlags, + scriptFunction.flags, scriptFunction.modifiers, false, - scriptFunction.ident, + scriptFunction.id, [...factory.createHiddenParameters(), ...updatedParameters], - scriptFunction.typeParamsDecl, + scriptFunction.typeParams, scriptFunction.returnTypeAnnotation ) } @@ -226,16 +235,17 @@ export class FunctionTransformer extends AbstractVisitor { const expr = node.expression const decl = arkts.getDecl(expr) if (decl && arkts.isMethodDefinition(decl) && (hasMemoAnnotation(decl.scriptFunction) || hasMemoIntrinsicAnnotation(decl.scriptFunction))) { + const params = expression2ETSParameterExpressionArr(decl.scriptFunction.params) this.checkMemoCall(decl) const updatedArguments = node.arguments.map((it, index) => { - const type = decl.scriptFunction.parameters[index].type + const type = params[index].typeAnnotation if (type && arkts.isETSFunctionType(type)) { - if (!hasMemoAnnotation(decl.scriptFunction.parameters[index]) && !hasMemoIntrinsicAnnotation(decl.scriptFunction.parameters[index])) { + if (!hasMemoAnnotation(params[index]) && !hasMemoIntrinsicAnnotation(params[index])) { return factory.createComputeExpression(this.positionalIdTracker.id(decl.name.name), it) } - if (arkts.isArrowFunctionExpression(it)) { - this.enterAnonymousScope(it.scriptFunction) - const res = this.updateScriptFunction(it.scriptFunction) + if (arkts.isArrowFunctionExpression(it) && it.function) { + this.enterAnonymousScope(it.function) + const res = this.updateScriptFunction(it.function) this.exitAnonymousScope() return res } diff --git a/arkoala-arkts/memo-plugin/src/MemoFactory.ts b/arkoala-arkts/memo-plugin/src/MemoFactory.ts index d26fbb67dad036991940fabc350d7feab3f8d57f..dbd3c23161063884a77de963e5663d7b733b7ca5 100644 --- a/arkoala-arkts/memo-plugin/src/MemoFactory.ts +++ b/arkoala-arkts/memo-plugin/src/MemoFactory.ts @@ -41,7 +41,7 @@ export class factory { // Parameters static createContextParameter(): arkts.ETSParameterExpression { - return arkts.factory.createParameterDeclaration( + return arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier( RuntimeNames.CONTEXT, arkts.factory.createTypeReference( @@ -54,7 +54,7 @@ export class factory { ) } static createIdParameter(): arkts.ETSParameterExpression { - return arkts.factory.createParameterDeclaration( + return arkts.factory.createETSParameterExpression( arkts.factory.createIdentifier(RuntimeNames.ID, arkts.factory.createTypeReference( arkts.factory.createTypeReferencePart( diff --git a/arkoala-arkts/memo-plugin/src/ParameterTransformer.ts b/arkoala-arkts/memo-plugin/src/ParameterTransformer.ts index 2715c6e4fa72c064e5ce7d35b6ffc8aeb260bac4..ae7a57df7464272b6b01ff7fe3c0fa1b1f080831 100644 --- a/arkoala-arkts/memo-plugin/src/ParameterTransformer.ts +++ b/arkoala-arkts/memo-plugin/src/ParameterTransformer.ts @@ -28,25 +28,25 @@ export class ParameterTransformer extends AbstractVisitor { super() } - withParameters(parameters: arkts.ETSParameterExpression[]): ParameterTransformer { - this.rewriteCalls = new Map(parameters.filter(it => it.type && (arkts.isETSFunctionType(it.type) || arkts.isETSUnionType(it.type))).map((it) => { + withParameters(parameters: readonly arkts.ETSParameterExpression[]): ParameterTransformer { + this.rewriteCalls = new Map(parameters.filter(it => it.typeAnnotation && (arkts.isETSFunctionType(it.typeAnnotation) || arkts.isETSUnionType(it.typeAnnotation))).map((it) => { return [it.peer, (passArgs: arkts.AstNode[]) => { if (hasMemoAnnotation(it) || hasMemoIntrinsicAnnotation(it)) { - if (it.type && arkts.isETSFunctionType(it.type) && !it.optional) { - return factory.createMemoParameterAccessMemoWithScope(it.identifier.name, this.positionalIdTracker?.id(), passArgs) + if (it.typeAnnotation && arkts.isETSFunctionType(it.typeAnnotation) && !it.isOptional) { + return factory.createMemoParameterAccessMemoWithScope(it.ident.name, this.positionalIdTracker?.id(), passArgs) } else { - return factory.createMemoParameterAccessMemoWithoutScope(it.identifier.name, this.positionalIdTracker?.id(), passArgs) + return factory.createMemoParameterAccessMemoWithoutScope(it.ident.name, this.positionalIdTracker?.id(), passArgs) } } - return factory.createMemoParameterAccessCall(it.identifier.name, this.positionalIdTracker?.id(), passArgs) + return factory.createMemoParameterAccessCall(it.ident.name, this.positionalIdTracker?.id(), passArgs) }] })) this.rewriteIdentifiers = new Map(parameters.map((it) => { return [it.peer, () => { - if ((it.type && arkts.isETSFunctionType(it.type)) || it.optional) { - return arkts.factory.createIdentifier(it.identifier.name) + if ((it.typeAnnotation && arkts.isETSFunctionType(it.typeAnnotation)) || it.isOptional) { + return arkts.factory.createIdentifier(it.ident.name) } - return factory.createMemoParameterAccess(it.identifier.name) + return factory.createMemoParameterAccess(it.ident.name) }] })) return this @@ -66,7 +66,7 @@ export class ParameterTransformer extends AbstractVisitor { if (arkts.isCallExpression(beforeChildren)) { if (arkts.isIdentifier(beforeChildren.expression)) { const decl = arkts.getDecl(beforeChildren.expression) - if (decl && arkts.isEtsParameterExpression(decl) && this.rewriteCalls?.has(decl.peer)) { + if (decl && arkts.isETSParameterExpression(decl) && this.rewriteCalls?.has(decl.peer)) { return this.rewriteCalls.get(decl.peer)!( beforeChildren.arguments.map((it) => this.visitor(it)) ) @@ -76,7 +76,7 @@ export class ParameterTransformer extends AbstractVisitor { const node = this.visitEachChild(beforeChildren) if (arkts.isIdentifier(node)) { const decl = arkts.getDecl(node) - if ((decl && arkts.isEtsParameterExpression(decl)) && this.rewriteIdentifiers?.has(decl.peer)) { + if ((decl && arkts.isETSParameterExpression(decl)) && this.rewriteIdentifiers?.has(decl.peer)) { const res = this.rewriteIdentifiers.get(decl.peer)!() if (arkts.isMemberExpression(res)) { return res