• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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