diff --git a/arkui-plugins/collectors/memo-collectors/function-collector.ts b/arkui-plugins/collectors/memo-collectors/function-collector.ts index df1f8fd4f4d04189f8054df12a56270567f775d2..a2751741f69e1484bdebada2f62f07056ec40d31 100644 --- a/arkui-plugins/collectors/memo-collectors/function-collector.ts +++ b/arkui-plugins/collectors/memo-collectors/function-collector.ts @@ -47,6 +47,13 @@ export class MemoFunctionCollector extends AbstractVisitor { this._shouldCollectReturn = newValue; } + private disableCollectReturnBeforeCallback(callbackFn: () => void): void { + const tempValue = this.shouldCollectReturn; + this.shouldCollectReturn = false; + callbackFn(); + this.shouldCollectReturn = tempValue; + } + private collectMemoAstNode(node: arkts.AstNode, info: MemoableInfo): void { if (checkIsMemoFromMemoableInfo(info, false)) { arkts.NodeCache.getInstance().collect(node); @@ -115,17 +122,17 @@ export class MemoFunctionCollector extends AbstractVisitor { private visitCallExpression(node: arkts.CallExpression): arkts.AstNode { if (arkts.NodeCache.getInstance().has(node)) { - this.shouldCollectReturn = false; - this.visitEachChild(node); - this.shouldCollectReturn = true; + this.disableCollectReturnBeforeCallback(() => { + this.visitEachChild(node); + }); return node; } const expr = findIdentifierFromCallee(node.expression); const decl = (expr && getDeclResolveAlias(expr)) ?? node.expression; if (!decl) { - this.shouldCollectReturn = false; - this.visitEachChild(node); - this.shouldCollectReturn = true; + this.disableCollectReturnBeforeCallback(() => { + this.visitEachChild(node); + }); return node; } if (arkts.NodeCache.getInstance().has(decl)) { @@ -138,9 +145,9 @@ export class MemoFunctionCollector extends AbstractVisitor { } else if (arkts.isIdentifier(decl) && !!decl.parent && arkts.isVariableDeclarator(decl.parent)) { this.collectCallWithDeclaredIdInVariableDeclarator(node, decl.parent); } - this.shouldCollectReturn = false; - this.visitEachChild(node); - this.shouldCollectReturn = true; + this.disableCollectReturnBeforeCallback(() => { + this.visitEachChild(node); + }); return node; } diff --git a/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets b/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets index a665975076ca05f9e8111b218136fdbff21f123c..76b8150735a73f4c837ce9da39f669ca01e07c3e 100755 --- a/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets +++ b/arkui-plugins/test/demo/localtest/entry/src/main/ets/pages/new.ets @@ -42,7 +42,7 @@ struct MyStateSample { @Component struct Child { - @Link linkVar: string = ""; // TODO: remove this + @Link linkVar: string; @Prop propVar: string = "Prop"; changeValue1() { diff --git a/arkui-plugins/test/demo/mock/memo/functions/declare-and-call.ets b/arkui-plugins/test/demo/mock/memo/functions/declare-and-call.ets index 6ab9e8d74e1833a28762e1a5bd35227a30d1170c..9b54856e512b5a835d63ed2a53d91ea11d4db03a 100644 --- a/arkui-plugins/test/demo/mock/memo/functions/declare-and-call.ets +++ b/arkui-plugins/test/demo/mock/memo/functions/declare-and-call.ets @@ -29,7 +29,26 @@ function funcB(): void { funcA(); } +interface MemoBuilder { + @memo builder: () => void +} + +@memo +function funcWithMemoBuilder(@memo memo_arg: MemoBuilder): void {} + +function funcWithArg(arg: () => void): void {} + +function func(): void {} + @memo () => { funcA(); + funcWithMemoBuilder({ + builder: () => { + funcWithArg(() => { + func(); + return; + }); + } + }); } \ No newline at end of file diff --git a/arkui-plugins/test/ut/memo-plugins/function-declarations/declare-and-call.test.ts b/arkui-plugins/test/ut/memo-plugins/function-declarations/declare-and-call.test.ts index a1eb3091e9ac4484ce1fe57536a6af26b0c1602f..b4d2d21c4e4376797b78044103e26192daa60794 100644 --- a/arkui-plugins/test/ut/memo-plugins/function-declarations/declare-and-call.test.ts +++ b/arkui-plugins/test/ut/memo-plugins/function-declarations/declare-and-call.test.ts @@ -41,6 +41,23 @@ function main() {} return; } funcA(__memo_context, ((__memo_id) + ())); + funcWithMemoBuilder(__memo_context, ((__memo_id) + ()), { + builder: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + funcWithArg((() => { + func(); + return; + })); + { + __memo_scope.recache(); + return; + } + }), + }); { __memo_scope.recache(); return; @@ -59,6 +76,20 @@ function main() {} return; } } +@memo() function funcWithMemoBuilder(__memo_context: __memo_context_type, __memo_id: __memo_id_type, @memo() memo_arg: MemoBuilder): void { + const __memo_scope = __memo_context.scope(((__memo_id) + ()), 1); + const __memo_parameter_memo_arg = __memo_scope.param(0, memo_arg); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + __memo_scope.recache(); + return; + } +} +function funcWithArg(arg: (()=> void)): void {} +function func(): void {} class A { @memo() public foo(__memo_context: __memo_context_type, __memo_id: __memo_id_type) { const __memo_scope = __memo_context.scope(((__memo_id) + ()), 0); @@ -74,6 +105,10 @@ class A { } public constructor() {} } +interface MemoBuilder { + @memo() set builder(builder: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)) + @memo() get builder(): ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void) +} `; function testMemoTransformer(this: PluginTestContext): void {