1/* 2 * Copyright (c) 2024 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 { 17 Identifier, 18 isComputedPropertyName, 19 isConstructorDeclaration, 20 isFunctionDeclaration, 21 isFunctionExpression, 22 isIdentifier, 23 isMethodDeclaration, 24 isNumericLiteral, 25 isParameter, 26 isStringLiteralLike, 27 isTypeParameterDeclaration, 28} from 'typescript'; 29import type { 30 Declaration, 31 Node, 32 NumericLiteral, 33 PropertyName, 34 SourceFile, 35 StringLiteral, 36 StringLiteralLike, 37 Symbol, 38 TypeChecker, 39} from 'typescript'; 40import type { INameObfuscationOption } from '../configs/INameObfuscationOption'; 41import { NodeUtils } from './NodeUtils'; 42import { isReservedProperty } from './TransformUtil'; 43import type { MangledSymbolInfo } from '../common/type'; 44import { nodeSymbolMap } from './ScopeAnalyzer'; 45 46// Determine that the current file is a declaration file and that the option to keep parameters is enabled 47export function shouldKeepCurFileParamerters(sourceFile: SourceFile, config: INameObfuscationOption): boolean { 48 return !!(sourceFile.isDeclarationFile && config.mKeepParameterNames); 49} 50 51// Determine whether the current parameter name needs to be obfuscated. 52export function shouldKeepParameter(decl: Declaration | undefined, config: INameObfuscationOption, mangledSymbolNames: Map<Symbol, MangledSymbolInfo>, 53 checker: TypeChecker): boolean { 54 if (!decl || (!isParameter(decl) && !isTypeParameterDeclaration(decl)) || !isIdentifier(decl.name) || !decl.parent) { 55 return false; 56 } 57 const parentNode: Node = decl.parent; 58 59 if ((isFunctionDeclaration(parentNode) || isFunctionExpression(parentNode))) { 60 const functionName: Identifier | undefined = parentNode.name; 61 return !!functionName && !isObfuscatedName(functionName, mangledSymbolNames, checker); 62 } 63 64 if (isMethodDeclaration(parentNode)) { 65 if (!config.mRenameProperties) { 66 return true; 67 } 68 let methodName: Identifier | NumericLiteral | StringLiteralLike | undefined = getPropertyNameOfMethod(parentNode.name); 69 return !!methodName && NodeUtils.isPropertyNameType(methodName) && isReservedProperty(methodName.text); 70 } 71 72 if (isConstructorDeclaration(parentNode)) { 73 const className: Identifier | undefined = parentNode.parent.name; 74 return !!className && !isObfuscatedName(className, mangledSymbolNames, checker); 75 } 76 77 return false; 78} 79 80function isObfuscatedName(name: Identifier, mangledSymbolNames: Map<Symbol, MangledSymbolInfo>, checker: TypeChecker): boolean { 81 const sym: Symbol | undefined = NodeUtils.findSymbolOfIdentifier(checker, name, nodeSymbolMap); 82 const symbolInfo: MangledSymbolInfo | undefined = mangledSymbolNames.get(sym); 83 if (symbolInfo && symbolInfo.mangledName !== name.text) { 84 return true; 85 } 86 return false; 87} 88 89function getPropertyNameOfMethod(propertyName: PropertyName): Identifier | NumericLiteral | StringLiteralLike | undefined { 90 if (isComputedPropertyName(propertyName)) { 91 if (isStringLiteralLike(propertyName.expression) || isNumericLiteral(propertyName.expression) || isIdentifier(propertyName.expression)) { 92 return propertyName.expression; 93 } 94 return undefined; 95 } 96 return propertyName as Identifier | NumericLiteral | StringLiteral; 97}