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;