1/* 2 * Copyright (c) 2022 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 isClassDeclaration, isEnumDeclaration, isExportAssignment, isExportDeclaration, isFunctionDeclaration, 18 isImportDeclaration, isInterfaceDeclaration, isModuleDeclaration, isTypeAliasDeclaration, isVariableStatement, 19 SourceFile, SyntaxKind 20} from 'typescript'; 21import { ClassEntity, getClassDeclaration } from './classDeclaration'; 22import { EnumEntity, getEnumDeclaration } from './enumDeclaration'; 23import { FunctionEntity, getFunctionDeclaration } from './functionDeclaration'; 24import { getExportAssignment, getImportDeclaration, ImportElementEntity } from './importAndExportDeclaration'; 25import { getInterfaceDeclaration, InterfaceEntity } from './interfaceDeclaration'; 26import { StaticMethodEntity } from './methodDeclaration'; 27import { getModuleDeclaration, ModuleBlockEntity } from './moduleDeclaration'; 28import { getTypeAliasDeclaration, TypeAliasEntity } from './typeAliasDeclaration'; 29import { getVariableStatementDeclaration, StatementEntity } from './variableStatementResolve'; 30 31/** 32 * assembly all sourceFile node info 33 * @param sourceFile 34 * @param fileName 35 * @returns 36 */ 37export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): SourceFileEntity { 38 const importDeclarations: Array<ImportElementEntity> = []; 39 const moduleDeclarations: Array<ModuleBlockEntity> = []; 40 const typeAliasDeclarations: Array<TypeAliasEntity> = []; 41 const classDeclarations: Array<ClassEntity> = []; 42 const interfaceDeclarations: Array<InterfaceEntity> = []; 43 const enumDeclarations: Array<EnumEntity> = []; 44 let exportAssignment: Array<string> = []; 45 const staticMethods: Array<Array<StaticMethodEntity>> = []; 46 const exportDeclarations: Array<string> = []; 47 48 sourceFile.forEachChild(node => { 49 if (isImportDeclaration(node)) { 50 importDeclarations.push(getImportDeclaration(node, sourceFile)); 51 } else if (isModuleDeclaration(node)) { 52 moduleDeclarations.push(getModuleDeclaration(node, sourceFile, fileName)); 53 } else if (isTypeAliasDeclaration(node)) { 54 typeAliasDeclarations.push(getTypeAliasDeclaration(node, sourceFile)); 55 } else if (isClassDeclaration(node)) { 56 let isDefaultExportClass = false; 57 if (node.modifiers !== undefined) { 58 node.modifiers.forEach(value => { 59 if (value.kind === SyntaxKind.DefaultKeyword) { 60 isDefaultExportClass = true; 61 } 62 }); 63 } 64 if (isDefaultExportClass) { 65 const classDeclarationEntity = getClassDeclaration(node, sourceFile); 66 classDeclarations.push(classDeclarationEntity); 67 if (classDeclarationEntity.staticMethods.length > 0) { 68 staticMethods.push(classDeclarationEntity.staticMethods); 69 } 70 } 71 } else if (isInterfaceDeclaration(node)) { 72 interfaceDeclarations.push(getInterfaceDeclaration(node, sourceFile)); 73 } else if (isExportAssignment(node)) { 74 exportAssignment = getExportAssignment(node, sourceFile); 75 } else if (isEnumDeclaration(node)) { 76 enumDeclarations.push(getEnumDeclaration(node, sourceFile)); 77 } else if (isExportDeclaration(node)) { 78 exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd()); 79 } else { 80 if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) { 81 console.log('--------------------------- uncaught sourceFile type start -----------------------'); 82 console.log('fileName: ' + fileName); 83 console.log(node); 84 console.log('--------------------------- uncaught sourceFile type end -----------------------'); 85 } 86 } 87 }); 88 89 return { 90 importDeclarations: importDeclarations, 91 moduleDeclarations: moduleDeclarations, 92 typeAliasDeclarations: typeAliasDeclarations, 93 classDeclarations: classDeclarations, 94 interfaceDeclarations: interfaceDeclarations, 95 enumDeclarations: enumDeclarations, 96 exportAssignment: exportAssignment, 97 staticMethods: staticMethods, 98 exportDeclarations: exportDeclarations 99 }; 100} 101 102/** 103 * get default export class 104 * @param sourceFile 105 * @returns 106 */ 107export function getDefaultExportClassDeclaration(sourceFile: SourceFile): Array<ClassEntity> { 108 const defaultExportClass: Array<ClassEntity> = []; 109 sourceFile.forEachChild(node => { 110 if (isClassDeclaration(node)) { 111 defaultExportClass.push(getClassDeclaration(node, sourceFile)); 112 } 113 }); 114 return defaultExportClass; 115} 116 117/** 118 * get sourceFile const variable statement 119 * @param sourceFile 120 * @returns 121 */ 122export function getSourceFileVariableStatements(sourceFile: SourceFile): Array<Array<StatementEntity>> { 123 const variableStatements: Array<Array<StatementEntity>> = []; 124 sourceFile.forEachChild(node => { 125 if (isVariableStatement(node)) { 126 variableStatements.push(getVariableStatementDeclaration(node, sourceFile)); 127 } 128 }); 129 return variableStatements; 130} 131 132/** 133 * get sourcefile functions 134 * @param sourceFile 135 * @returns 136 */ 137export function getSourceFileFunctions(sourceFile: SourceFile): Map<string, Array<FunctionEntity>> { 138 const functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>(); 139 sourceFile.forEachChild(node => { 140 if (isFunctionDeclaration(node)) { 141 const functionEntity = getFunctionDeclaration(node, sourceFile); 142 if (functionDeclarations.get(functionEntity.functionName) !== undefined) { 143 functionDeclarations.get(functionEntity.functionName)?.push(functionEntity); 144 } else { 145 const functionArray: Array<FunctionEntity> = []; 146 functionArray.push(functionEntity); 147 functionDeclarations.set(functionEntity.functionName, functionArray); 148 } 149 } 150 }); 151 return functionDeclarations; 152} 153 154export interface SourceFileEntity { 155 importDeclarations: Array<ImportElementEntity>, 156 moduleDeclarations: Array<ModuleBlockEntity>, 157 typeAliasDeclarations: Array<TypeAliasEntity>, 158 classDeclarations: Array<ClassEntity>, 159 interfaceDeclarations: Array<InterfaceEntity>, 160 enumDeclarations: Array<EnumEntity>, 161 exportAssignment: Array<string>, 162 staticMethods: Array<Array<StaticMethodEntity>>, 163 exportDeclarations: Array<string> 164} 165