• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, isExportAssignment, isExportDeclaration, isFunctionDeclaration,
18  isImportDeclaration, isInterfaceDeclaration, isModuleDeclaration, isTypeAliasDeclaration, isVariableStatement,
19  SourceFile, SyntaxKind
20} from 'typescript';
21import { ClassEntity, getClassDeclaration } from './classDeclaration';
22import { EnumEntity, getEnumDeclaration } from './enumDeclaration';
23import { FunctionEntity, getFunctionDeclaration } from './functionDeclaration';
24import { getExportAssignment, getImportDeclaration, ImportElementEntity } from './importAndExportDeclaration';
25import { getInterfaceDeclaration, InterfaceEntity } from './interfaceDeclaration';
26import { StaticMethodEntity } from './methodDeclaration';
27import { getModuleDeclaration, ModuleBlockEntity } from './moduleDeclaration';
28import { getTypeAliasDeclaration, TypeAliasEntity } from './typeAliasDeclaration';
29import { getVariableStatementDeclaration, StatementEntity } from './variableStatementResolve';
30
31/**
32 * assembly all sourceFile node info
33 * @param sourceFile
34 * @param fileName
35 * @returns
36 */
37export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): SourceFileEntity {
38  const importDeclarations: Array<ImportElementEntity> = [];
39  const moduleDeclarations: Array<ModuleBlockEntity> = [];
40  const typeAliasDeclarations: Array<TypeAliasEntity> = [];
41  const classDeclarations: Array<ClassEntity> = [];
42  const interfaceDeclarations: Array<InterfaceEntity> = [];
43  const enumDeclarations: Array<EnumEntity> = [];
44  let exportAssignment: Array<string> = [];
45  const staticMethods: Array<Array<StaticMethodEntity>> = [];
46  const exportDeclarations: Array<string> = [];
47
48  sourceFile.forEachChild(node => {
49    if (isImportDeclaration(node)) {
50      importDeclarations.push(getImportDeclaration(node, sourceFile));
51    } else if (isModuleDeclaration(node)) {
52      moduleDeclarations.push(getModuleDeclaration(node, sourceFile, fileName));
53    } else if (isTypeAliasDeclaration(node)) {
54      typeAliasDeclarations.push(getTypeAliasDeclaration(node, sourceFile));
55    } else if (isClassDeclaration(node)) {
56      let isDefaultExportClass = false;
57      if (node.modifiers !== undefined) {
58        node.modifiers.forEach(value => {
59          if (value.kind === SyntaxKind.DefaultKeyword) {
60            isDefaultExportClass = true;
61          }
62        });
63      }
64      if (isDefaultExportClass) {
65        const classDeclarationEntity = getClassDeclaration(node, sourceFile);
66        classDeclarations.push(classDeclarationEntity);
67        if (classDeclarationEntity.staticMethods.length > 0) {
68          staticMethods.push(classDeclarationEntity.staticMethods);
69        }
70      }
71    } else if (isInterfaceDeclaration(node)) {
72      interfaceDeclarations.push(getInterfaceDeclaration(node, sourceFile));
73    } else if (isExportAssignment(node)) {
74      exportAssignment = getExportAssignment(node, sourceFile);
75    } else if (isEnumDeclaration(node)) {
76      enumDeclarations.push(getEnumDeclaration(node, sourceFile));
77    } else if (isExportDeclaration(node)) {
78      exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd());
79    } else {
80      if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) {
81        console.log('--------------------------- uncaught sourceFile type start -----------------------');
82        console.log('fileName: ' + fileName);
83        console.log(node);
84        console.log('--------------------------- uncaught sourceFile type end -----------------------');
85      }
86    }
87  });
88
89  return {
90    importDeclarations: importDeclarations,
91    moduleDeclarations: moduleDeclarations,
92    typeAliasDeclarations: typeAliasDeclarations,
93    classDeclarations: classDeclarations,
94    interfaceDeclarations: interfaceDeclarations,
95    enumDeclarations: enumDeclarations,
96    exportAssignment: exportAssignment,
97    staticMethods: staticMethods,
98    exportDeclarations: exportDeclarations
99  };
100}
101
102/**
103 * get default export class
104 * @param sourceFile
105 * @returns
106 */
107export function getDefaultExportClassDeclaration(sourceFile: SourceFile): Array<ClassEntity> {
108  const defaultExportClass: Array<ClassEntity> = [];
109  sourceFile.forEachChild(node => {
110    if (isClassDeclaration(node)) {
111      defaultExportClass.push(getClassDeclaration(node, sourceFile));
112    }
113  });
114  return defaultExportClass;
115}
116
117/**
118 * get sourceFile const variable statement
119 * @param sourceFile
120 * @returns
121 */
122export function getSourceFileVariableStatements(sourceFile: SourceFile): Array<Array<StatementEntity>> {
123  const variableStatements: Array<Array<StatementEntity>> = [];
124  sourceFile.forEachChild(node => {
125    if (isVariableStatement(node)) {
126      variableStatements.push(getVariableStatementDeclaration(node, sourceFile));
127    }
128  });
129  return variableStatements;
130}
131
132/**
133 * get sourcefile functions
134 * @param sourceFile
135 * @returns
136 */
137export function getSourceFileFunctions(sourceFile: SourceFile): Map<string, Array<FunctionEntity>> {
138  const functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>();
139  sourceFile.forEachChild(node => {
140    if (isFunctionDeclaration(node)) {
141      const functionEntity = getFunctionDeclaration(node, sourceFile);
142      if (functionDeclarations.get(functionEntity.functionName) !== undefined) {
143        functionDeclarations.get(functionEntity.functionName)?.push(functionEntity);
144      } else {
145        const functionArray: Array<FunctionEntity> = [];
146        functionArray.push(functionEntity);
147        functionDeclarations.set(functionEntity.functionName, functionArray);
148      }
149    }
150  });
151  return functionDeclarations;
152}
153
154export interface SourceFileEntity {
155  importDeclarations: Array<ImportElementEntity>,
156  moduleDeclarations: Array<ModuleBlockEntity>,
157  typeAliasDeclarations: Array<TypeAliasEntity>,
158  classDeclarations: Array<ClassEntity>,
159  interfaceDeclarations: Array<InterfaceEntity>,
160  enumDeclarations: Array<EnumEntity>,
161  exportAssignment: Array<string>,
162  staticMethods: Array<Array<StaticMethodEntity>>,
163  exportDeclarations: Array<string>
164}
165