1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as path from 'path'; 17import { PluginTestContext, PluginTester } from '../../../utils/plugin-tester'; 18import { BuildConfig, mockBuildConfig } from '../../../utils/artkts-config'; 19import { getRootPath, MOCK_ENTRY_DIR_PATH } from '../../../utils/path-config'; 20import { parseDumpSrc } from '../../../utils/parse-string'; 21import { memoNoRecheck } from '../../../utils/plugins'; 22 23const LAMBDA_DIR_PATH: string = 'memo/lambdas'; 24 25const buildConfig: BuildConfig = mockBuildConfig(); 26buildConfig.compileFiles = [ 27 path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, LAMBDA_DIR_PATH, 'with-receiver.ets'), 28]; 29 30const pluginTester = new PluginTester('test memo lambda', buildConfig); 31 32const expectedScript: string = ` 33import { memo as memo, __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from \"@ohos.arkui.stateManagement\"; 34function main() {} 35@memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 36 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 37 if (__memo_scope.unchanged) { 38 __memo_scope.cached; 39 return; 40 } 41 let x = new Person(); 42 fullName(x, ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 43 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 44 if (__memo_scope.unchanged) { 45 __memo_scope.cached; 46 return; 47 } 48 { 49 __memo_scope.recache(); 50 return; 51 } 52 })); 53 let f1: F1 = foo; 54 f1 = goo; 55 let f2: F2 = goo; 56 f2 = foo; 57 f1 = f2; 58 let a = new A(); 59 f1(a, ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 60 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 61 if (__memo_scope.unchanged) { 62 __memo_scope.cached; 63 return; 64 } 65 { 66 __memo_scope.recache(); 67 return; 68 } 69 })); 70 f1(a, ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 71 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 72 if (__memo_scope.unchanged) { 73 __memo_scope.cached; 74 return; 75 } 76 { 77 __memo_scope.recache(); 78 return; 79 } 80 })); 81 f2(a, ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 82 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 83 if (__memo_scope.unchanged) { 84 __memo_scope.cached; 85 return; 86 } 87 { 88 __memo_scope.recache(); 89 return; 90 } 91 })); 92 { 93 __memo_scope.recache(); 94 return; 95 } 96}); 97@functions.OptionalParametersAnnotation({minArgCount:1}) function fullName(this: Person, @memo() arg?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)): void { 98 return; 99} 100@functions.OptionalParametersAnnotation({minArgCount:1}) function foo(this: A, @memo() arg?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)): void {} 101@functions.OptionalParametersAnnotation({minArgCount:1}) function goo(a: A, @memo() arg?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)): void {} 102class Person { 103 public constructor() {} 104} 105class A { 106 public constructor() {} 107} 108type F1 = ((this: A, @memo() arg?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void))=> void); 109type F2 = ((a: A, @memo() arg?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void))=> void); 110`; 111 112function testMemoTransformer(this: PluginTestContext): void { 113 expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); 114} 115 116pluginTester.run( 117 'transform lambdas with receiver', 118 [memoNoRecheck], 119 { 120 'checked:memo-no-recheck': [testMemoTransformer], 121 }, 122 { 123 stopAfter: 'checked', 124 } 125); 126