• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-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 arkts from '@koalaui/libarkts';
17import { Plugins, PluginContext } from '../common/plugin-context';
18import { FunctionTransformer } from './function-transformer';
19import { PositionalIdTracker } from './utils';
20import { ReturnTransformer } from './return-transformer';
21import { ParameterTransformer } from './parameter-transformer';
22import { ProgramVisitor } from '../common/program-visitor';
23import { EXTERNAL_SOURCE_PREFIX_NAMES, EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK } from '../common/predefines';
24import { debugDump, debugLog, getDumpFileName } from '../common/debug';
25import { SignatureTransformer } from './signature-transformer';
26import { InternalsTransformer } from './internal-transformer';
27
28export function unmemoizeTransform(): Plugins {
29    return {
30        name: 'memo-plugin',
31        checked: checkedTransform,
32        clean() {
33            arkts.arktsGlobal.clearContext();
34        },
35    };
36}
37
38function checkedTransform(this: PluginContext): arkts.EtsScript | undefined {
39    console.log('[MEMO PLUGIN] AFTER CHECKED ENTER');
40    const contextPtr = arkts.arktsGlobal.compilerContext?.peer ?? this.getContextPtr();
41    if (!!contextPtr) {
42        let program = arkts.getOrUpdateGlobalContext(contextPtr).program;
43        let script = program.astNode;
44        debugLog('[BEFORE MEMO SCRIPT] script: ', script.dumpSrc());
45        const cachePath: string | undefined = this.getProjectConfig()?.cachePath;
46        const isFrameworkMode = !!this.getProjectConfig()?.frameworkMode;
47        const canSkipPhases = false;
48        debugDump(
49            script.dumpSrc(),
50            getDumpFileName(0, 'SRC', 5, 'MEMO_AfterCheck_Begin'),
51            true,
52            cachePath,
53            program.programFileNameWithExtension
54        );
55        arkts.Performance.getInstance().createEvent('memo-checked');
56        program = checkedProgramVisit(program, this, canSkipPhases, isFrameworkMode);
57        script = program.astNode;
58        arkts.Performance.getInstance().stopEvent('memo-checked', true);
59        debugLog('[AFTER MEMO SCRIPT] script: ', script.dumpSrc());
60        debugDump(
61            script.dumpSrc(),
62            getDumpFileName(0, 'SRC', 6, 'MEMO_AfterCheck_End'),
63            true,
64            cachePath,
65            program.programFileNameWithExtension
66        );
67        arkts.Performance.getInstance().createEvent('memo-recheck');
68        arkts.recheckSubtree(script);
69        arkts.Performance.getInstance().stopEvent('memo-recheck', true);
70        arkts.Performance.getInstance().clearAllEvents();
71        this.setArkTSAst(script);
72        console.log('[MEMO PLUGIN] AFTER CHECKED EXIT');
73        return script;
74    }
75    console.log('[MEMO PLUGIN] AFTER CHECKED EXIT WITH NO TRANSFORM');
76    return undefined;
77}
78
79function checkedProgramVisit(
80    program: arkts.Program,
81    pluginContext: PluginContext,
82    canSkipPhases: boolean = false,
83    isFrameworkMode: boolean = false
84): arkts.Program {
85    if (canSkipPhases) {
86        debugLog('[SKIP PHASE] phase: memo-checked, moduleName: ', program?.moduleName);
87    } else {
88        debugLog('[CANT SKIP PHASE] phase: memo-checked, moduleName: ', program?.moduleName);
89        const positionalIdTracker = new PositionalIdTracker(arkts.getFileName(), false);
90        const parameterTransformer = new ParameterTransformer({
91            positionalIdTracker,
92        });
93        const returnTransformer = new ReturnTransformer();
94        const signatureTransformer = new SignatureTransformer();
95        const internalsTransformer = new InternalsTransformer({ positionalIdTracker });
96        const functionTransformer = new FunctionTransformer({
97            positionalIdTracker,
98            parameterTransformer,
99            returnTransformer,
100            signatureTransformer,
101            internalsTransformer
102        });
103        const skipPrefixNames = isFrameworkMode
104            ? EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK
105            : EXTERNAL_SOURCE_PREFIX_NAMES;
106        const programVisitor = new ProgramVisitor({
107            pluginName: unmemoizeTransform.name,
108            state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED,
109            visitors: [functionTransformer],
110            skipPrefixNames,
111            pluginContext,
112        });
113        program = programVisitor.programVisitor(program);
114    }
115    return program;
116}