diff --git a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts index 6f8a2488be9e28f327d3ff984dad58a3c9e45218..031657700bcbd7da10ffc99c01ed161d0df546bc 100644 --- a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts +++ b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts @@ -21,6 +21,7 @@ import { hasMemoAnnotation, hasMemoIntrinsicAnnotation, hasMemoStableAnnotation, + isVoidType } from "./utils" import { ParameterTransformer } from "./ParameterTransformer" import { ReturnTransformer } from "./ReturnTranformer" @@ -42,8 +43,11 @@ function updateFunctionBody( arkts.VariableDeclaration | undefined, arkts.ReturnStatement | arkts.BlockStatement | undefined, ] { + let returnTypeAnno = stableThis + ? arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID) + : returnTypeAnnotation; const scopeDeclaration = factory.createScopeDeclaration( - stableThis ? arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID) : returnTypeAnnotation, + returnTypeAnno, hash, parameters.length ) const memoParameters = parameters.map((name, id) => { return factory.createMemoParameterDeclarator(id, name.identifier.name) }) @@ -57,7 +61,8 @@ function updateFunctionBody( ] : [] const syntheticReturnStatement = factory.createSyntheticReturnStatement(stableThis) - const unchangedCheck = factory.createIfStatementWithSyntheticReturnStatement(syntheticReturnStatement) + const isVoidValue = isVoidType(returnTypeAnno) + const unchangedCheck = factory.createIfStatementWithSyntheticReturnStatement(syntheticReturnStatement, isVoidValue) return [ arkts.factory.updateBlockStatement( node, @@ -198,7 +203,10 @@ export class FunctionTransformer extends AbstractVisitor { scriptFunction.modifiers, false, scriptFunction.ident, - [...factory.createHiddenParameters(), ...updatedParameters], + [ + ...factory.createHiddenParameters(), + ...updatedParameters + ], scriptFunction.typeParamsDecl, scriptFunction.returnTypeAnnotation ) @@ -237,7 +245,7 @@ export class FunctionTransformer extends AbstractVisitor { this.enterAnonymousScope(it.scriptFunction) const res = this.updateScriptFunction(it.scriptFunction) this.exitAnonymousScope() - return res + return arkts.factory.updateArrowFunction(it, res) } } return it @@ -252,4 +260,4 @@ export class FunctionTransformer extends AbstractVisitor { } return node } -} +} \ No newline at end of file diff --git a/arkoala-arkts/memo-plugin/src/MemoFactory.ts b/arkoala-arkts/memo-plugin/src/MemoFactory.ts index d26fbb67dad036991940fabc350d7feab3f8d57f..bece82ce20b8c1ab543e02fc98c5978f70dcf653 100644 --- a/arkoala-arkts/memo-plugin/src/MemoFactory.ts +++ b/arkoala-arkts/memo-plugin/src/MemoFactory.ts @@ -208,7 +208,9 @@ export class factory { } static createReturnThis(): arkts.BlockStatement { return arkts.factory.createBlockStatement([ - factory.createRecacheCall(), + arkts.factory.createExpressionStatement( + factory.createRecacheCall() + ), arkts.factory.createReturnStatement( arkts.factory.createThisExpression() ) @@ -239,7 +241,19 @@ export class factory { ) ]) } - static createIfStatementWithSyntheticReturnStatement(syntheticReturnStatement: arkts.ReturnStatement | arkts.BlockStatement): arkts.IfStatement { + static createIfStatementWithSyntheticReturnStatement( + syntheticReturnStatement: arkts.ReturnStatement | arkts.BlockStatement, + isVoidValue: boolean + ): arkts.IfStatement { + let returnStatement = syntheticReturnStatement; + if (isVoidValue && arkts.isReturnStatement(syntheticReturnStatement)) { + returnStatement = arkts.factory.createBlockStatement([ + arkts.factory.createExpressionStatement( + syntheticReturnStatement.argument! + ), + arkts.factory.createReturnStatement() + ]) + } return arkts.factory.createIfStatement( arkts.factory.createMemberExpression( arkts.factory.createIdentifier(RuntimeNames.SCOPE), @@ -248,7 +262,7 @@ export class factory { false, false, ), - syntheticReturnStatement, + returnStatement, ) } diff --git a/arkoala-arkts/memo-plugin/src/ReturnTranformer.ts b/arkoala-arkts/memo-plugin/src/ReturnTranformer.ts index d169e0a95a0201c6bd7f05da04046c06f6491501..6e5420aba16892e1557e53e430486dcfd54b4cee 100644 --- a/arkoala-arkts/memo-plugin/src/ReturnTranformer.ts +++ b/arkoala-arkts/memo-plugin/src/ReturnTranformer.ts @@ -36,7 +36,7 @@ export class ReturnTransformer extends AbstractVisitor { // TODO: temporary checking skip nodes by comparison with expected skip nodes // Should be fixed when update procedure implemented properly if (/* beforeChildren === this.skipNode */ isSyntheticReturnStatement(beforeChildren)) { - return beforeChildren + return beforeChildren; } if (arkts.isScriptFunction(beforeChildren)) { return beforeChildren @@ -46,8 +46,13 @@ export class ReturnTransformer extends AbstractVisitor { if (this.stableThis && node.argument && arkts.isThisExpression(node.argument)) { return factory.createReturnThis() } - return arkts.factory.updateReturnStatement(node, factory.createRecacheCall(node.argument)) + return arkts.factory.createBlockStatement([ + arkts.factory.createExpressionStatement( + factory.createRecacheCall(node.argument) + ), + node + ]); } return node } -} +} \ No newline at end of file diff --git a/arkoala-arkts/memo-plugin/src/utils.ts b/arkoala-arkts/memo-plugin/src/utils.ts index a43d108516095ec96e40d6d65b05d584740d9e13..00c2d4e2b35d6701c17ecc65dc6a731c9a7fd3d5 100644 --- a/arkoala-arkts/memo-plugin/src/utils.ts +++ b/arkoala-arkts/memo-plugin/src/utils.ts @@ -83,16 +83,16 @@ export class PositionalIdTracker { } } +export function isMemoAnnotation(node: arkts.AnnotationUsage, memoName: RuntimeNames) { + return node.expr !== undefined && arkts.isIdentifier(node.expr) && node.expr.name === memoName +} + export function hasMemoAnnotation(node: arkts.ScriptFunction | arkts.ETSParameterExpression) { - return node.annotations.some((it) => - it.expr !== undefined && arkts.isIdentifier(it.expr) && it.expr.name === RuntimeNames.ANNOTATION - ) + return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION)) } export function hasMemoIntrinsicAnnotation(node: arkts.ScriptFunction | arkts.ETSParameterExpression) { - return node.annotations.some((it) => - it.expr !== undefined && arkts.isIdentifier(it.expr) && it.expr.name === RuntimeNames.ANNOTATION_INTRINSIC - ) + return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION_INTRINSIC)) } export function hasMemoStableAnnotation(node: arkts.ClassDefinition) { @@ -101,6 +101,17 @@ export function hasMemoStableAnnotation(node: arkts.ClassDefinition) { ) } +export function removeMemoAnnotationInParam(param: arkts.ETSParameterExpression): arkts.ETSParameterExpression { + param.annotations = param.annotations.filter( + (it) => ( + !isMemoAnnotation(it, RuntimeNames.ANNOTATION) + && !isMemoAnnotation(it, RuntimeNames.ANNOTATION_INTRINSIC) + && !isMemoAnnotation(it, RuntimeNames.ANNOTATION_STABLE) + ) + ); + return param; +} + /** * TODO: * @deprecated @@ -124,3 +135,10 @@ export function isMemoParametersDeclaration(node: arkts.AstNode) { return arkts.isVariableDeclaration(node) && node.declarators.every((it) => it.name.name.startsWith(RuntimeNames.PARAMETER)) } + +/** + * TODO: change this to TypeNodeGetType to check void type + */ +export function isVoidType(typeNode: arkts.TypeNode | undefined) { + return typeNode?.dumpSrc() === "void" +}