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, ModuleBody } 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 38interface SubstepGetModuleparam { 39 typeAliasDeclarations: Array<TypeAliasEntity>, 40 classDeclarations: Array<ClassEntity>, 41 interfaceDeclarations: Array<InterfaceEntity>, 42 functionDeclarations: Map<string, Array<FunctionEntity>>, 43 enumDeclarations: Array<EnumEntity>, 44 moduleDeclarations: Array<ModuleBlockEntity>, 45 variableStatements: Array<Array<StatementEntity>>, 46 moduleImportEquaqls: Array<ImportEuqalEntity>, 47 exportDeclarations: Array<string>, 48 sourceFile: SourceFile, 49 fileName: string, 50 moduleBody: ModuleBody 51} 52 53export interface ModuleBlockEntity { 54 moduleName: string, 55 exportModifiers: Array<number>, 56 typeAliasDeclarations: Array<TypeAliasEntity>, 57 classDeclarations: Array<ClassEntity>, 58 interfaceDeclarations: Array<InterfaceEntity>, 59 functionDeclarations: Map<string, Array<FunctionEntity>>, 60 enumDeclarations: Array<EnumEntity>, 61 moduleDeclarations: Array<ModuleBlockEntity>, 62 variableStatements: Array<Array<StatementEntity>>, 63 moduleImportEquaqls: Array<ImportEuqalEntity>, 64 exportDeclarations: Array<string> 65} 66 67/** 68 * get module info 69 * @param node 70 * @param sourceFile 71 * @param fileName 72 * @returns 73 */ 74export function getModuleDeclaration(node: Node, sourceFile: SourceFile, fileName: string): ModuleBlockEntity { 75 const moduleNode = node as ModuleDeclaration; 76 const typeAliasDeclarations: Array<TypeAliasEntity> = []; 77 const classDeclarations: Array<ClassEntity> = []; 78 const interfaceDeclarations: Array<InterfaceEntity> = []; 79 const functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>(); 80 const enumDeclarations: Array<EnumEntity> = []; 81 const moduleDeclarations: Array<ModuleBlockEntity> = []; 82 const variableStatements: Array<Array<StatementEntity>> = []; 83 const moduleImportEquaqls: Array<ImportEuqalEntity> = []; 84 const exportDeclarations: Array<string> = []; 85 const moduleBody = moduleNode.body; 86 let moduleName = ''; 87 if (isIdentifier(moduleNode.name)) { 88 moduleName = moduleNode.name.escapedText.toString(); 89 } else { 90 moduleName = sourceFile.text.substring(moduleNode.name.pos, moduleNode.name.end).trim(); 91 } 92 93 let exportModifiers: Array<number> = []; 94 const modifiers = moduleNode.modifiers; 95 if (modifiers !== undefined) { 96 exportModifiers = getExportKeyword(modifiers); 97 } 98 const SubstepModuleBlockEntitys: SubstepGetModuleparam = substepModule({ 99 typeAliasDeclarations, 100 classDeclarations, 101 interfaceDeclarations, 102 functionDeclarations, 103 enumDeclarations, 104 moduleDeclarations, 105 variableStatements, 106 moduleImportEquaqls, 107 exportDeclarations, 108 moduleBody, 109 sourceFile, 110 fileName 111 }); 112 delete SubstepModuleBlockEntitys.moduleBody; 113 delete SubstepModuleBlockEntitys.sourceFile; 114 delete SubstepModuleBlockEntitys.fileName; 115 return { 116 ...SubstepModuleBlockEntitys, 117 exportModifiers, 118 moduleName 119 }; 120} 121 122/** 123 * get some module info 124 * @param SubstepGetModuleparam 125 * @returns 126 */ 127function substepModule(props: SubstepGetModuleparam): SubstepGetModuleparam { 128 if (props.moduleBody !== undefined && isModuleBlock(props.moduleBody)) { 129 props.moduleBody.statements.forEach(value => { 130 if (isFunctionDeclaration(value)) { 131 const functionEntity = getFunctionDeclaration(value, props.sourceFile); 132 if (props.functionDeclarations.get(functionEntity.functionName) !== undefined) { 133 props.functionDeclarations.get(functionEntity.functionName)?.push(functionEntity); 134 } else { 135 const functionArray: Array<FunctionEntity> = []; 136 functionArray.push(functionEntity); 137 props.functionDeclarations.set(functionEntity.functionName, functionArray); 138 } 139 } else if (isTypeAliasDeclaration(value)) { 140 props.typeAliasDeclarations.push(getTypeAliasDeclaration(value, props.sourceFile)); 141 } else if (isEnumDeclaration(value)) { 142 props.enumDeclarations.push(getEnumDeclaration(value, props.sourceFile)); 143 } else if (isClassDeclaration(value)) { 144 props.classDeclarations.push(getClassDeclaration(value, props.sourceFile)); 145 } else if (isInterfaceDeclaration(value)) { 146 props.interfaceDeclarations.push(getInterfaceDeclaration(value, props.sourceFile)); 147 } else if (isModuleDeclaration(value)) { 148 props.moduleDeclarations.push(getModuleDeclaration(value, props.sourceFile, props.fileName)); 149 } else if (isVariableStatement(value)) { 150 props.variableStatements.push(getVariableStatementDeclaration(value, props.sourceFile)); 151 } else if (isImportEqualsDeclaration(value)) { 152 props.moduleImportEquaqls.push(getModuleImportEqual(value, props.sourceFile)); 153 } else if (isExportDeclaration(value)) { 154 props.exportDeclarations.push(getExportDeclaration(value, props.sourceFile)); 155 } else { 156 console.log('--------------------------- uncaught module type start -----------------------'); 157 console.log('fileName: ' + props.fileName); 158 console.log(value); 159 console.log('--------------------------- uncaught module type end -----------------------'); 160 } 161 }); 162 } 163 return props; 164} 165