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 = [path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, LAMBDA_DIR_PATH, 'argument-call.ets')]; 27 28const pluginTester = new PluginTester('test memo lambda', 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((arg: (()=> void)) => {})((() => {})); 34 35((arg: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)) => {})(@memo() (() => {})); 36 37((gensym%%_1?: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)) => { 38 let arg: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void) = (((gensym%%_1) !== (undefined)) ? gensym%%_1 : (((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 39 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (201676739)), 0); 40 if (__memo_scope.unchanged) { 41 __memo_scope.cached; 42 return; 43 } 44 { 45 __memo_scope.recache(); 46 return; 47 } 48 }) as @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void))); 49})(@memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 50 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (209782503)), 0); 51 if (__memo_scope.unchanged) { 52 __memo_scope.cached; 53 return; 54 } 55 { 56 __memo_scope.recache(); 57 return; 58 } 59})); 60 61@memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 62 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 63 if (__memo_scope.unchanged) { 64 __memo_scope.cached; 65 return; 66 } 67 @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, gensym%%_<some_random_number>?: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)): void => { 68 let arg: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void) = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 69 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 70 if (__memo_scope.unchanged) { 71 __memo_scope.cached; 72 return; 73 } 74 { 75 __memo_scope.recache(); 76 return; 77 } 78 }) as @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void))); 79 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 1); 80 const __memo_parameter_arg = __memo_scope.param(0, arg); 81 if (__memo_scope.unchanged) { 82 __memo_scope.cached; 83 return; 84 } 85 { 86 __memo_scope.recache(); 87 return; 88 } 89 })(__memo_context, ((__memo_id) + (<some_random_number>)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 90 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 91 if (__memo_scope.unchanged) { 92 __memo_scope.cached; 93 return; 94 } 95 { 96 __memo_scope.recache(); 97 return; 98 } 99 })); 100 { 101 __memo_scope.recache(); 102 return; 103 } 104}); 105 106@memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 107 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 108 if (__memo_scope.unchanged) { 109 __memo_scope.cached; 110 return; 111 } 112 let goo = @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, gensym%%_<some_random_number>?: string): void => { 113 let name: string = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (\"old\" as string)); 114 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 1); 115 const __memo_parameter_name = __memo_scope.param(0, name); 116 if (__memo_scope.unchanged) { 117 __memo_scope.cached; 118 return; 119 } 120 { 121 __memo_scope.recache(); 122 return; 123 } 124 }); 125 goo(__memo_context, ((__memo_id) + (<some_random_number>))); 126 { 127 __memo_scope.recache(); 128 return; 129 } 130}); 131 132(() => { 133 let foo = ((gensym%%_<some_random_number>?: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void)) => { 134 let arg: @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void) = (((gensym%%_<some_random_number>) !== (undefined)) ? gensym%%_<some_random_number> : (((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 135 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 136 if (__memo_scope.unchanged) { 137 __memo_scope.cached; 138 return; 139 } 140 { 141 __memo_scope.recache(); 142 return; 143 } 144 }) as @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void))); 145 }); 146 foo(@memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => { 147 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 148 if (__memo_scope.unchanged) { 149 __memo_scope.cached; 150 return; 151 } 152 { 153 __memo_scope.recache(); 154 return; 155 } 156 })); 157}); 158`; 159 160function testMemoTransformer(this: PluginTestContext): void { 161 expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); 162} 163 164pluginTester.run( 165 'transform argument calls in lambdas', 166 [memoNoRecheck], 167 { 168 'checked:memo-no-recheck': [testMemoTransformer], 169 }, 170 { 171 stopAfter: 'checked', 172 } 173); 174