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, isExportDeclaration, isFunctionDeclaration, isIdentifier, 18 isImportEqualsDeclaration, isInterfaceDeclaration, isModuleBlock, isModuleDeclaration, isTypeAliasDeclaration, 19 isVariableStatement, ModuleDeclaration, Node, SourceFile 20} from 'typescript'; 21import { getExportKeyword } from '../common/commonUtils'; 22import { ClassEntity, getClassDeclaration } from './classDeclaration'; 23import { EnumEntity, getEnumDeclaration } from './enumDeclaration'; 24import { FunctionEntity, getFunctionDeclaration } from './functionDeclaration'; 25import { getExportDeclaration, getModuleImportEqual, ImportEuqalEntity } from './importAndExportDeclaration'; 26import { getInterfaceDeclaration, InterfaceEntity } from './interfaceDeclaration'; 27import { getTypeAliasDeclaration, TypeAliasEntity } from './typeAliasDeclaration'; 28import { getVariableStatementDeclaration, StatementEntity } from './variableStatementResolve'; 29 30/** 31 * get module info 32 * @param node 33 * @param sourceFile 34 * @param fileName 35 * @returns 36 */ 37export function getModuleDeclaration(node: Node, sourceFile: SourceFile, fileName: string): ModuleBlockEntity { 38 const moduleNode = node as ModuleDeclaration; 39 let moduleName = ''; 40 if (isIdentifier(moduleNode.name)) { 41 moduleName = moduleNode.name.escapedText.toString(); 42 } else { 43 moduleName = sourceFile.text.substring(moduleNode.name.pos, moduleNode.name.end).trimStart().trimEnd(); 44 } 45 46 let exportModifiers: Array<number> = []; 47 const modifiers = moduleNode.modifiers; 48 if (modifiers !== undefined) { 49 exportModifiers = getExportKeyword(modifiers); 50 } 51 52 const typeAliasDeclarations: Array<TypeAliasEntity> = []; 53 const classDeclarations: Array<ClassEntity> = []; 54 const interfaceDeclarations: Array<InterfaceEntity> = []; 55 const functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>(); 56 const enumDeclarations: Array<EnumEntity> = []; 57 const moduleDeclarations: Array<ModuleBlockEntity> = []; 58 const variableStatements: Array<Array<StatementEntity>> = []; 59 const moduleImportEquaqls: Array<ImportEuqalEntity> = []; 60 const exportDeclarations: Array<string> = []; 61 const moduleBody = moduleNode.body; 62 63 if (moduleBody !== undefined && isModuleBlock(moduleBody)) { 64 moduleBody.statements.forEach(value => { 65 if (isFunctionDeclaration(value)) { 66 const FunctionEntity = getFunctionDeclaration(value, sourceFile); 67 if (functionDeclarations.get(FunctionEntity.functionName) !== undefined) { 68 functionDeclarations.get(FunctionEntity.functionName)?.push(FunctionEntity); 69 } else { 70 const functionArray: Array<FunctionEntity> = []; 71 functionArray.push(FunctionEntity); 72 functionDeclarations.set(FunctionEntity.functionName, functionArray); 73 } 74 } else if (isTypeAliasDeclaration(value)) { 75 typeAliasDeclarations.push(getTypeAliasDeclaration(value, sourceFile)); 76 } else if (isEnumDeclaration(value)) { 77 enumDeclarations.push(getEnumDeclaration(value, sourceFile)); 78 } else if (isClassDeclaration(value)) { 79 classDeclarations.push(getClassDeclaration(value, sourceFile)); 80 } else if (isInterfaceDeclaration(value)) { 81 interfaceDeclarations.push(getInterfaceDeclaration(value, sourceFile)); 82 } else if (isModuleDeclaration(value)) { 83 moduleDeclarations.push(getModuleDeclaration(value, sourceFile, fileName)); 84 } else if (isVariableStatement(value)) { 85 variableStatements.push(getVariableStatementDeclaration(value, sourceFile)); 86 } else if (isImportEqualsDeclaration(value)) { 87 moduleImportEquaqls.push(getModuleImportEqual(value, sourceFile)); 88 } else if (isExportDeclaration(value)) { 89 exportDeclarations.push(getExportDeclaration(value, sourceFile)); 90 } else { 91 console.log('--------------------------- uncaught module type start -----------------------'); 92 console.log('fileName: ' + fileName); 93 console.log(value); 94 console.log('--------------------------- uncaught module type end -----------------------'); 95 } 96 }); 97 } 98 99 return { 100 moduleName: moduleName, 101 exportModifiers: exportModifiers, 102 typeAliasDeclarations: typeAliasDeclarations, 103 classDeclarations: classDeclarations, 104 interfaceDeclarations: interfaceDeclarations, 105 functionDeclarations: functionDeclarations, 106 enumDeclarations: enumDeclarations, 107 moduleDeclarations: moduleDeclarations, 108 variableStatements: variableStatements, 109 moduleImportEquaqls: moduleImportEquaqls, 110 exportDeclarations: exportDeclarations 111 }; 112} 113 114export interface ModuleBlockEntity { 115 moduleName: string, 116 exportModifiers: Array<number>, 117 typeAliasDeclarations: Array<TypeAliasEntity>, 118 classDeclarations: Array<ClassEntity>, 119 interfaceDeclarations: Array<InterfaceEntity>, 120 functionDeclarations: Map<string, Array<FunctionEntity>>, 121 enumDeclarations: Array<EnumEntity>, 122 moduleDeclarations: Array<ModuleBlockEntity>, 123 variableStatements: Array<Array<StatementEntity>>, 124 moduleImportEquaqls: Array<ImportEuqalEntity>, 125 exportDeclarations: Array<string> 126} 127