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