13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ciimport { 173af6ab5fSopenharmony_ci SyntaxKind, 183af6ab5fSopenharmony_ci factory, 193af6ab5fSopenharmony_ci forEachChild, 203af6ab5fSopenharmony_ci isBreakOrContinueStatement, 213af6ab5fSopenharmony_ci isConstructorDeclaration, 223af6ab5fSopenharmony_ci isExportSpecifier, 233af6ab5fSopenharmony_ci isIdentifier, 243af6ab5fSopenharmony_ci isImportSpecifier, 253af6ab5fSopenharmony_ci isLabeledStatement, 263af6ab5fSopenharmony_ci isMetaProperty, 273af6ab5fSopenharmony_ci isSourceFile, 283af6ab5fSopenharmony_ci isStructDeclaration, 293af6ab5fSopenharmony_ci setParentRecursive, 303af6ab5fSopenharmony_ci visitEachChild, 313af6ab5fSopenharmony_ci isPropertyDeclaration, 323af6ab5fSopenharmony_ci isMethodDeclaration, 333af6ab5fSopenharmony_ci isGetAccessor, 343af6ab5fSopenharmony_ci isSetAccessor, 353af6ab5fSopenharmony_ci isClassDeclaration, 363af6ab5fSopenharmony_ci isFunctionExpression, 373af6ab5fSopenharmony_ci isArrowFunction, 383af6ab5fSopenharmony_ci isVariableDeclaration, 393af6ab5fSopenharmony_ci isPropertyAssignment, 403af6ab5fSopenharmony_ci isPrivateIdentifier 413af6ab5fSopenharmony_ci} from 'typescript'; 423af6ab5fSopenharmony_ci 433af6ab5fSopenharmony_ciimport type { 443af6ab5fSopenharmony_ci ClassElement, 453af6ab5fSopenharmony_ci Identifier, 463af6ab5fSopenharmony_ci Node, 473af6ab5fSopenharmony_ci SourceFile, 483af6ab5fSopenharmony_ci StructDeclaration, 493af6ab5fSopenharmony_ci Symbol, 503af6ab5fSopenharmony_ci TransformationContext, 513af6ab5fSopenharmony_ci Transformer, 523af6ab5fSopenharmony_ci TransformerFactory, 533af6ab5fSopenharmony_ci TypeChecker 543af6ab5fSopenharmony_ci} from 'typescript'; 553af6ab5fSopenharmony_ci 563af6ab5fSopenharmony_ciimport { 573af6ab5fSopenharmony_ci createScopeManager, 583af6ab5fSopenharmony_ci isClassScope, 593af6ab5fSopenharmony_ci isGlobalScope, 603af6ab5fSopenharmony_ci isEnumScope, 613af6ab5fSopenharmony_ci isInterfaceScope, 623af6ab5fSopenharmony_ci isObjectLiteralScope, 633af6ab5fSopenharmony_ci noSymbolIdentifier, 643af6ab5fSopenharmony_ci} from '../../utils/ScopeAnalyzer'; 653af6ab5fSopenharmony_ci 663af6ab5fSopenharmony_ciimport type { 673af6ab5fSopenharmony_ci Label, 683af6ab5fSopenharmony_ci Scope, 693af6ab5fSopenharmony_ci ScopeManager 703af6ab5fSopenharmony_ci} from '../../utils/ScopeAnalyzer'; 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ciimport { 733af6ab5fSopenharmony_ci IDENTIFIER_CACHE, 743af6ab5fSopenharmony_ci MEM_METHOD_CACHE 753af6ab5fSopenharmony_ci} from '../../utils/NameCacheUtil'; 763af6ab5fSopenharmony_ci 773af6ab5fSopenharmony_ciimport type {INameGenerator, NameGeneratorOptions} from '../../generator/INameGenerator'; 783af6ab5fSopenharmony_ciimport type {IOptions} from '../../configs/IOptions'; 793af6ab5fSopenharmony_ciimport type { INameObfuscationOption, IUnobfuscationOption } from '../../configs/INameObfuscationOption'; 803af6ab5fSopenharmony_ciimport type {TransformPlugin} from '../TransformPlugin'; 813af6ab5fSopenharmony_ciimport type { MangledSymbolInfo } from '../../common/type'; 823af6ab5fSopenharmony_ciimport {TransformerOrder} from '../TransformPlugin'; 833af6ab5fSopenharmony_ciimport {getNameGenerator, NameGeneratorType} from '../../generator/NameFactory'; 843af6ab5fSopenharmony_ciimport {TypeUtils} from '../../utils/TypeUtils'; 853af6ab5fSopenharmony_ciimport { 863af6ab5fSopenharmony_ci isInTopLevelWhitelist, 873af6ab5fSopenharmony_ci isInLocalWhitelist, 883af6ab5fSopenharmony_ci isReservedLocalVariable, 893af6ab5fSopenharmony_ci isReservedTopLevel, 903af6ab5fSopenharmony_ci recordHistoryUnobfuscatedNames 913af6ab5fSopenharmony_ci} from '../../utils/TransformUtil'; 923af6ab5fSopenharmony_ciimport {NodeUtils} from '../../utils/NodeUtils'; 933af6ab5fSopenharmony_ciimport {ApiExtractor} from '../../common/ApiExtractor'; 943af6ab5fSopenharmony_ciimport {performancePrinter, ArkObfuscator, cleanFileMangledNames} from '../../ArkObfuscator'; 953af6ab5fSopenharmony_ciimport { EventList } from '../../utils/PrinterUtils'; 963af6ab5fSopenharmony_ciimport { isViewPUBasedClass } from '../../utils/OhsUtil'; 973af6ab5fSopenharmony_ciimport { 983af6ab5fSopenharmony_ci PropCollections, 993af6ab5fSopenharmony_ci UnobfuscationCollections, 1003af6ab5fSopenharmony_ci LocalVariableCollections 1013af6ab5fSopenharmony_ci} from '../../utils/CommonCollections'; 1023af6ab5fSopenharmony_ci 1033af6ab5fSopenharmony_cinamespace secharmony { 1043af6ab5fSopenharmony_ci /** 1053af6ab5fSopenharmony_ci * Rename Identifiers, including: 1063af6ab5fSopenharmony_ci * 1. variable name 1073af6ab5fSopenharmony_ci * 2. function name 1083af6ab5fSopenharmony_ci * 3. label name 1093af6ab5fSopenharmony_ci * 4. class name/interface name/ label name 1103af6ab5fSopenharmony_ci * we need implement some features: 1113af6ab5fSopenharmony_ci * 1. rename identifiers 1123af6ab5fSopenharmony_ci * 2. store/restore name to/from nameCache file. 1133af6ab5fSopenharmony_ci * 3. do scope analysis for identifier obfuscations 1143af6ab5fSopenharmony_ci * 1153af6ab5fSopenharmony_ci * @param option 1163af6ab5fSopenharmony_ci */ 1173af6ab5fSopenharmony_ci const createRenameIdentifierFactory = function (option: IOptions): TransformerFactory<Node> { 1183af6ab5fSopenharmony_ci const profile: INameObfuscationOption | undefined = option?.mNameObfuscation; 1193af6ab5fSopenharmony_ci const unobfuscationOption: IUnobfuscationOption | undefined = option?.mUnobfuscationOption; 1203af6ab5fSopenharmony_ci if (!profile || !profile.mEnable) { 1213af6ab5fSopenharmony_ci return null; 1223af6ab5fSopenharmony_ci } 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci let options: NameGeneratorOptions = {}; 1253af6ab5fSopenharmony_ci let generator: INameGenerator = getNameGenerator(profile.mNameGeneratorType, options); 1263af6ab5fSopenharmony_ci 1273af6ab5fSopenharmony_ci const openTopLevel: boolean = option?.mNameObfuscation?.mTopLevel; 1283af6ab5fSopenharmony_ci const exportObfuscation: boolean = option?.mExportObfuscation; 1293af6ab5fSopenharmony_ci let isInitializedReservedList = false; 1303af6ab5fSopenharmony_ci return renameIdentifierFactory; 1313af6ab5fSopenharmony_ci 1323af6ab5fSopenharmony_ci function renameIdentifierFactory(context: TransformationContext): Transformer<Node> { 1333af6ab5fSopenharmony_ci initWhitelist(); 1343af6ab5fSopenharmony_ci let mangledSymbolNames: Map<Symbol, MangledSymbolInfo> = new Map<Symbol, MangledSymbolInfo>(); 1353af6ab5fSopenharmony_ci let mangledLabelNames: Map<Label, string> = new Map<Label, string>(); 1363af6ab5fSopenharmony_ci let fileExportNames: Set<string> = undefined; 1373af6ab5fSopenharmony_ci let fileImportNames: Set<string> = undefined; 1383af6ab5fSopenharmony_ci noSymbolIdentifier.clear(); 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci let historyMangledNames: Set<string> = undefined; 1413af6ab5fSopenharmony_ci if (historyNameCache && historyNameCache.size > 0) { 1423af6ab5fSopenharmony_ci historyMangledNames = new Set<string>(Array.from(historyNameCache.values())); 1433af6ab5fSopenharmony_ci } 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci let checker: TypeChecker = undefined; 1463af6ab5fSopenharmony_ci let manager: ScopeManager = createScopeManager(); 1473af6ab5fSopenharmony_ci 1483af6ab5fSopenharmony_ci return renameTransformer; 1493af6ab5fSopenharmony_ci 1503af6ab5fSopenharmony_ci /** 1513af6ab5fSopenharmony_ci * Transformer to rename identifiers 1523af6ab5fSopenharmony_ci * 1533af6ab5fSopenharmony_ci * @param node ast node of a file. 1543af6ab5fSopenharmony_ci */ 1553af6ab5fSopenharmony_ci function renameTransformer(node: Node): Node { 1563af6ab5fSopenharmony_ci if (nameCache.size === 0) { 1573af6ab5fSopenharmony_ci nameCache.set(IDENTIFIER_CACHE, new Map<string, string>()); 1583af6ab5fSopenharmony_ci nameCache.set(MEM_METHOD_CACHE, new Map<string, string>()); 1593af6ab5fSopenharmony_ci } 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_ci if (!isSourceFile(node) || ArkObfuscator.isKeptCurrentFile) { 1623af6ab5fSopenharmony_ci return node; 1633af6ab5fSopenharmony_ci } 1643af6ab5fSopenharmony_ci 1653af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.startEvent(EventList.CREATE_CHECKER, performancePrinter.timeSumPrinter); 1663af6ab5fSopenharmony_ci checker = TypeUtils.createChecker(node); 1673af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.endEvent(EventList.CREATE_CHECKER, performancePrinter.timeSumPrinter); 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.startEvent(EventList.SCOPE_ANALYZE, performancePrinter.timeSumPrinter); 1703af6ab5fSopenharmony_ci manager.analyze(node, checker, exportObfuscation); 1713af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.endEvent(EventList.SCOPE_ANALYZE, performancePrinter.timeSumPrinter); 1723af6ab5fSopenharmony_ci 1733af6ab5fSopenharmony_ci let root: Scope = manager.getRootScope(); 1743af6ab5fSopenharmony_ci fileExportNames = root.fileExportNames; 1753af6ab5fSopenharmony_ci fileImportNames = root.fileImportNames; 1763af6ab5fSopenharmony_ci 1773af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.startEvent(EventList.CREATE_OBFUSCATED_NAMES, performancePrinter.timeSumPrinter); 1783af6ab5fSopenharmony_ci renameInScope(root); 1793af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.endEvent(EventList.CREATE_OBFUSCATED_NAMES, performancePrinter.timeSumPrinter); 1803af6ab5fSopenharmony_ci 1813af6ab5fSopenharmony_ci root = undefined; 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.startEvent(EventList.OBFUSCATE_NODES, performancePrinter.timeSumPrinter); 1843af6ab5fSopenharmony_ci let ret: Node = visit(node); 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ci let parentNodes = setParentRecursive(ret, true); 1873af6ab5fSopenharmony_ci performancePrinter?.singleFilePrinter?.endEvent(EventList.OBFUSCATE_NODES, performancePrinter.timeSumPrinter); 1883af6ab5fSopenharmony_ci return parentNodes; 1893af6ab5fSopenharmony_ci } 1903af6ab5fSopenharmony_ci 1913af6ab5fSopenharmony_ci /** 1923af6ab5fSopenharmony_ci * rename symbol table store in scopes... 1933af6ab5fSopenharmony_ci * 1943af6ab5fSopenharmony_ci * @param scope scope, such as global, module, function, block 1953af6ab5fSopenharmony_ci */ 1963af6ab5fSopenharmony_ci function renameInScope(scope: Scope): void { 1973af6ab5fSopenharmony_ci // process labels in scope, the label can't rename as the name of top labels. 1983af6ab5fSopenharmony_ci renameLabelsInScope(scope); 1993af6ab5fSopenharmony_ci // process symbols in scope, exclude property name. 2003af6ab5fSopenharmony_ci renameNamesInScope(scope); 2013af6ab5fSopenharmony_ci 2023af6ab5fSopenharmony_ci let subScope = undefined; 2033af6ab5fSopenharmony_ci while (scope.children.length > 0) { 2043af6ab5fSopenharmony_ci subScope = scope.children.pop(); 2053af6ab5fSopenharmony_ci renameInScope(subScope); 2063af6ab5fSopenharmony_ci subScope = undefined; 2073af6ab5fSopenharmony_ci } 2083af6ab5fSopenharmony_ci } 2093af6ab5fSopenharmony_ci 2103af6ab5fSopenharmony_ci function renameNamesInScope(scope: Scope): void { 2113af6ab5fSopenharmony_ci if (isExcludeScope(scope)) { 2123af6ab5fSopenharmony_ci return; 2133af6ab5fSopenharmony_ci } 2143af6ab5fSopenharmony_ci 2153af6ab5fSopenharmony_ci if (!exportObfuscation) { 2163af6ab5fSopenharmony_ci scope.defs.forEach((def) => { 2173af6ab5fSopenharmony_ci let parentScope = scope; 2183af6ab5fSopenharmony_ci while (parentScope) { 2193af6ab5fSopenharmony_ci if (parentScope.importNames && parentScope.importNames.has(def.name)) { 2203af6ab5fSopenharmony_ci scope.defs.delete(def); 2213af6ab5fSopenharmony_ci scope.mangledNames.add(def.name); 2223af6ab5fSopenharmony_ci } 2233af6ab5fSopenharmony_ci parentScope = parentScope.parent; 2243af6ab5fSopenharmony_ci } 2253af6ab5fSopenharmony_ci }); 2263af6ab5fSopenharmony_ci } 2273af6ab5fSopenharmony_ci 2283af6ab5fSopenharmony_ci renames(scope, scope.defs, generator); 2293af6ab5fSopenharmony_ci } 2303af6ab5fSopenharmony_ci 2313af6ab5fSopenharmony_ci function renames(scope: Scope, defs: Set<Symbol>, generator: INameGenerator): void { 2323af6ab5fSopenharmony_ci defs.forEach((def) => { 2333af6ab5fSopenharmony_ci const original: string = def.name; 2343af6ab5fSopenharmony_ci let mangled: string = original; 2353af6ab5fSopenharmony_ci const path: string = scope.loc + '#' + original; 2363af6ab5fSopenharmony_ci // No allow to rename reserved names. 2373af6ab5fSopenharmony_ci if (!Reflect.has(def, 'obfuscateAsProperty') && 2383af6ab5fSopenharmony_ci isInLocalWhitelist(original, UnobfuscationCollections.unobfuscatedNamesMap, path) || 2393af6ab5fSopenharmony_ci (!exportObfuscation && scope.exportNames.has(def.name)) || 2403af6ab5fSopenharmony_ci isSkippedGlobal(openTopLevel, scope)) { 2413af6ab5fSopenharmony_ci scope.mangledNames.add(mangled); 2423af6ab5fSopenharmony_ci mangledSymbolNames.set(def, {mangledName: mangled, originalNameWithScope: path}); 2433af6ab5fSopenharmony_ci return; 2443af6ab5fSopenharmony_ci } 2453af6ab5fSopenharmony_ci 2463af6ab5fSopenharmony_ci if (mangledSymbolNames.has(def)) { 2473af6ab5fSopenharmony_ci return; 2483af6ab5fSopenharmony_ci } 2493af6ab5fSopenharmony_ci 2503af6ab5fSopenharmony_ci const historyName: string = historyNameCache?.get(path); 2513af6ab5fSopenharmony_ci if (historyName) { 2523af6ab5fSopenharmony_ci recordHistoryUnobfuscatedNames(path); // For incremental build 2533af6ab5fSopenharmony_ci mangled = historyName; 2543af6ab5fSopenharmony_ci } else if (Reflect.has(def, 'obfuscateAsProperty')) { 2553af6ab5fSopenharmony_ci // obfuscate toplevel, export 2563af6ab5fSopenharmony_ci mangled = getPropertyMangledName(original, path); 2573af6ab5fSopenharmony_ci } else { 2583af6ab5fSopenharmony_ci // obfuscate local variable 2593af6ab5fSopenharmony_ci mangled = getMangled(scope, generator); 2603af6ab5fSopenharmony_ci } 2613af6ab5fSopenharmony_ci // add new names to name cache 2623af6ab5fSopenharmony_ci let identifierCache = nameCache?.get(IDENTIFIER_CACHE); 2633af6ab5fSopenharmony_ci (identifierCache as Map<string, string>).set(path, mangled); 2643af6ab5fSopenharmony_ci let symbolInfo: MangledSymbolInfo = { 2653af6ab5fSopenharmony_ci mangledName: mangled, 2663af6ab5fSopenharmony_ci originalNameWithScope: path 2673af6ab5fSopenharmony_ci }; 2683af6ab5fSopenharmony_ci scope.mangledNames.add(mangled); 2693af6ab5fSopenharmony_ci mangledSymbolNames.set(def, symbolInfo); 2703af6ab5fSopenharmony_ci }); 2713af6ab5fSopenharmony_ci } 2723af6ab5fSopenharmony_ci 2733af6ab5fSopenharmony_ci function getPropertyMangledName(original: string, nameWithScope: string): string { 2743af6ab5fSopenharmony_ci if (isInTopLevelWhitelist(original, UnobfuscationCollections.unobfuscatedNamesMap, nameWithScope)) { 2753af6ab5fSopenharmony_ci return original; 2763af6ab5fSopenharmony_ci } 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_ci const historyName: string = PropCollections.historyMangledTable?.get(original); 2793af6ab5fSopenharmony_ci let mangledName: string = historyName ? historyName : PropCollections.globalMangledTable.get(original); 2803af6ab5fSopenharmony_ci while (!mangledName) { 2813af6ab5fSopenharmony_ci let tmpName = generator.getName(); 2823af6ab5fSopenharmony_ci if (isReservedTopLevel(tmpName) || 2833af6ab5fSopenharmony_ci tmpName === original) { 2843af6ab5fSopenharmony_ci continue; 2853af6ab5fSopenharmony_ci } 2863af6ab5fSopenharmony_ci 2873af6ab5fSopenharmony_ci /** 2883af6ab5fSopenharmony_ci * In case b is obfuscated as a when only enable toplevel obfuscation: 2893af6ab5fSopenharmony_ci * let b = 1; 2903af6ab5fSopenharmony_ci * export let a = 1; 2913af6ab5fSopenharmony_ci */ 2923af6ab5fSopenharmony_ci if (cleanFileMangledNames && fileExportNames && fileExportNames.has(tmpName)) { 2933af6ab5fSopenharmony_ci continue; 2943af6ab5fSopenharmony_ci } 2953af6ab5fSopenharmony_ci 2963af6ab5fSopenharmony_ci /** 2973af6ab5fSopenharmony_ci * In case b is obfuscated as a when only enable toplevel obfuscation: 2983af6ab5fSopenharmony_ci * import {a} from 'filePath'; 2993af6ab5fSopenharmony_ci * let b = 1; 3003af6ab5fSopenharmony_ci */ 3013af6ab5fSopenharmony_ci if (cleanFileMangledNames && fileImportNames.has(tmpName)) { 3023af6ab5fSopenharmony_ci continue; 3033af6ab5fSopenharmony_ci } 3043af6ab5fSopenharmony_ci 3053af6ab5fSopenharmony_ci /** 3063af6ab5fSopenharmony_ci * In case a newly added variable get an obfuscated name that is already in history namecache 3073af6ab5fSopenharmony_ci */ 3083af6ab5fSopenharmony_ci if (historyMangledNames && historyMangledNames.has(tmpName)) { 3093af6ab5fSopenharmony_ci continue; 3103af6ab5fSopenharmony_ci } 3113af6ab5fSopenharmony_ci 3123af6ab5fSopenharmony_ci if (PropCollections.newlyOccupiedMangledProps.has(tmpName) || PropCollections.mangledPropsInNameCache.has(tmpName)) { 3133af6ab5fSopenharmony_ci continue; 3143af6ab5fSopenharmony_ci } 3153af6ab5fSopenharmony_ci 3163af6ab5fSopenharmony_ci if (ApiExtractor.mConstructorPropertySet?.has(tmpName)) { 3173af6ab5fSopenharmony_ci continue; 3183af6ab5fSopenharmony_ci } 3193af6ab5fSopenharmony_ci 3203af6ab5fSopenharmony_ci mangledName = tmpName; 3213af6ab5fSopenharmony_ci } 3223af6ab5fSopenharmony_ci 3233af6ab5fSopenharmony_ci PropCollections.globalMangledTable.set(original, mangledName); 3243af6ab5fSopenharmony_ci PropCollections.newlyOccupiedMangledProps.add(mangledName); 3253af6ab5fSopenharmony_ci return mangledName; 3263af6ab5fSopenharmony_ci } 3273af6ab5fSopenharmony_ci 3283af6ab5fSopenharmony_ci function isExcludeScope(scope: Scope): boolean { 3293af6ab5fSopenharmony_ci if (isClassScope(scope)) { 3303af6ab5fSopenharmony_ci return true; 3313af6ab5fSopenharmony_ci } 3323af6ab5fSopenharmony_ci 3333af6ab5fSopenharmony_ci if (isInterfaceScope(scope)) { 3343af6ab5fSopenharmony_ci return true; 3353af6ab5fSopenharmony_ci } 3363af6ab5fSopenharmony_ci 3373af6ab5fSopenharmony_ci if (isEnumScope(scope)) { 3383af6ab5fSopenharmony_ci return true; 3393af6ab5fSopenharmony_ci } 3403af6ab5fSopenharmony_ci 3413af6ab5fSopenharmony_ci return isObjectLiteralScope(scope); 3423af6ab5fSopenharmony_ci } 3433af6ab5fSopenharmony_ci 3443af6ab5fSopenharmony_ci function searchMangledInParent(scope: Scope, name: string): boolean { 3453af6ab5fSopenharmony_ci let found: boolean = false; 3463af6ab5fSopenharmony_ci let parentScope = scope; 3473af6ab5fSopenharmony_ci while (parentScope) { 3483af6ab5fSopenharmony_ci if (parentScope.mangledNames.has(name)) { 3493af6ab5fSopenharmony_ci found = true; 3503af6ab5fSopenharmony_ci break; 3513af6ab5fSopenharmony_ci } 3523af6ab5fSopenharmony_ci 3533af6ab5fSopenharmony_ci parentScope = parentScope.parent; 3543af6ab5fSopenharmony_ci } 3553af6ab5fSopenharmony_ci 3563af6ab5fSopenharmony_ci return found; 3573af6ab5fSopenharmony_ci } 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ci function getMangled(scope: Scope, localGenerator: INameGenerator): string { 3603af6ab5fSopenharmony_ci let mangled: string = ''; 3613af6ab5fSopenharmony_ci do { 3623af6ab5fSopenharmony_ci mangled = localGenerator.getName()!; 3633af6ab5fSopenharmony_ci // if it is a globally reserved name, it needs to be regenerated 3643af6ab5fSopenharmony_ci if (isReservedLocalVariable(mangled)) { 3653af6ab5fSopenharmony_ci mangled = ''; 3663af6ab5fSopenharmony_ci continue; 3673af6ab5fSopenharmony_ci } 3683af6ab5fSopenharmony_ci 3693af6ab5fSopenharmony_ci if (fileExportNames && fileExportNames.has(mangled)) { 3703af6ab5fSopenharmony_ci mangled = ''; 3713af6ab5fSopenharmony_ci continue; 3723af6ab5fSopenharmony_ci } 3733af6ab5fSopenharmony_ci 3743af6ab5fSopenharmony_ci if (historyMangledNames && historyMangledNames.has(mangled)) { 3753af6ab5fSopenharmony_ci mangled = ''; 3763af6ab5fSopenharmony_ci continue; 3773af6ab5fSopenharmony_ci } 3783af6ab5fSopenharmony_ci 3793af6ab5fSopenharmony_ci if (searchMangledInParent(scope, mangled)) { 3803af6ab5fSopenharmony_ci mangled = ''; 3813af6ab5fSopenharmony_ci continue; 3823af6ab5fSopenharmony_ci } 3833af6ab5fSopenharmony_ci 3843af6ab5fSopenharmony_ci if (ApiExtractor.mConstructorPropertySet?.has(mangled)) { 3853af6ab5fSopenharmony_ci mangled = ''; 3863af6ab5fSopenharmony_ci } 3873af6ab5fSopenharmony_ci } while (mangled === ''); 3883af6ab5fSopenharmony_ci 3893af6ab5fSopenharmony_ci return mangled; 3903af6ab5fSopenharmony_ci } 3913af6ab5fSopenharmony_ci 3923af6ab5fSopenharmony_ci function renameLabelsInScope(scope: Scope): void { 3933af6ab5fSopenharmony_ci const labels: Label[] = scope.labels; 3943af6ab5fSopenharmony_ci if (labels.length > 0) { 3953af6ab5fSopenharmony_ci let upperMangledLabels = getUpperMangledLabelNames(labels[0]); 3963af6ab5fSopenharmony_ci for (const label of labels) { 3973af6ab5fSopenharmony_ci let mangledLabel = getMangledLabel(label, upperMangledLabels); 3983af6ab5fSopenharmony_ci mangledLabelNames.set(label, mangledLabel); 3993af6ab5fSopenharmony_ci } 4003af6ab5fSopenharmony_ci } 4013af6ab5fSopenharmony_ci } 4023af6ab5fSopenharmony_ci 4033af6ab5fSopenharmony_ci function getMangledLabel(label: Label, mangledLabels: string[]): string { 4043af6ab5fSopenharmony_ci let mangledLabel: string = ''; 4053af6ab5fSopenharmony_ci do { 4063af6ab5fSopenharmony_ci mangledLabel = generator.getName(); 4073af6ab5fSopenharmony_ci if (mangledLabel === label.name) { 4083af6ab5fSopenharmony_ci mangledLabel = ''; 4093af6ab5fSopenharmony_ci } 4103af6ab5fSopenharmony_ci 4113af6ab5fSopenharmony_ci if (mangledLabels.includes(mangledLabel)) { 4123af6ab5fSopenharmony_ci mangledLabel = ''; 4133af6ab5fSopenharmony_ci } 4143af6ab5fSopenharmony_ci } while (mangledLabel === ''); 4153af6ab5fSopenharmony_ci 4163af6ab5fSopenharmony_ci return mangledLabel; 4173af6ab5fSopenharmony_ci } 4183af6ab5fSopenharmony_ci 4193af6ab5fSopenharmony_ci function getUpperMangledLabelNames(label: Label): string[] { 4203af6ab5fSopenharmony_ci const results: string[] = []; 4213af6ab5fSopenharmony_ci let parent: Label = label.parent; 4223af6ab5fSopenharmony_ci while (parent) { 4233af6ab5fSopenharmony_ci let mangledLabelName: string = mangledLabelNames.get(parent); 4243af6ab5fSopenharmony_ci if (mangledLabelName) { 4253af6ab5fSopenharmony_ci results.push(mangledLabelName); 4263af6ab5fSopenharmony_ci } 4273af6ab5fSopenharmony_ci parent = parent.parent; 4283af6ab5fSopenharmony_ci } 4293af6ab5fSopenharmony_ci 4303af6ab5fSopenharmony_ci return results; 4313af6ab5fSopenharmony_ci } 4323af6ab5fSopenharmony_ci 4333af6ab5fSopenharmony_ci function isFunctionLike(node: Node): boolean { 4343af6ab5fSopenharmony_ci switch (node.kind) { 4353af6ab5fSopenharmony_ci case SyntaxKind.FunctionDeclaration: 4363af6ab5fSopenharmony_ci case SyntaxKind.MethodDeclaration: 4373af6ab5fSopenharmony_ci case SyntaxKind.GetAccessor: 4383af6ab5fSopenharmony_ci case SyntaxKind.SetAccessor: 4393af6ab5fSopenharmony_ci case SyntaxKind.Constructor: 4403af6ab5fSopenharmony_ci case SyntaxKind.FunctionExpression: 4413af6ab5fSopenharmony_ci case SyntaxKind.ArrowFunction: 4423af6ab5fSopenharmony_ci return true; 4433af6ab5fSopenharmony_ci } 4443af6ab5fSopenharmony_ci return false; 4453af6ab5fSopenharmony_ci } 4463af6ab5fSopenharmony_ci 4473af6ab5fSopenharmony_ci function nodeHasFunctionLikeChild(node: Node): boolean { 4483af6ab5fSopenharmony_ci let hasFunctionLikeChild: boolean = false; 4493af6ab5fSopenharmony_ci let childVisitor: (child: Node) => Node = (child: Node): Node => { 4503af6ab5fSopenharmony_ci if (!hasFunctionLikeChild && child && isFunctionLike(child)) { 4513af6ab5fSopenharmony_ci hasFunctionLikeChild = true; 4523af6ab5fSopenharmony_ci } 4533af6ab5fSopenharmony_ci return child; 4543af6ab5fSopenharmony_ci }; 4553af6ab5fSopenharmony_ci visitEachChild(node, childVisitor, context); 4563af6ab5fSopenharmony_ci return hasFunctionLikeChild; 4573af6ab5fSopenharmony_ci } 4583af6ab5fSopenharmony_ci 4593af6ab5fSopenharmony_ci /** 4603af6ab5fSopenharmony_ci * visit each node to change identifier name to mangled name 4613af6ab5fSopenharmony_ci * - calculate shadow name index to find shadow node 4623af6ab5fSopenharmony_ci * @param node 4633af6ab5fSopenharmony_ci */ 4643af6ab5fSopenharmony_ci function visit(node: Node): Node { 4653af6ab5fSopenharmony_ci let needHandlePositionInfo: boolean = isFunctionLike(node) || nodeHasFunctionLikeChild(node); 4663af6ab5fSopenharmony_ci if (needHandlePositionInfo) { 4673af6ab5fSopenharmony_ci // Obtain line info for nameCache. 4683af6ab5fSopenharmony_ci handlePositionInfo(node); 4693af6ab5fSopenharmony_ci } 4703af6ab5fSopenharmony_ci 4713af6ab5fSopenharmony_ci if (!isIdentifier(node) || !node.parent) { 4723af6ab5fSopenharmony_ci return visitEachChild(node, visit, context); 4733af6ab5fSopenharmony_ci } 4743af6ab5fSopenharmony_ci 4753af6ab5fSopenharmony_ci if (isLabeledStatement(node.parent) || isBreakOrContinueStatement(node.parent)) { 4763af6ab5fSopenharmony_ci return updateLabelNode(node); 4773af6ab5fSopenharmony_ci } 4783af6ab5fSopenharmony_ci 4793af6ab5fSopenharmony_ci return updateNameNode(node); 4803af6ab5fSopenharmony_ci } 4813af6ab5fSopenharmony_ci 4823af6ab5fSopenharmony_ci function handlePositionInfo(node: Node): void { 4833af6ab5fSopenharmony_ci const sourceFile = NodeUtils.getSourceFileOfNode(node); 4843af6ab5fSopenharmony_ci if (node && node.pos < 0 && node.end < 0) { 4853af6ab5fSopenharmony_ci // Node must have a real position for following operations. 4863af6ab5fSopenharmony_ci // Adapting to the situation that the node does not have a real postion. 4873af6ab5fSopenharmony_ci return; 4883af6ab5fSopenharmony_ci } 4893af6ab5fSopenharmony_ci const startPosition = sourceFile.getLineAndCharacterOfPosition(node.getStart()); 4903af6ab5fSopenharmony_ci const endPosition = sourceFile.getLineAndCharacterOfPosition(node.getEnd()); 4913af6ab5fSopenharmony_ci // 1: The line number in sourceFile starts from 0 while in IDE starts from 1. 4923af6ab5fSopenharmony_ci const startLine = startPosition.line + 1; 4933af6ab5fSopenharmony_ci const startCharacter = startPosition.character + 1; // 1: Same as above. 4943af6ab5fSopenharmony_ci const endLine = endPosition.line + 1; // 1: Same as above. 4953af6ab5fSopenharmony_ci const endCharacter = endPosition.character + 1; // 1: Same as above. 4963af6ab5fSopenharmony_ci const lineAndColum: string = ':' + startLine + ':' + startCharacter + ':' + endLine + ':' + endCharacter; 4973af6ab5fSopenharmony_ci 4983af6ab5fSopenharmony_ci let isProperty: boolean = isMethodDeclaration(node) || isGetAccessor(node) || 4993af6ab5fSopenharmony_ci isSetAccessor(node) || (isConstructorDeclaration(node) && 5003af6ab5fSopenharmony_ci !(isClassDeclaration(node.parent) && isViewPUBasedClass(node.parent))); 5013af6ab5fSopenharmony_ci // Arrow functions are anoymous, only function expressions are considered. 5023af6ab5fSopenharmony_ci let isPropertyParent: boolean = isFunctionExpression(node) && 5033af6ab5fSopenharmony_ci (isPropertyDeclaration(node.parent) || isPropertyAssignment(node.parent)); 5043af6ab5fSopenharmony_ci let isMemberMethod: boolean = isProperty || isPropertyParent; 5053af6ab5fSopenharmony_ci if (isMemberMethod) { 5063af6ab5fSopenharmony_ci writeMemberMethodCache(node, lineAndColum); 5073af6ab5fSopenharmony_ci return; 5083af6ab5fSopenharmony_ci } 5093af6ab5fSopenharmony_ci 5103af6ab5fSopenharmony_ci let name = Reflect.get(node, 'name') as Identifier; 5113af6ab5fSopenharmony_ci if (name?.kind === SyntaxKind.Identifier) { 5123af6ab5fSopenharmony_ci identifierLineMap.set(name, lineAndColum); 5133af6ab5fSopenharmony_ci } else if ((isFunctionExpression(node) || isArrowFunction(node)) && isVariableDeclaration(node.parent) && 5143af6ab5fSopenharmony_ci node.parent.name?.kind === SyntaxKind.Identifier) { 5153af6ab5fSopenharmony_ci // The node is anonymous, and we need to find its parent node. 5163af6ab5fSopenharmony_ci // e.g.: let foo = function() {}; 5173af6ab5fSopenharmony_ci identifierLineMap.set(node.parent.name, lineAndColum); 5183af6ab5fSopenharmony_ci } 5193af6ab5fSopenharmony_ci } 5203af6ab5fSopenharmony_ci 5213af6ab5fSopenharmony_ci function writeMemberMethodCache(node: Node, lineAndColum: string): void { 5223af6ab5fSopenharmony_ci let gotNode; 5233af6ab5fSopenharmony_ci if (node.kind === SyntaxKind.Constructor) { 5243af6ab5fSopenharmony_ci gotNode = node.parent; 5253af6ab5fSopenharmony_ci } else if ((node.kind === SyntaxKind.FunctionExpression && 5263af6ab5fSopenharmony_ci (isPropertyDeclaration(node.parent) || isPropertyAssignment(node.parent)))) { 5273af6ab5fSopenharmony_ci gotNode = node.parent.initializer ?? node.parent; 5283af6ab5fSopenharmony_ci } else { 5293af6ab5fSopenharmony_ci gotNode = node; 5303af6ab5fSopenharmony_ci } 5313af6ab5fSopenharmony_ci 5323af6ab5fSopenharmony_ci let isIdentifierNode: boolean = gotNode.name && (isIdentifier(gotNode.name) || isPrivateIdentifier(gotNode.name)); 5333af6ab5fSopenharmony_ci let valueName: string = ''; 5343af6ab5fSopenharmony_ci 5353af6ab5fSopenharmony_ci if (isIdentifierNode) { 5363af6ab5fSopenharmony_ci // The original method for retrieving method names used gotNode.name.escapedText. This approach limited the collection 5373af6ab5fSopenharmony_ci // of method records in MemberMethodCache to cases where gotNode.name was an Identifier or PrivateIdentifier. 5383af6ab5fSopenharmony_ci // To address the issue where method names starting with double underscores were transformed to start with triple underscores, 5393af6ab5fSopenharmony_ci // we changed the retrieval method to use gotNode.name.text instead of escapedText. However, this change introduced the possibility 5403af6ab5fSopenharmony_ci // of collecting method records when gotNode.name is a NumericLiteral or StringLiteral, which is not desired. 5413af6ab5fSopenharmony_ci // To avoid altering the collection specifications of MemberMethodCache, we restricted the collection scenarios 5423af6ab5fSopenharmony_ci // to match the original cases where only identifiers and private identifiers are collected. 5433af6ab5fSopenharmony_ci valueName = gotNode.name.text; 5443af6ab5fSopenharmony_ci } 5453af6ab5fSopenharmony_ci 5463af6ab5fSopenharmony_ci if (valueName === '') { 5473af6ab5fSopenharmony_ci return; 5483af6ab5fSopenharmony_ci } 5493af6ab5fSopenharmony_ci 5503af6ab5fSopenharmony_ci let originalName: string = valueName; 5513af6ab5fSopenharmony_ci let keyName = originalName + lineAndColum; 5523af6ab5fSopenharmony_ci if (node.kind === SyntaxKind.Constructor && classMangledName.has(gotNode.name)) { 5533af6ab5fSopenharmony_ci valueName = classMangledName.get(gotNode.name); 5543af6ab5fSopenharmony_ci classInfoInMemberMethodCache.add(keyName); 5553af6ab5fSopenharmony_ci } 5563af6ab5fSopenharmony_ci let memberMethodCache = nameCache?.get(MEM_METHOD_CACHE); 5573af6ab5fSopenharmony_ci if (memberMethodCache) { 5583af6ab5fSopenharmony_ci (memberMethodCache as Map<string, string>).set(keyName, valueName); 5593af6ab5fSopenharmony_ci } 5603af6ab5fSopenharmony_ci } 5613af6ab5fSopenharmony_ci 5623af6ab5fSopenharmony_ci function updateNameNode(node: Identifier): Node { 5633af6ab5fSopenharmony_ci // skip property in property access expression 5643af6ab5fSopenharmony_ci if (NodeUtils.isPropertyAccessNode(node)) { 5653af6ab5fSopenharmony_ci return node; 5663af6ab5fSopenharmony_ci } 5673af6ab5fSopenharmony_ci 5683af6ab5fSopenharmony_ci if (NodeUtils.isNewTargetNode(node)) { 5693af6ab5fSopenharmony_ci return node; 5703af6ab5fSopenharmony_ci } 5713af6ab5fSopenharmony_ci 5723af6ab5fSopenharmony_ci let sym: Symbol | undefined = NodeUtils.findSymbolOfIdentifier(checker, node); 5733af6ab5fSopenharmony_ci let mangledPropertyNameOfNoSymbolImportExport = ''; 5743af6ab5fSopenharmony_ci if (!sym) { 5753af6ab5fSopenharmony_ci if (exportObfuscation && noSymbolIdentifier.has(node.text) && trySearchImportExportSpecifier(node)) { 5763af6ab5fSopenharmony_ci mangledPropertyNameOfNoSymbolImportExport = mangleNoSymbolImportExportPropertyName(node.text); 5773af6ab5fSopenharmony_ci } else { 5783af6ab5fSopenharmony_ci return node; 5793af6ab5fSopenharmony_ci } 5803af6ab5fSopenharmony_ci } 5813af6ab5fSopenharmony_ci 5823af6ab5fSopenharmony_ci // Add new names to name cache 5833af6ab5fSopenharmony_ci const symbolInfo: MangledSymbolInfo = mangledSymbolNames.get(sym); 5843af6ab5fSopenharmony_ci const identifierCache = nameCache?.get(IDENTIFIER_CACHE); 5853af6ab5fSopenharmony_ci const lineAndColumn = identifierLineMap?.get(node); 5863af6ab5fSopenharmony_ci // We only save the line info of FunctionLike. 5873af6ab5fSopenharmony_ci const isFunction: boolean = sym ? Reflect.has(sym, 'isFunction') : false; 5883af6ab5fSopenharmony_ci if (isFunction && symbolInfo && lineAndColumn) { 5893af6ab5fSopenharmony_ci const originalName = symbolInfo.originalNameWithScope; 5903af6ab5fSopenharmony_ci const pathWithLine: string = originalName + lineAndColumn; 5913af6ab5fSopenharmony_ci (identifierCache as Map<string, string>).set(pathWithLine, symbolInfo.mangledName); 5923af6ab5fSopenharmony_ci (identifierCache as Map<string, string>).delete(originalName); 5933af6ab5fSopenharmony_ci } 5943af6ab5fSopenharmony_ci 5953af6ab5fSopenharmony_ci let mangledName: string = mangledSymbolNames.get(sym)?.mangledName; 5963af6ab5fSopenharmony_ci if (node?.parent.kind === SyntaxKind.ClassDeclaration) { 5973af6ab5fSopenharmony_ci classMangledName.set(node, mangledName); 5983af6ab5fSopenharmony_ci } 5993af6ab5fSopenharmony_ci if (!mangledName && mangledPropertyNameOfNoSymbolImportExport !== '') { 6003af6ab5fSopenharmony_ci mangledName = mangledPropertyNameOfNoSymbolImportExport; 6013af6ab5fSopenharmony_ci } 6023af6ab5fSopenharmony_ci 6033af6ab5fSopenharmony_ci if (!mangledName || mangledName === sym?.name) { 6043af6ab5fSopenharmony_ci return node; 6053af6ab5fSopenharmony_ci } 6063af6ab5fSopenharmony_ci 6073af6ab5fSopenharmony_ci return factory.createIdentifier(mangledName); 6083af6ab5fSopenharmony_ci } 6093af6ab5fSopenharmony_ci 6103af6ab5fSopenharmony_ci function updateLabelNode(node: Identifier): Node { 6113af6ab5fSopenharmony_ci let label: Label | undefined; 6123af6ab5fSopenharmony_ci let labelName: string = ''; 6133af6ab5fSopenharmony_ci 6143af6ab5fSopenharmony_ci mangledLabelNames.forEach((value, key) => { 6153af6ab5fSopenharmony_ci if (key.refs.includes(node)) { 6163af6ab5fSopenharmony_ci label = key; 6173af6ab5fSopenharmony_ci labelName = value; 6183af6ab5fSopenharmony_ci } 6193af6ab5fSopenharmony_ci }); 6203af6ab5fSopenharmony_ci 6213af6ab5fSopenharmony_ci return label ? factory.createIdentifier(labelName) : node; 6223af6ab5fSopenharmony_ci } 6233af6ab5fSopenharmony_ci 6243af6ab5fSopenharmony_ci /** 6253af6ab5fSopenharmony_ci * import {A as B} from 'modulename'; 6263af6ab5fSopenharmony_ci * import {C as D} from 'modulename'; 6273af6ab5fSopenharmony_ci * above A、C have no symbol, so deal with them specially. 6283af6ab5fSopenharmony_ci */ 6293af6ab5fSopenharmony_ci function mangleNoSymbolImportExportPropertyName(original: string): string { 6303af6ab5fSopenharmony_ci const path: string = '#' + original; 6313af6ab5fSopenharmony_ci const historyName: string = historyNameCache?.get(path); 6323af6ab5fSopenharmony_ci let mangled = historyName ?? getPropertyMangledName(original, path); 6333af6ab5fSopenharmony_ci if (nameCache && nameCache.get(IDENTIFIER_CACHE)) { 6343af6ab5fSopenharmony_ci (nameCache.get(IDENTIFIER_CACHE) as Map<string, string>).set(path, mangled); 6353af6ab5fSopenharmony_ci } 6363af6ab5fSopenharmony_ci return mangled; 6373af6ab5fSopenharmony_ci } 6383af6ab5fSopenharmony_ci 6393af6ab5fSopenharmony_ci function trySearchImportExportSpecifier(node: Node): boolean { 6403af6ab5fSopenharmony_ci while (node.parent) { 6413af6ab5fSopenharmony_ci node = node.parent; 6423af6ab5fSopenharmony_ci if ((isImportSpecifier(node) || isExportSpecifier(node)) && node.propertyName && isIdentifier(node.propertyName)) { 6433af6ab5fSopenharmony_ci return true; 6443af6ab5fSopenharmony_ci } 6453af6ab5fSopenharmony_ci } 6463af6ab5fSopenharmony_ci return false; 6473af6ab5fSopenharmony_ci } 6483af6ab5fSopenharmony_ci } 6493af6ab5fSopenharmony_ci 6503af6ab5fSopenharmony_ci function initWhitelist(): void { 6513af6ab5fSopenharmony_ci if (isInitializedReservedList) { 6523af6ab5fSopenharmony_ci return; 6533af6ab5fSopenharmony_ci } 6543af6ab5fSopenharmony_ci if (profile?.mRenameProperties) { 6553af6ab5fSopenharmony_ci PropCollections.enablePropertyObfuscation = true; 6563af6ab5fSopenharmony_ci const tmpReservedProps: string[] = profile?.mReservedProperties ?? []; 6573af6ab5fSopenharmony_ci tmpReservedProps.forEach(item => { 6583af6ab5fSopenharmony_ci PropCollections.reservedProperties.add(item); 6593af6ab5fSopenharmony_ci }); 6603af6ab5fSopenharmony_ci PropCollections.mangledPropsInNameCache = new Set(PropCollections.historyMangledTable?.values()); 6613af6ab5fSopenharmony_ci if (profile?.mUniversalReservedProperties) { 6623af6ab5fSopenharmony_ci PropCollections.universalReservedProperties = [...profile.mUniversalReservedProperties]; 6633af6ab5fSopenharmony_ci } 6643af6ab5fSopenharmony_ci UnobfuscationCollections.reservedLangForTopLevel.forEach(element => { 6653af6ab5fSopenharmony_ci UnobfuscationCollections.reservedLangForProperty.add(element); 6663af6ab5fSopenharmony_ci }); 6673af6ab5fSopenharmony_ci UnobfuscationCollections.reservedExportName.forEach(element => { 6683af6ab5fSopenharmony_ci UnobfuscationCollections.reservedExportNameAndProp.add(element); 6693af6ab5fSopenharmony_ci }); 6703af6ab5fSopenharmony_ci UnobfuscationCollections.reservedSdkApiForGlobal.forEach(element => { 6713af6ab5fSopenharmony_ci UnobfuscationCollections.reservedSdkApiForProp.add(element); 6723af6ab5fSopenharmony_ci }); 6733af6ab5fSopenharmony_ci } 6743af6ab5fSopenharmony_ci LocalVariableCollections.reservedConfig = new Set(profile?.mReservedNames ?? []); 6753af6ab5fSopenharmony_ci LocalVariableCollections.reservedStruct = new Set(); 6763af6ab5fSopenharmony_ci profile?.mReservedToplevelNames?.forEach(item => PropCollections.reservedProperties.add(item)); 6773af6ab5fSopenharmony_ci profile?.mUniversalReservedToplevelNames?.forEach(item => PropCollections.universalReservedProperties.push(item)); 6783af6ab5fSopenharmony_ci isInitializedReservedList = true; 6793af6ab5fSopenharmony_ci } 6803af6ab5fSopenharmony_ci }; 6813af6ab5fSopenharmony_ci 6823af6ab5fSopenharmony_ci function isSkippedGlobal(enableTopLevel: boolean, scope: Scope): boolean { 6833af6ab5fSopenharmony_ci return !enableTopLevel && isGlobalScope(scope); 6843af6ab5fSopenharmony_ci } 6853af6ab5fSopenharmony_ci 6863af6ab5fSopenharmony_ci export let transformerPlugin: TransformPlugin = { 6873af6ab5fSopenharmony_ci 'name': 'renameIdentifierPlugin', 6883af6ab5fSopenharmony_ci 'order': TransformerOrder.RENAME_IDENTIFIER_TRANSFORMER, 6893af6ab5fSopenharmony_ci 'createTransformerFactory': createRenameIdentifierFactory 6903af6ab5fSopenharmony_ci }; 6913af6ab5fSopenharmony_ci 6923af6ab5fSopenharmony_ci export let nameCache: Map<string, string | Map<string, string>> = new Map(); 6933af6ab5fSopenharmony_ci export let historyNameCache: Map<string, string> = undefined; 6943af6ab5fSopenharmony_ci export let historyUnobfuscatedNamesMap: Map<string, string[]> = undefined; 6953af6ab5fSopenharmony_ci export let identifierLineMap: Map<Identifier, string> = new Map(); 6963af6ab5fSopenharmony_ci export let classMangledName: Map<Node, string> = new Map(); 6973af6ab5fSopenharmony_ci // Record the original class name and line number range to distinguish between class names and member method names. 6983af6ab5fSopenharmony_ci export let classInfoInMemberMethodCache: Set<string> = new Set(); 6993af6ab5fSopenharmony_ci 7003af6ab5fSopenharmony_ci export function clearCaches(): void { 7013af6ab5fSopenharmony_ci nameCache.clear(); 7023af6ab5fSopenharmony_ci historyNameCache = undefined; 7033af6ab5fSopenharmony_ci historyUnobfuscatedNamesMap = undefined; 7043af6ab5fSopenharmony_ci identifierLineMap.clear(); 7053af6ab5fSopenharmony_ci classMangledName.clear(); 7063af6ab5fSopenharmony_ci classInfoInMemberMethodCache.clear(); 7073af6ab5fSopenharmony_ci UnobfuscationCollections.unobfuscatedNamesMap.clear(); 7083af6ab5fSopenharmony_ci } 7093af6ab5fSopenharmony_ci} 7103af6ab5fSopenharmony_ci 7113af6ab5fSopenharmony_ciexport = secharmony;