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 type {
17  ExportAssignment,
18  ExportDeclaration,
19  ImportDeclaration,
20  ImportEqualsDeclaration,
21  Node,
22  SourceFile
23} from 'typescript';
24import { isImportDeclaration } from 'typescript';
25
26/**
27 * get current sourceFile all imports
28 * @param sourceFile
29 * @returns
30 */
31export function getImportDeclarationArray(sourceFile: SourceFile): Array<ImportElementEntity> {
32  const importDeclarations: Array<ImportElementEntity> = [];
33  sourceFile.forEachChild(node => {
34    if (isImportDeclaration(node)) {
35      importDeclarations.push(getImportDeclaration(node, sourceFile));
36    }
37  });
38  return importDeclarations;
39}
40
41/**
42 * get module inner import info
43 * @param importEqualNode
44 * @param sourceFile
45 * @returns
46 */
47export function getModuleImportEqual(
48  importEqualNode: ImportEqualsDeclaration,
49  sourceFile: SourceFile
50): ImportEuqalEntity {
51  const fileText = sourceFile.getFullText();
52  const textRange = importEqualNode.moduleReference;
53  return {
54    importEqualName: importEqualNode.name.escapedText.toString(),
55    importEqualTypeName: fileText.slice(textRange.pos, textRange.end).trim(),
56    importEqualTypeKind: importEqualNode.moduleReference.kind
57  };
58}
59
60/**
61 * get export info
62 * @param exportNode
63 * @param sourceFile
64 * @returns
65 */
66export function getExportDeclaration(exportNode: ExportDeclaration, sourceFile: SourceFile): string {
67  return sourceFile.text.substring(exportNode.pos, exportNode.end).trim();
68}
69
70/**
71 * get import info
72 * @param node
73 * @param sourceFile
74 * @returns
75 */
76export function getImportDeclaration(node: Node, sourceFile: SourceFile): ImportElementEntity {
77  let importElements = '';
78  const importNode = node as ImportDeclaration;
79  const fileText = sourceFile.getFullText();
80  const moduleSpecifier = importNode.moduleSpecifier;
81  const importPath = fileText.substring(moduleSpecifier.pos, moduleSpecifier.end).trim();
82  const importClause = importNode.importClause;
83  if (importClause !== undefined) {
84    importElements = fileText.substring(importClause.pos, importClause.end).trim();
85    if (importElements.startsWith('type ')) {
86      importElements = importElements.replace('type ', '');
87    }
88  }
89
90  return {
91    importPath: importPath,
92    importElements: importElements
93  };
94}
95
96/**
97 * get export info
98 * @param exportAssigment
99 * @param sourceFile
100 * @returns
101 */
102export function getExportAssignment(exportAssigment: ExportAssignment, sourceFile: SourceFile): Array<string> {
103  const exportAssignments: Array<string> = [];
104  if (exportAssigment.expression !== undefined) {
105    exportAssignments.push(
106      sourceFile.text.substring(exportAssigment.expression.pos, exportAssigment.expression.end).trim()
107    );
108  }
109  return exportAssignments;
110}
111
112export interface ImportElementEntity {
113  importPath: string;
114  importElements: string;
115}
116
117export interface ExportElementEntity {
118  exportName: string;
119}
120
121export interface ImportEuqalEntity {
122  importEqualName: string;
123  importEqualTypeName: string;
124  importEqualTypeKind: number;
125}
126