17c804472Sopenharmony_ci/*
27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47c804472Sopenharmony_ci * you may not use this file except in compliance with the License.
57c804472Sopenharmony_ci * You may obtain a copy of the License at
67c804472Sopenharmony_ci *
77c804472Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
87c804472Sopenharmony_ci *
97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127c804472Sopenharmony_ci * See the License for the specific language governing permissions and
137c804472Sopenharmony_ci * limitations under the License.
147c804472Sopenharmony_ci */
157c804472Sopenharmony_ci
167c804472Sopenharmony_ciimport {
177c804472Sopenharmony_ci  isClassDeclaration,
187c804472Sopenharmony_ci  isEnumDeclaration,
197c804472Sopenharmony_ci  isExportAssignment,
207c804472Sopenharmony_ci  isExportDeclaration,
217c804472Sopenharmony_ci  isFunctionDeclaration,
227c804472Sopenharmony_ci  isImportDeclaration,
237c804472Sopenharmony_ci  isInterfaceDeclaration,
247c804472Sopenharmony_ci  isModuleDeclaration,
257c804472Sopenharmony_ci  isTypeAliasDeclaration,
267c804472Sopenharmony_ci  isVariableStatement,
277c804472Sopenharmony_ci  SyntaxKind
287c804472Sopenharmony_ci} from 'typescript';
297c804472Sopenharmony_ciimport type { Node, SourceFile, ClassDeclaration, FunctionDeclaration } from 'typescript';
307c804472Sopenharmony_ciimport { getClassDeclaration } from './classDeclaration';
317c804472Sopenharmony_ciimport type { ClassEntity } from './classDeclaration';
327c804472Sopenharmony_ciimport { getEnumDeclaration } from './enumDeclaration';
337c804472Sopenharmony_ciimport type { EnumEntity } from './enumDeclaration';
347c804472Sopenharmony_ciimport { getFunctionDeclaration } from './functionDeclaration';
357c804472Sopenharmony_ciimport type { FunctionEntity } from './functionDeclaration';
367c804472Sopenharmony_ciimport { getExportAssignment, getImportDeclaration } from './importAndExportDeclaration';
377c804472Sopenharmony_ciimport type { ImportElementEntity } from './importAndExportDeclaration';
387c804472Sopenharmony_ciimport { getInterfaceDeclaration } from './interfaceDeclaration';
397c804472Sopenharmony_ciimport type { InterfaceEntity } from './interfaceDeclaration';
407c804472Sopenharmony_ciimport type { StaticMethodEntity } from './methodDeclaration';
417c804472Sopenharmony_ciimport { getModuleDeclaration } from './moduleDeclaration';
427c804472Sopenharmony_ciimport type { ModuleBlockEntity } from './moduleDeclaration';
437c804472Sopenharmony_ciimport { getTypeAliasDeclaration } from './typeAliasDeclaration';
447c804472Sopenharmony_ciimport type { TypeAliasEntity } from './typeAliasDeclaration';
457c804472Sopenharmony_ciimport { getVariableStatementDeclaration } from './variableStatementResolve';
467c804472Sopenharmony_ciimport type { StatementEntity } from './variableStatementResolve';
477c804472Sopenharmony_ci
487c804472Sopenharmony_ciinterface SubstepClassParams {
497c804472Sopenharmony_ci  node: ClassDeclaration;
507c804472Sopenharmony_ci  sourceFile: SourceFile;
517c804472Sopenharmony_ci  classDeclarations: Array<ClassEntity>;
527c804472Sopenharmony_ci  staticMethods: Array<Array<StaticMethodEntity>>;
537c804472Sopenharmony_ci}
547c804472Sopenharmony_ci
557c804472Sopenharmony_ciinterface SubstepFuntionParams {
567c804472Sopenharmony_ci  node: FunctionDeclaration;
577c804472Sopenharmony_ci  sourceFile: SourceFile;
587c804472Sopenharmony_ci  functionDeclarations: Map<string, Array<FunctionEntity>>;
597c804472Sopenharmony_ci}
607c804472Sopenharmony_ci
617c804472Sopenharmony_ciexport interface SourceFileEntity {
627c804472Sopenharmony_ci  importDeclarations: Array<ImportElementEntity>;
637c804472Sopenharmony_ci  moduleDeclarations: Array<ModuleBlockEntity>;
647c804472Sopenharmony_ci  typeAliasDeclarations: Array<TypeAliasEntity>;
657c804472Sopenharmony_ci  classDeclarations: Array<ClassEntity>;
667c804472Sopenharmony_ci  interfaceDeclarations: Array<InterfaceEntity>;
677c804472Sopenharmony_ci  enumDeclarations: Array<EnumEntity>;
687c804472Sopenharmony_ci  exportAssignment: Array<string>;
697c804472Sopenharmony_ci  staticMethods: Array<Array<StaticMethodEntity>>;
707c804472Sopenharmony_ci  exportDeclarations: Array<string>;
717c804472Sopenharmony_ci  functionDeclarations: Map<string, Array<FunctionEntity>>;
727c804472Sopenharmony_ci}
737c804472Sopenharmony_ci
747c804472Sopenharmony_ci/**
757c804472Sopenharmony_ci * assembly all sourceFile node info
767c804472Sopenharmony_ci * @param sourceFile
777c804472Sopenharmony_ci * @param fileName
787c804472Sopenharmony_ci * @returns
797c804472Sopenharmony_ci */
807c804472Sopenharmony_ciexport function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): SourceFileEntity {
817c804472Sopenharmony_ci  const importDeclarations: Array<ImportElementEntity> = [];
827c804472Sopenharmony_ci  const moduleDeclarations: Array<ModuleBlockEntity> = [];
837c804472Sopenharmony_ci  const typeAliasDeclarations: Array<TypeAliasEntity> = [];
847c804472Sopenharmony_ci  let classDeclarations: Array<ClassEntity> = [];
857c804472Sopenharmony_ci  const interfaceDeclarations: Array<InterfaceEntity> = [];
867c804472Sopenharmony_ci  const enumDeclarations: Array<EnumEntity> = [];
877c804472Sopenharmony_ci  let exportAssignment: Array<string> = [];
887c804472Sopenharmony_ci  let staticMethods: Array<Array<StaticMethodEntity>> = [];
897c804472Sopenharmony_ci  const exportDeclarations: Array<string> = [];
907c804472Sopenharmony_ci  let functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>();
917c804472Sopenharmony_ci  sourceFile.forEachChild(node => {
927c804472Sopenharmony_ci    if (isImportDeclaration(node)) {
937c804472Sopenharmony_ci      importDeclarations.push(getImportDeclaration(node, sourceFile));
947c804472Sopenharmony_ci    } else if (isModuleDeclaration(node)) {
957c804472Sopenharmony_ci      moduleDeclarations.push(getModuleDeclaration(node, sourceFile, fileName));
967c804472Sopenharmony_ci    } else if (isTypeAliasDeclaration(node)) {
977c804472Sopenharmony_ci      typeAliasDeclarations.push(getTypeAliasDeclaration(node, sourceFile));
987c804472Sopenharmony_ci    } else if (isClassDeclaration(node)) {
997c804472Sopenharmony_ci      const substepClassBack = substepClass({ node, sourceFile, classDeclarations, staticMethods });
1007c804472Sopenharmony_ci      classDeclarations = substepClassBack.classDeclarations;
1017c804472Sopenharmony_ci      staticMethods = substepClassBack.staticMethods;
1027c804472Sopenharmony_ci    } else if (isInterfaceDeclaration(node)) {
1037c804472Sopenharmony_ci      interfaceDeclarations.push(getInterfaceDeclaration(node, sourceFile));
1047c804472Sopenharmony_ci    } else if (isExportAssignment(node)) {
1057c804472Sopenharmony_ci      exportAssignment = getExportAssignment(node, sourceFile);
1067c804472Sopenharmony_ci    } else if (isEnumDeclaration(node)) {
1077c804472Sopenharmony_ci      enumDeclarations.push(getEnumDeclaration(node, sourceFile));
1087c804472Sopenharmony_ci    } else if (isExportDeclaration(node)) {
1097c804472Sopenharmony_ci      exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trim());
1107c804472Sopenharmony_ci    } else if (isFunctionDeclaration(node)) {
1117c804472Sopenharmony_ci      const classParams = substepFunction({ node, sourceFile, functionDeclarations });
1127c804472Sopenharmony_ci      functionDeclarations = classParams.functionDeclarations;
1137c804472Sopenharmony_ci    } else {
1147c804472Sopenharmony_ci      substepConsole(node, fileName);
1157c804472Sopenharmony_ci    }
1167c804472Sopenharmony_ci  });
1177c804472Sopenharmony_ci  return {
1187c804472Sopenharmony_ci    importDeclarations,
1197c804472Sopenharmony_ci    moduleDeclarations,
1207c804472Sopenharmony_ci    typeAliasDeclarations,
1217c804472Sopenharmony_ci    classDeclarations,
1227c804472Sopenharmony_ci    interfaceDeclarations,
1237c804472Sopenharmony_ci    enumDeclarations,
1247c804472Sopenharmony_ci    exportAssignment,
1257c804472Sopenharmony_ci    staticMethods,
1267c804472Sopenharmony_ci    exportDeclarations,
1277c804472Sopenharmony_ci    functionDeclarations
1287c804472Sopenharmony_ci  };
1297c804472Sopenharmony_ci}
1307c804472Sopenharmony_ci
1317c804472Sopenharmony_ci/**
1327c804472Sopenharmony_ci * get default export class
1337c804472Sopenharmony_ci * @param sourceFile
1347c804472Sopenharmony_ci * @returns
1357c804472Sopenharmony_ci */
1367c804472Sopenharmony_ciexport function getDefaultExportClassDeclaration(sourceFile: SourceFile): Array<ClassEntity> {
1377c804472Sopenharmony_ci  const defaultExportClass: Array<ClassEntity> = [];
1387c804472Sopenharmony_ci  sourceFile.forEachChild(node => {
1397c804472Sopenharmony_ci    if (isClassDeclaration(node)) {
1407c804472Sopenharmony_ci      defaultExportClass.push(getClassDeclaration(node, sourceFile));
1417c804472Sopenharmony_ci    }
1427c804472Sopenharmony_ci  });
1437c804472Sopenharmony_ci  return defaultExportClass;
1447c804472Sopenharmony_ci}
1457c804472Sopenharmony_ci
1467c804472Sopenharmony_ci/**
1477c804472Sopenharmony_ci * get sourceFile const variable statement
1487c804472Sopenharmony_ci * @param sourceFile
1497c804472Sopenharmony_ci * @returns
1507c804472Sopenharmony_ci */
1517c804472Sopenharmony_ciexport function getSourceFileVariableStatements(sourceFile: SourceFile): Array<Array<StatementEntity>> {
1527c804472Sopenharmony_ci  const variableStatements: Array<Array<StatementEntity>> = [];
1537c804472Sopenharmony_ci  sourceFile.forEachChild(node => {
1547c804472Sopenharmony_ci    if (isVariableStatement(node)) {
1557c804472Sopenharmony_ci      variableStatements.push(getVariableStatementDeclaration(node, sourceFile));
1567c804472Sopenharmony_ci    }
1577c804472Sopenharmony_ci  });
1587c804472Sopenharmony_ci  return variableStatements;
1597c804472Sopenharmony_ci}
1607c804472Sopenharmony_ci
1617c804472Sopenharmony_ci/**
1627c804472Sopenharmony_ci * get sourcefile functions
1637c804472Sopenharmony_ci * @param sourceFile
1647c804472Sopenharmony_ci * @returns
1657c804472Sopenharmony_ci */
1667c804472Sopenharmony_ciexport function getSourceFileFunctions(sourceFile: SourceFile): Map<string, Array<FunctionEntity>> {
1677c804472Sopenharmony_ci  const functionDeclarations: Map<string, Array<FunctionEntity>> = new Map<string, Array<FunctionEntity>>();
1687c804472Sopenharmony_ci  sourceFile.forEachChild(node => {
1697c804472Sopenharmony_ci    if (isFunctionDeclaration(node)) {
1707c804472Sopenharmony_ci      const functionEntity = getFunctionDeclaration(node, sourceFile);
1717c804472Sopenharmony_ci      if (functionDeclarations.get(functionEntity.functionName) !== undefined) {
1727c804472Sopenharmony_ci        functionDeclarations.get(functionEntity.functionName)?.push(functionEntity);
1737c804472Sopenharmony_ci      } else {
1747c804472Sopenharmony_ci        const functionArray: Array<FunctionEntity> = [];
1757c804472Sopenharmony_ci        functionArray.push(functionEntity);
1767c804472Sopenharmony_ci        functionDeclarations.set(functionEntity.functionName, functionArray);
1777c804472Sopenharmony_ci      }
1787c804472Sopenharmony_ci    }
1797c804472Sopenharmony_ci  });
1807c804472Sopenharmony_ci  return functionDeclarations;
1817c804472Sopenharmony_ci}
1827c804472Sopenharmony_ci
1837c804472Sopenharmony_ci/**
1847c804472Sopenharmony_ci * assembly some sourceFile node info
1857c804472Sopenharmony_ci * @param substepClassParams
1867c804472Sopenharmony_ci * @returns
1877c804472Sopenharmony_ci */
1887c804472Sopenharmony_cifunction substepClass(substepClassParams: SubstepClassParams): SubstepClassParams {
1897c804472Sopenharmony_ci  let isDefaultExportClass = false;
1907c804472Sopenharmony_ci  if (substepClassParams.node.modifiers !== undefined) {
1917c804472Sopenharmony_ci    substepClassParams.node.modifiers.forEach(value => {
1927c804472Sopenharmony_ci      if (value.kind === SyntaxKind.DefaultKeyword) {
1937c804472Sopenharmony_ci        isDefaultExportClass = true;
1947c804472Sopenharmony_ci      }
1957c804472Sopenharmony_ci    });
1967c804472Sopenharmony_ci  }
1977c804472Sopenharmony_ci  if (isDefaultExportClass) {
1987c804472Sopenharmony_ci    const classDeclarationEntity = getClassDeclaration(substepClassParams.node, substepClassParams.sourceFile);
1997c804472Sopenharmony_ci    substepClassParams.classDeclarations.push(classDeclarationEntity);
2007c804472Sopenharmony_ci    if (classDeclarationEntity.staticMethods.length > 0) {
2017c804472Sopenharmony_ci      substepClassParams.staticMethods.push(classDeclarationEntity.staticMethods);
2027c804472Sopenharmony_ci    }
2037c804472Sopenharmony_ci  }
2047c804472Sopenharmony_ci  return substepClassParams;
2057c804472Sopenharmony_ci}
2067c804472Sopenharmony_ci
2077c804472Sopenharmony_ci/**
2087c804472Sopenharmony_ci * assembly some sourceFile node info
2097c804472Sopenharmony_ci * @param substepClassParams
2107c804472Sopenharmony_ci * @returns
2117c804472Sopenharmony_ci */
2127c804472Sopenharmony_cifunction substepFunction(substepClassParams: SubstepFuntionParams): SubstepFuntionParams {
2137c804472Sopenharmony_ci  const functionEntity = getFunctionDeclaration(substepClassParams.node, substepClassParams.sourceFile);
2147c804472Sopenharmony_ci  if (substepClassParams.functionDeclarations.get(functionEntity.functionName) !== undefined) {
2157c804472Sopenharmony_ci    substepClassParams.functionDeclarations.get(functionEntity.functionName)?.push(functionEntity);
2167c804472Sopenharmony_ci  } else {
2177c804472Sopenharmony_ci    const functionArray: Array<FunctionEntity> = [];
2187c804472Sopenharmony_ci    functionArray.push(functionEntity);
2197c804472Sopenharmony_ci    substepClassParams.functionDeclarations.set(functionEntity.functionName, functionArray);
2207c804472Sopenharmony_ci  }
2217c804472Sopenharmony_ci  return substepClassParams;
2227c804472Sopenharmony_ci}
2237c804472Sopenharmony_ci
2247c804472Sopenharmony_ci/**
2257c804472Sopenharmony_ci * assembly some sourceFile node info
2267c804472Sopenharmony_ci * @param substepClassParams
2277c804472Sopenharmony_ci * @returns
2287c804472Sopenharmony_ci */
2297c804472Sopenharmony_cifunction substepConsole(node: Node, fileName: string): void {
2307c804472Sopenharmony_ci  if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) {
2317c804472Sopenharmony_ci    console.log('--------------------------- uncaught sourceFile type start -----------------------');
2327c804472Sopenharmony_ci    console.log('fileName: ' + fileName);
2337c804472Sopenharmony_ci    console.log(node);
2347c804472Sopenharmony_ci    console.log('--------------------------- uncaught sourceFile type end -----------------------');
2357c804472Sopenharmony_ci  }
2367c804472Sopenharmony_ci}
237