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 METHOD_DIR_PATH: string = 'memo/methods'; 24 25const buildConfig: BuildConfig = mockBuildConfig(); 26buildConfig.compileFiles = [path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, METHOD_DIR_PATH, 'non-void-method.ets')]; 27 28const pluginTester = new PluginTester('test memo method', 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() {} 33function __context(): __memo_context_type 34function __id(): __memo_id_type 35@Retention({policy:"SOURCE"}) @interface memo_intrinsic {} 36@Retention({policy:"SOURCE"}) @interface memo_entry {} 37class Test { 38 public void_method(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void { 39 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 40 if (__memo_scope.unchanged) { 41 __memo_scope.cached; 42 return; 43 } 44 { 45 __memo_scope.recache(); 46 return; 47 } 48 } 49 public string_method_with_return(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg: string): string { 50 const __memo_scope = __memo_context.scope<string>(((__memo_id) + (<some_random_number>)), 1); 51 const __memo_parameter_arg = __memo_scope.param(0, arg); 52 if (__memo_scope.unchanged) { 53 return __memo_scope.cached; 54 } 55 return __memo_scope.recache(__memo_parameter_arg.value); 56 } 57 public method_with_type_parameter<T>(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg: T): T { 58 const __memo_scope = __memo_context.scope<T>(((__memo_id) + (<some_random_number>)), 1); 59 const __memo_parameter_arg = __memo_scope.param(0, arg); 60 if (__memo_scope.unchanged) { 61 return __memo_scope.cached; 62 } 63 return __memo_scope.recache(__memo_parameter_arg.value); 64 } 65 public intrinsic_method(): int { 66 return 0; 67 } 68 public intrinsic_method_with_this(): int { 69 this.void_method(__memo_context, ((__memo_id) + (<some_random_number>))); 70 return 0; 71 } 72 public memoEntry<R>(__memo_context: __memo_context_type, __memo_id: __memo_id_type, @memo() entry: ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> R)): R { 73 const getContext = (() => { 74 return __context(); 75 }); 76 const getId = (() => { 77 return __id(); 78 }); 79 { 80 const __memo_context = getContext(); 81 const __memo_id = getId(); 82 return entry(__memo_context, ((__memo_id) + (<some_random_number>))); 83 } 84 } 85 public constructor() {} 86} 87class Use { 88 public test(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void { 89 const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0); 90 if (__memo_scope.unchanged) { 91 __memo_scope.cached; 92 return; 93 } 94 const test = new Test(); 95 test.string_method_with_return(__memo_context, ((__memo_id) + (<some_random_number>)), "a string"); 96 test.method_with_type_parameter(__memo_context, ((__memo_id) + (<some_random_number>)), "I'm string"); 97 { 98 __memo_scope.recache(); 99 return; 100 } 101 } 102 public constructor() {} 103} 104`; 105 106function testMemoTransformer(this: PluginTestContext): void { 107 expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); 108} 109 110pluginTester.run( 111 'transform methods with non-void return type', 112 [memoNoRecheck], 113 { 114 'checked:memo-no-recheck': [testMemoTransformer], 115 }, 116 { 117 stopAfter: 'checked', 118 } 119); 120