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}