• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 'internal-calls.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
35type MemoType = @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void);
36class Test {
37    public void_method(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void {
38        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0);
39        if (__memo_scope.unchanged) {
40            __memo_scope.cached;
41            return;
42        }
43        {
44            __memo_scope.recache();
45            return;
46        }
47    }
48    public internal_call(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void {
49        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0);
50        if (__memo_scope.unchanged) {
51            __memo_scope.cached;
52            return;
53        }
54        this.void_method(__memo_context, ((__memo_id) + (<some_random_number>)));
55        {
56            __memo_scope.recache();
57            return;
58        }
59    }
60    public method_with_internals(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void {
61        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0);
62        if (__memo_scope.unchanged) {
63            __memo_scope.cached;
64            return;
65        }
66        __context();
67        __id();
68        {
69            __memo_scope.recache();
70            return;
71        }
72    }
73    public memo_lambda() {
74        @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): void => {
75            const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0);
76            if (__memo_scope.unchanged) {
77                __memo_scope.cached;
78                return;
79            }
80            {
81                __memo_scope.recache();
82                return;
83            }
84        });
85    }
86    public memo_variables(__memo_context: __memo_context_type, __memo_id: __memo_id_type): void {
87        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 0);
88        if (__memo_scope.unchanged) {
89            __memo_scope.cached;
90            return;
91        }
92        @memo() const f = ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): number => {
93            const __memo_scope = __memo_context.scope<number>(((__memo_id) + (<some_random_number>)), 0);
94            if (__memo_scope.unchanged) {
95                return __memo_scope.cached;
96            }
97            return __memo_scope.recache(123);
98        }), g = ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, x: number): number => {
99            const __memo_scope = __memo_context.scope<number>(((__memo_id) + (<some_random_number>)), 1);
100            const __memo_parameter_x = __memo_scope.param(0, x);
101            if (__memo_scope.unchanged) {
102                return __memo_scope.cached;
103            }
104            return __memo_scope.recache(((123) + (__memo_parameter_x.value)));
105        });
106        const h = @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type): number => {
107            const __memo_scope = __memo_context.scope<number>(((__memo_id) + (<some_random_number>)), 0);
108            if (__memo_scope.unchanged) {
109                return __memo_scope.cached;
110            }
111            return __memo_scope.recache(1);
112        });
113        f(__memo_context, ((__memo_id) + (<some_random_number>)));
114        g(__memo_context, ((__memo_id) + (<some_random_number>)), 1);
115        h(__memo_context, ((__memo_id) + (<some_random_number>)));
116        {
117            __memo_scope.recache();
118            return;
119        }
120    }
121    @functions.OptionalParametersAnnotation({minArgCount:0}) public args_with_default_values(__memo_context: __memo_context_type, __memo_id: __memo_id_type, gensym%%_1?: int, gensym%%_2?: (()=> int), gensym%%_3?: int, arg4?: int): void {
122        let arg1: int = (((gensym%%_1) !== (undefined)) ? gensym%%_1 : (10 as int));
123        let arg2: (()=> int) = (((gensym%%_2) !== (undefined)) ? gensym%%_2 : ((() => {
124            return 20;
125        }) as (()=> int)));
126        let arg3: int = (((gensym%%_3) !== (undefined)) ? gensym%%_3 : (arg1 as int));
127        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 4);
128        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);
129        if (__memo_scope.unchanged) {
130            __memo_scope.cached;
131            return;
132        }
133        console.log(__memo_parameter_arg1.value, __memo_parameter_arg2.value, __memo_parameter_arg3.value, __memo_parameter_arg4.value);
134        console.log(__memo_parameter_arg2.value());
135        {
136            __memo_scope.recache();
137            return;
138        }
139    }
140    @functions.OptionalParametersAnnotation({minArgCount:0}) public optional_args(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg1?: int, arg2?: (()=> int)): void {
141        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 2);
142        const __memo_parameter_arg1 = __memo_scope.param(0, arg1), __memo_parameter_arg2 = __memo_scope.param(1, arg2);
143        if (__memo_scope.unchanged) {
144            __memo_scope.cached;
145            return;
146        }
147        console.log(__memo_parameter_arg1.value);
148        console.log(__memo_parameter_arg2.value);
149        console.log(({let gensym%%_166 = __memo_parameter_arg2.value;
150        (((gensym%%_166) == (null)) ? undefined : gensym%%_166())}));
151        {
152            __memo_scope.recache();
153            return;
154        }
155    }
156    public type_alias(__memo_context: __memo_context_type, __memo_id: __memo_id_type, arg: MemoType): void {
157        const __memo_scope = __memo_context.scope<void>(((__memo_id) + (<some_random_number>)), 1);
158        const __memo_parameter_arg = __memo_scope.param(0, arg);
159        if (__memo_scope.unchanged) {
160            __memo_scope.cached;
161            return;
162        }
163        __memo_parameter_arg.value(__memo_context, ((__memo_id) + (<some_random_number>)));
164        {
165            __memo_scope.recache();
166            return;
167        }
168    }
169    public constructor() {}
170}
171`;
172
173function testMemoTransformer(this: PluginTestContext): void {
174    expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript));
175}
176
177pluginTester.run(
178    'transform inner calls in methods',
179    [memoNoRecheck],
180    {
181        'checked:memo-no-recheck': [testMemoTransformer],
182    },
183    {
184        stopAfter: 'checked',
185    }
186);
187