1/* 2 * Copyright (c) 2023 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 forEachChild, 18 getLeadingCommentRangesOfNode, 19 isCallExpression, 20 isExpressionStatement, 21 isIdentifier, 22 isStructDeclaration, 23 SyntaxKind, 24 visitEachChild 25} from 'typescript'; 26 27import type { 28 CommentRange, 29 Identifier, 30 Node, 31 SourceFile, 32 StructDeclaration, 33 TransformationContext 34} from 'typescript'; 35 36/** 37 * collect exist identifier names in current source file 38 * @param sourceFile 39 */ 40export function collectExistNames(sourceFile: SourceFile): Set<string> { 41 const identifiers: Set<string> = new Set<string>(); 42 43 let visit = (node: Node): void => { 44 if (isIdentifier(node)) { 45 identifiers.add(node.text); 46 } 47 48 forEachChild(node, visit); 49 }; 50 51 forEachChild(sourceFile, visit); 52 return identifiers; 53} 54 55type IdentifiersAndStructs = {shadowIdentifiers: Identifier[], shadowStructs: StructDeclaration[]}; 56 57/** 58 * collect exist identifiers in current source file 59 * @param sourceFile 60 * @param context 61 */ 62export function collectIdentifiersAndStructs(sourceFile: SourceFile, context: TransformationContext): IdentifiersAndStructs { 63 const identifiers: Identifier[] = []; 64 const structs: StructDeclaration[] = []; 65 66 let visit = (node: Node): Node => { 67 if (isStructDeclaration(node)) { 68 structs.push(node); 69 } 70 // @ts-ignore 71 if (node.virtual) { 72 return node; 73 } 74 if (!isIdentifier(node) || !node.parent) { 75 return visitEachChild(node, visit, context); 76 } 77 78 identifiers.push(node); 79 return node; 80 }; 81 82 visit(sourceFile); 83 return {shadowIdentifiers: identifiers, shadowStructs: structs}; 84} 85 86export enum OhPackType { 87 NONE, 88 JS_BUNDLE, 89 ES_MODULE 90} 91 92export function isCommentedNode(node: Node, sourceFile: SourceFile): boolean { 93 const ranges: CommentRange[] = getLeadingCommentRangesOfNode(node, sourceFile); 94 return ranges !== undefined; 95} 96 97export function isSuperCallStatement(node: Node): boolean { 98 return isExpressionStatement(node) && 99 isCallExpression(node.expression) && 100 node.expression.expression.kind === SyntaxKind.SuperKeyword; 101} 102