/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { isClassDeclaration, isEnumDeclaration, isExportAssignment, isExportDeclaration, isFunctionDeclaration, isImportDeclaration, isInterfaceDeclaration, isModuleDeclaration, isTypeAliasDeclaration, isVariableStatement, SyntaxKind } from 'typescript'; import type { SourceFile } from 'typescript'; import { getClassDeclaration } from './classDeclaration'; import type { ClassEntity } from './classDeclaration'; import { getEnumDeclaration } from './enumDeclaration'; import type { EnumEntity } from './enumDeclaration'; import { getFunctionDeclaration } from './functionDeclaration'; import type { FunctionEntity } from './functionDeclaration'; import { getExportAssignment, getImportDeclaration } from './importAndExportDeclaration'; import type { ImportElementEntity } from './importAndExportDeclaration'; import { getInterfaceDeclaration } from './interfaceDeclaration'; import type { InterfaceEntity } from './interfaceDeclaration'; import type { StaticMethodEntity } from './methodDeclaration'; import { getModuleDeclaration } from './moduleDeclaration'; import type { ModuleBlockEntity } from './moduleDeclaration'; import { getTypeAliasDeclaration } from './typeAliasDeclaration'; import type { TypeAliasEntity } from './typeAliasDeclaration'; import { getVariableStatementDeclaration } from './variableStatementResolve'; import type { StatementEntity } from './variableStatementResolve'; /** * assembly all sourceFile node info * @param sourceFile * @param fileName * @returns */ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): SourceFileEntity { const importDeclarations: Array = []; const moduleDeclarations: Array = []; const typeAliasDeclarations: Array = []; const classDeclarations: Array = []; const interfaceDeclarations: Array = []; const enumDeclarations: Array = []; let exportAssignment: Array = []; const staticMethods: Array> = []; const exportDeclarations: Array = []; const functionDeclarations: Array = []; sourceFile.forEachChild(node => { if (isImportDeclaration(node)) { importDeclarations.push(getImportDeclaration(node, sourceFile)); } else if (isModuleDeclaration(node)) { moduleDeclarations.push(getModuleDeclaration(node, sourceFile, fileName)); } else if (isTypeAliasDeclaration(node)) { typeAliasDeclarations.push(getTypeAliasDeclaration(node, sourceFile)); } else if (isClassDeclaration(node)) { let isDefaultExportClass = false; if (node.modifiers !== undefined) { node.modifiers.forEach(value => { if (value.kind === SyntaxKind.DefaultKeyword) { isDefaultExportClass = true; } }); } if (isDefaultExportClass) { const classDeclarationEntity = getClassDeclaration(node, sourceFile); classDeclarations.push(classDeclarationEntity); if (classDeclarationEntity.staticMethods.length > 0) { staticMethods.push(classDeclarationEntity.staticMethods); } } } else if (isInterfaceDeclaration(node)) { interfaceDeclarations.push(getInterfaceDeclaration(node, sourceFile)); } else if (isExportAssignment(node)) { exportAssignment = getExportAssignment(node, sourceFile); } else if (isEnumDeclaration(node)) { enumDeclarations.push(getEnumDeclaration(node, sourceFile)); } else if (isExportDeclaration(node)) { exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd()); } else if (isFunctionDeclaration(node)){ functionDeclarations.push(getFunctionDeclaration(node, sourceFile)); } else { if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) { console.log('--------------------------- uncaught sourceFile type start -----------------------'); console.log('fileName: ' + fileName); console.log(node); console.log('--------------------------- uncaught sourceFile type end -----------------------'); } } }); return { importDeclarations: importDeclarations, moduleDeclarations: moduleDeclarations, typeAliasDeclarations: typeAliasDeclarations, classDeclarations: classDeclarations, interfaceDeclarations: interfaceDeclarations, enumDeclarations: enumDeclarations, exportAssignment: exportAssignment, staticMethods: staticMethods, exportDeclarations: exportDeclarations, functionDeclarations: functionDeclarations, }; } /** * get default export class * @param sourceFile * @returns */ export function getDefaultExportClassDeclaration(sourceFile: SourceFile): Array { const defaultExportClass: Array = []; sourceFile.forEachChild(node => { if (isClassDeclaration(node)) { defaultExportClass.push(getClassDeclaration(node, sourceFile)); } }); return defaultExportClass; } /** * get sourceFile const variable statement * @param sourceFile * @returns */ export function getSourceFileVariableStatements(sourceFile: SourceFile): Array> { const variableStatements: Array> = []; sourceFile.forEachChild(node => { if (isVariableStatement(node)) { variableStatements.push(getVariableStatementDeclaration(node, sourceFile)); } }); return variableStatements; } /** * get sourcefile functions * @param sourceFile * @returns */ export function getSourceFileFunctions(sourceFile: SourceFile): Map> { const functionDeclarations: Map> = new Map>(); sourceFile.forEachChild(node => { if (isFunctionDeclaration(node)) { const functionEntity = getFunctionDeclaration(node, sourceFile); if (functionDeclarations.get(functionEntity.functionName) !== undefined) { functionDeclarations.get(functionEntity.functionName)?.push(functionEntity); } else { const functionArray: Array = []; functionArray.push(functionEntity); functionDeclarations.set(functionEntity.functionName, functionArray); } } }); return functionDeclarations; } export interface SourceFileEntity { importDeclarations: Array, moduleDeclarations: Array, typeAliasDeclarations: Array, classDeclarations: Array, interfaceDeclarations: Array, enumDeclarations: Array, exportAssignment: Array, staticMethods: Array>, exportDeclarations: Array, functionDeclarations: Array }