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