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 FUNCTION_DIR_PATH: string = 'memo/functions'; 24 25const buildConfig: BuildConfig = mockBuildConfig(); 26buildConfig.compileFiles = [path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, FUNCTION_DIR_PATH, 'argument-call.ets')]; 27 28const pluginTester = new PluginTester('test memo function', buildConfig); 29 30const expectedScript: string = ` 31import { memo as memo, __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from \"@ohos.arkui.stateManagement\"; 32function main() {} 33@functions.OptionalParametersAnnotation({minArgCount:3}) function memo_arg_call(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg1: number, arg2: ((x: number)=> number), @memo() arg3: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number)=> number), arg4?: ((x: number)=> number), @memo() arg5?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number)=> number)): void { 34 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 5); 35 const __memo_parameter_arg1 = __memo_scope.param(0, arg1), __memo_parameter_arg2 = __memo_scope.param(1, arg2), __memo_parameter_arg3 = __memo_scope.param(2, arg3), __memo_parameter_arg4 = __memo_scope.param(3, arg4), __memo_parameter_arg5 = __memo_scope.param(4, arg5); 36 if (__memo_scope.unchanged) { 37 __memo_scope.cached; 38 return; 39 } 40 __memo_parameter_arg2.value(__memo_parameter_arg1.value); 41 __memo_parameter_arg3.value(__memo_context, ((__memo_id) + (<some_random_number>)), __memo_parameter_arg1.value); 42 ({let gensym%%_<some_random_number> = __memo_parameter_arg4.value; 43 (((gensym%%_<some_random_number>) == (null)) ? undefined : gensym%%_<some_random_number>(__memo_parameter_arg1.value))}); 44 ({let gensym%%_<some_random_number> = __memo_parameter_arg5.value; 45 (((gensym%%_<some_random_number>) == (null)) ? undefined : gensym%%_<some_random_number>(__memo_context, ((__memo_id) + (<some_random_number>)), __memo_parameter_arg1.value))}); 46 { 47 __memo_scope.recache(); 48 return; 49 } 50} 51@functions.OptionalParametersAnnotation({minArgCount:1}) function memo_arg_call_with_lowering(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg1: number, arg4?: ((x: number)=> number), @memo() arg5?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number)=> number)): void { 52 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 3); 53 const __memo_parameter_arg1 = __memo_scope.param(0, arg1), __memo_parameter_arg4 = __memo_scope.param(1, arg4), __memo_parameter_arg5 = __memo_scope.param(2, arg5); 54 if (__memo_scope.unchanged) { 55 __memo_scope.cached; 56 return; 57 } 58 { 59 let gensym___<some_random_number> = __memo_parameter_arg4.value; 60 (((gensym___<some_random_number>) == (null)) ? undefined : gensym___<some_random_number>(__memo_parameter_arg1.value)); 61 } 62 { 63 let gensym___<some_random_number> = __memo_parameter_arg5.value; 64 (((gensym___<some_random_number>) == (null)) ? undefined : gensym___<some_random_number>(__memo_context, ((__memo_id) + (<some_random_number>)), __memo_parameter_arg1.value)); 65 } 66 { 67 __memo_scope.recache(); 68 return; 69 } 70} 71@functions.OptionalParametersAnnotation({minArgCount:0}) function args_with_default_values(__memo_context: __memo_context_type, __memo_id: __memo_id_type, gensym%%_<some_random_number>?: int, @memo() gensym%%_<some_random_number>?: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> int), gensym%%_<some_random_number>?: int, arg4?: int): void { 72 let arg1: int = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (10 as int)); 73 let arg2: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> int) = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (((__memo_context: __memo_context_type, __memo_id: __memo_id_type): int => { 74 const __memo_scope = __memo_context.scope<int>(((__memo_id) + (<some_random_number>)), 0); 75 if (__memo_scope.unchanged) { 76 return __memo_scope.cached; 77 } 78 return __memo_scope.recache(20); 79 }) as ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> int))); 80 let arg3: int = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (arg1 as int)); 81 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 4); 82 const __memo_parameter_arg1 = __memo_scope.param(0, arg1), __memo_parameter_arg2 = __memo_scope.param(1, arg2), __memo_parameter_arg3 = __memo_scope.param(2, arg3), __memo_parameter_arg4 = __memo_scope.param(3, arg4); 83 if (__memo_scope.unchanged) { 84 __memo_scope.cached; 85 return; 86 } 87 console.log(__memo_parameter_arg1.value, __memo_parameter_arg2.value, __memo_parameter_arg3.value, __memo_parameter_arg4.value); 88 console.log(__memo_parameter_arg2.value(__memo_context, ((__memo_id) + (<some_random_number>)))); 89 { 90 __memo_scope.recache(); 91 return; 92 } 93} 94`; 95 96function testMemoTransformer(this: PluginTestContext): void { 97 expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); 98} 99 100pluginTester.run( 101 'transform argument calls in functions', 102 [memoNoRecheck], 103 { 104 'checked:memo-no-recheck': [testMemoTransformer], 105 }, 106 { 107 stopAfter: 'checked', 108 } 109); 110