• 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 ts, { TypeParameter, TypeParameterDeclaration } from 'typescript';
17import _ from 'lodash';
18import path from 'path';
19
20import {
21  ApiInfo,
22  ApiType,
23  BasicApiInfo,
24  ClassInfo,
25  ConstantInfo,
26  ContainerApiInfo,
27  EnumInfo,
28  EnumValueInfo,
29  ExportDeclareInfo,
30  ExportDefaultInfo,
31  ImportInfo,
32  InterfaceInfo,
33  MethodInfo,
34  MethodType,
35  ModifierProcessorInterface,
36  ModuleInfo,
37  NamespaceInfo,
38  NodeProcessorInterface,
39  ParamInfo,
40  PropertyInfo,
41  PropertyNode,
42  ReferenceInfo,
43  StructInfo,
44  TypeAliasType,
45  TypeAliasInfo,
46  containerApiTypes,
47  GenericInfo,
48  ParentClass,
49  ParserParam,
50  FileTag,
51  TypeParamInfo,
52  TypeLocationInfo,
53} from '../../typedef/parser/ApiInfoDefination';
54import { Comment } from '../../typedef/parser/Comment';
55import { StringUtils } from '../../utils/StringUtils';
56import { StringConstant, EventConstant } from '../../utils/Constant';
57import { BasicApiInfoMap, ApiInfosMap, FileInfoMap } from './parser';
58import { JsDocProcessorHelper } from './JsDocProcessor';
59
60export const parserParam: ParserParam = new ParserParam();
61
62export class NodeProcessorHelper {
63  // 如果是字符串的话,会出现单双引号重复的情况
64  static regQuotation: RegExp = /^[\'|\"](.*)[\'|\"]$/;
65
66  /**
67   * 解析文件typereference对应symbol集合
68   *
69   * @type {Map<string, Map<string, ts.Symbol>>}
70   */
71  static symbolOfTypeReferenceMap: Map<string, Map<string, ts.Symbol>> = new Map<string, Map<string, ts.Symbol>>();
72
73  static processReference(
74    sourceFile: ts.SourceFile,
75    parentMap: Map<string, object>,
76    parentApiInfo: BasicApiInfo
77  ): void {
78    const references: ReferenceInfo[] = [];
79    sourceFile.referencedFiles.forEach((referencedFile: ts.FileReference) => {
80      const referenceInfo: ReferenceInfo = new ReferenceInfo(ApiType.REFERENCE_FILE, sourceFile, parentApiInfo);
81      referenceInfo.setApiName(ApiType.REFERENCE_FILE);
82      referenceInfo.setPathName(referencedFile.fileName);
83      references.push(referenceInfo);
84    });
85    if (references.length === 0) {
86      return;
87    }
88    const currentMap: Map<string, object> = new Map();
89    currentMap.set(StringConstant.SELF, references);
90    parentMap.set(StringConstant.REFERENCE, currentMap);
91  }
92  /**
93   * 根据节点类型处理节点的方法,处理的主流程
94   *
95   * @param { ts.Node } node 当前处理的节点
96   * @param { FileInfoMap } parentMap 父节点建立的map对象
97   * @param { BasicApiInfo } parentApiInfo 父节点解析后的对象
98   */
99  static processNode(node: ts.Node, parentMap: FileInfoMap | ApiInfosMap, parentApiInfo: BasicApiInfo): void {
100    const nodeProcessor: NodeProcessorInterface | undefined = nodeProcessorMap.get(node.kind);
101    if (!nodeProcessor) {
102      return;
103    }
104    const apiInfo: BasicApiInfo = nodeProcessor(node, parentApiInfo);
105    const currentMap: BasicApiInfoMap = NodeProcessorHelper.setApiInfo(apiInfo, parentMap, node);
106    const childNodes: ts.NodeArray<ts.Node> | undefined = NodeProcessorHelper.getChildNodes(node);
107    if (!childNodes) {
108      return;
109    }
110    childNodes.forEach((cNode: ts.Node) => {
111      if (apiInfo.getApiType() === ApiType.STRUCT && cNode.getFullText() === '') { // 去除struct的默认构造方法
112        return;
113      }
114      NodeProcessorHelper.processNode(cNode, currentMap as ApiInfosMap, apiInfo);
115    });
116  }
117
118  /**
119   * 将解析后的api添加到当前的map中,会对某些特殊情况进行调整
120   *
121   * @param { BasicApiInfo } apiInfo 当前api的解析对象
122   * @param { Map<string, object> } parentMap 当前父节点所在的map
123   * @param { ts.Node } node 当前apinode节点
124   * @returns { Map<string, object> } 返回当前节点所属的map
125   */
126  static setApiInfo(apiInfo: BasicApiInfo, parentMap: FileInfoMap | ApiInfosMap, node: ts.Node): BasicApiInfoMap {
127    if (apiInfo.getApiType() !== ApiType.METHOD) {
128      return NodeProcessorHelper.setSingleApiInfo(apiInfo, parentMap);
129    }
130    let apiInfos: BasicApiInfo[] = [];
131    apiInfos = NodeProcessorHelper.processEventMethod(apiInfo, node);
132    // 处理promise/asynccallback
133    NodeProcessorHelper.processAsyncMethod(apiInfos);
134    let currentMap: BasicApiInfoMap = new Map();
135    apiInfos.forEach((apiInfo: BasicApiInfo) => {
136      currentMap = NodeProcessorHelper.setSingleApiInfo(apiInfo, parentMap);
137    });
138    return currentMap;
139  }
140
141  /**
142   *  将解析后的单个api添加到当前的map中,不允许对apiInfo进行二次修改
143   *
144   * @param { BasicApiInfo } apiInfo 当前api的解析对象
145   * @param { ApiInfosMap } parentMap  当前父节点所在的map
146   * @return { BasicApiInfoMap } 返回当前节点所属的map
147   */
148  static setSingleApiInfo(apiInfo: BasicApiInfo, parentMap: FileInfoMap | ApiInfosMap): BasicApiInfoMap {
149    const apiName: string = apiInfo.getApiName();
150    const parentApiInfo: BasicApiInfo | undefined = apiInfo.getParentApi();
151    if (parentApiInfo && containerApiTypes.has(parentApiInfo.apiType)) {
152      const containerApiInfo: ContainerApiInfo = parentApiInfo as ContainerApiInfo;
153      containerApiInfo.addChildApi(apiInfo);
154    }
155    if (parentMap.has(apiName)) {
156      //同名方法处理
157      const currentMap: BasicApiInfoMap = parentMap.get(apiName) as BasicApiInfoMap;
158      const methodInfos: BasicApiInfo[] = currentMap.get(StringConstant.SELF) as BasicApiInfo[];
159      methodInfos.push(apiInfo);
160      return currentMap;
161    }
162    const apiInfos: BasicApiInfo[] = [];
163    apiInfos.push(apiInfo);
164    const currentMap: BasicApiInfoMap = new Map();
165    currentMap.set(StringConstant.SELF, apiInfos);
166    parentMap.set(apiName, currentMap);
167    return currentMap;
168  }
169
170  /**
171   * 处理方法节点中事件订阅相关方法
172   *
173   * 第一个参数只要是字符串的字面量就将apiName修改为on_string,联合类型进行分开解析
174   * @param {BasicApiInfo} apiInfo 当前api的解析对象
175   * @param {ts.Node} node 当前apinode节点
176   * @return {BasicApiInfo[]} 解析完on/off的apiInfo数组
177   */
178  static processEventMethod(apiInfo: BasicApiInfo, node: ts.Node): BasicApiInfo[] {
179    const apiInfos: BasicApiInfo[] = [];
180    const type: ts.TypeNode | undefined = NodeProcessorHelper.getOnOrOffMethodFirstParamType(
181      apiInfo,
182      node as MethodType
183    );
184    if (type === undefined) {
185      apiInfos.push(apiInfo);
186      return apiInfos;
187    }
188    const literal = (type as ts.LiteralTypeNode).literal;
189    if (type.kind === ts.SyntaxKind.LiteralType && ts.isStringLiteral(literal)) {
190      const text: string = literal.getText();
191      apiInfo.setApiName(`${apiInfo.getApiName()}_${text.substring(1, text.length - 1)}`);
192      apiInfo.setIsJoinType(true);
193    } else if (type.kind === ts.SyntaxKind.UnionType) {
194      const types: ts.NodeArray<ts.TypeNode> = (type as ts.UnionTypeNode).types;
195      types.forEach((item: ts.TypeNode) => {
196        if (ts.isLiteralTypeNode(item) && ts.isStringLiteral(item.literal)) {
197          const text: string = item.literal.getText();
198          const cloneApiInfo: BasicApiInfo = _.cloneDeep(apiInfo);
199          cloneApiInfo.setParentApi(apiInfo.getParentApi());
200          cloneApiInfo.setApiName(`${apiInfo.getApiName()}_${text.substring(1, text.length - 1)}`);
201          apiInfo.setIsJoinType(true);
202          apiInfos.push(cloneApiInfo);
203        }
204      });
205    } else if (type.kind === ts.SyntaxKind.StringKeyword) {
206      apiInfo.setApiName(`${apiInfo.getApiName()}_string`);
207      apiInfo.setIsJoinType(true);
208    } else if (type.kind === ts.SyntaxKind.BooleanKeyword) {
209      apiInfo.setApiName(`${apiInfo.getApiName()}_boolean`);
210      apiInfo.setIsJoinType(true);
211    } else {
212      apiInfo.setApiName(`${apiInfo.getApiName()}_${type.getText()}`);
213      apiInfo.setIsJoinType(true);
214    }
215    if (apiInfos.length === 0) {
216      apiInfos.push(apiInfo);
217    }
218    return apiInfos;
219  }
220
221  /**
222   * 获取on/off方法第一个参数的类型
223   *
224   * @param {BasicApiInfo} apiInfo 当前api的解析对象
225   * @param {MethodType} methodNode 当前apinode节点
226   * @return {(ts.TypeNode | undefined)} 满足条件的on/off第一个参数的类型
227   */
228  static getOnOrOffMethodFirstParamType(apiInfo: BasicApiInfo, methodNode: MethodType): ts.TypeNode | undefined {
229    const subscriotionSet: Set<string> = new Set(EventConstant.eventNameList);
230    if (!subscriotionSet.has(apiInfo.getApiName())) {
231      return undefined;
232    }
233    apiInfo.setIsJoinType(true);
234    if (methodNode.parameters.length === 0) {
235      return undefined;
236    }
237    const firstParam: ts.ParameterDeclaration = methodNode.parameters[0];
238    return firstParam.type;
239  }
240
241  /**
242   * 处理AsyncCallback和Promise,将符合规则的apiName修改为apiName(AsyncCallback/Promise243   *
244   * 1、返回参数是Promise类型
245   *
246   * 2、参数中有类型为AsyncCallback的参数
247   *
248   * @param {BasicApiInfo[]} apiInfos 需要处理的apiInfo集合
249   */
250  static processAsyncMethod(apiInfos: BasicApiInfo[]): void {
251    apiInfos.forEach((apiInfo: BasicApiInfo) => {
252      const methodInfo: MethodInfo = apiInfo as MethodInfo;
253      const returnValues: string[] = methodInfo.getReturnValue();
254      if (returnValues.length === 1 && returnValues[0].startsWith(StringConstant.PROMISE_METHOD_KEY)) {
255        methodInfo.setSync(StringConstant.PROMISE_METHOD_KEY_CHANGE);
256        return;
257      }
258      const params: ParamInfo[] = methodInfo.getParams();
259      for (let i = params.length - 1; i >= 0; i--) {
260        const paramType: string[] = params[i].getType();
261        if (paramType.length === 1 && paramType[0].startsWith(StringConstant.ASYNC_CALLBACK_METHOD_KEY)) {
262          methodInfo.setSync(StringConstant.ASYNC_CALLBACK_METHOD_KEY_CHANGE);
263          return;
264        }
265      }
266    });
267  }
268
269  /**
270   * 获取interface、class、namespace,struct以及type定义的对象的子节点
271   *
272   * @param { ts.Node } node 当前节点
273   * @returns { ts.NodeArray<ts.Node> | undefined } 返回当前节点的子节点
274   */
275  static getChildNodes(node: ts.Node): ts.NodeArray<ts.Node> | undefined {
276    if (
277      ts.isInterfaceDeclaration(node) ||
278      ts.isClassDeclaration(node) ||
279      ts.isEnumDeclaration(node)
280    ) {
281      return node.members;
282    }
283    if (ts.isStructDeclaration(node)) {
284      return ts.visitNodes(node.members, (node) => {
285        if (ts.isConstructorDeclaration(node)) {
286          return undefined;
287        }
288        return node;
289      });
290    }
291    if (ts.isTypeAliasDeclaration(node) && ts.isTypeLiteralNode(node.type)) {
292      return node.type.members;
293    }
294    if (ts.isModuleDeclaration(node) && node.body && ts.isModuleBlock(node.body)) {
295      return node.body.statements;
296    }
297    return undefined;
298  }
299
300  /**
301   * 处理export default xxx节点
302   *
303   * @param { ts.Node } node 当前节点
304   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
305   * @returns { ExportDefaultInfo } 返回处理后得到的ExportDefaultInfo对象
306   */
307  static processExportAssignment(node: ts.Node, parentApi: BasicApiInfo): ExportDefaultInfo {
308    const exportDefaultInfo: ExportDefaultInfo = new ExportDefaultInfo(ApiType.EXPORT_DEFAULT, node, parentApi);
309    const exportDefaultNode: ts.ExportAssignment = node as ts.ExportAssignment;
310    exportDefaultInfo.setApiName(StringConstant.EXPORT_DEFAULT + exportDefaultNode.expression.getText());
311    exportDefaultInfo.setDefinedText(exportDefaultNode.getText());
312    ModifierHelper.processModifiers(exportDefaultNode.modifiers, exportDefaultInfo);
313    return exportDefaultInfo;
314  }
315
316  /**
317   * 处理export { xxx }节点
318   *
319   * @param { ts.Node } node 当前节点
320   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
321   * @returns { ExportDeclareInfo } 返回处理后得到的ExportDeclareInfoInfo对象
322   */
323  static processExportDeclaration(node: ts.Node, parentApi: BasicApiInfo): ExportDeclareInfo {
324    const exportDeclareInfo: ExportDeclareInfo = new ExportDeclareInfo(ApiType.EXPORT, node, parentApi);
325    const exportDeclarationNode: ts.ExportDeclaration = node as ts.ExportDeclaration;
326    const exportClause: ts.NamedExportBindings | undefined = exportDeclarationNode.exportClause;
327    if (!exportClause) {
328      //export * from 'test';
329      exportDeclareInfo.setApiName(
330        StringConstant.EXPORT +
331        (exportDeclarationNode.moduleSpecifier ? exportDeclarationNode.moduleSpecifier.getText() : '')
332      );
333    } else if (ts.isNamespaceExport(exportClause)) {
334      //export * as myTest from 'test';
335      exportDeclareInfo.setApiName(StringConstant.EXPORT + exportClause.name.getText());
336    } else if (ts.isNamedExports(exportClause)) {
337      // export { xxx , yyy  }
338      // export { xxx as x, yyy as y }
339      const exportValueNames: string[] = [];
340      exportClause.elements.forEach((element: ts.ExportSpecifier) => {
341        const exportValueType: string = element.propertyName ? element.propertyName.getText() : '';
342        const exportValueName: string = element.name.getText();
343        exportValueNames.push(exportValueName);
344        exportDeclareInfo.addExportValues(exportValueName, exportValueType);
345      });
346      exportDeclareInfo.setApiName(StringConstant.EXPORT + exportValueNames.join('_'));
347    }
348    exportDeclareInfo.setDefinedText(exportDeclarationNode.getText());
349    ModifierHelper.processModifiers(exportDeclarationNode.modifiers, exportDeclareInfo);
350    return exportDeclareInfo;
351  }
352
353  /**
354   * 处理 export import NetAddress = connection.NetAddress;
355   *
356   * @param { ts.Node } node 当前节点
357   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
358   * @returns { importInfo } 返回处理后得到的importInfo对象
359   */
360  static processImportEqualsDeclaration(node: ts.Node, parentApi: BasicApiInfo): ImportInfo {
361    const importInfo: ImportInfo = new ImportInfo(ApiType.EXPORT, node, parentApi);
362    return importInfo;
363  }
364
365  /**
366   * 处理import xxx from xxx 节点
367   *
368   * @param { ts.Node } node 当前节点
369   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
370   * @returns { ImportInfo } 返回处理后得到的ImportInfo对象
371   */
372  static processImportInfo(node: ts.Node, parentApi: BasicApiInfo): ImportInfo {
373    const importInfo: ImportInfo = new ImportInfo(ApiType.IMPORT, node, parentApi);
374    const importNode: ts.ImportDeclaration = node as ts.ImportDeclaration;
375    importInfo.setApiName(importNode.moduleSpecifier.getText());
376    importInfo.setImportPath(importNode.moduleSpecifier.getText());
377    importInfo.setDefinedText(importNode.getText());
378    ModifierHelper.processModifiers(importNode.modifiers, importInfo);
379    if (importNode.importClause === undefined) {
380      return importInfo;
381    }
382    const importClause: ts.ImportClause = importNode.importClause;
383    if (importClause.namedBindings && ts.isNamedImports(importClause.namedBindings)) {
384      importClause.namedBindings.elements.forEach((element: ts.ImportSpecifier) => {
385        const importValueType: string = element.propertyName ? element.propertyName.getText() : '';
386        const importValueName: string = element.name.getText();
387        importInfo.addImportValue(importValueName, importValueType);
388      });
389    } else {
390      const importValueName: string = importClause.name ? importClause.name.escapedText.toString() : '';
391      importInfo.addImportValue(importValueName, importValueName);
392    }
393    return importInfo;
394  }
395
396  /**
397   * 处理interface节点
398   *
399   * @param { ts.Node } node 当前节点
400   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
401   * @returns { InterfaceInfo } 返回处理后得到的InterfaceInfo对象
402   */
403  static processInterface(node: ts.Node, parentApi: BasicApiInfo): InterfaceInfo {
404    const interfaceDeclaration: ts.InterfaceDeclaration = node as ts.InterfaceDeclaration;
405    const interfaceInfo: InterfaceInfo = new InterfaceInfo(ApiType.INTERFACE, node, parentApi);
406    interfaceInfo.setApiName(interfaceDeclaration.name.getText());
407    interfaceDeclaration.typeParameters?.forEach((typeParameter: ts.TypeParameterDeclaration) => {
408      interfaceInfo.setGenericInfo(NodeProcessorHelper.processGenericity(typeParameter));
409    });
410    ModifierHelper.processModifiers(interfaceDeclaration.modifiers, interfaceInfo);
411    if (interfaceDeclaration.heritageClauses === undefined) {
412      return interfaceInfo;
413    }
414    interfaceDeclaration.heritageClauses.forEach((value: ts.HeritageClause) => {
415      if (value.token === ts.SyntaxKind.ExtendsKeyword) {
416        value.types.forEach((value: ts.ExpressionWithTypeArguments) => {
417          const parentClass: ParentClass = new ParentClass();
418          parentClass.setImplementClass('');
419          parentClass.setExtendClass(value.getText());
420          interfaceInfo.setParentClasses(parentClass);
421        });
422      } else if (value.token === ts.SyntaxKind.ImplementsKeyword) {
423        value.types.forEach((value: ts.ExpressionWithTypeArguments) => {
424          const parentClass: ParentClass = new ParentClass();
425          parentClass.setImplementClass(value.getText());
426          parentClass.setExtendClass('');
427          interfaceInfo.setParentClasses(parentClass);
428        });
429      }
430    });
431    return interfaceInfo;
432  }
433
434  static processGenericity(typeParameter: ts.TypeParameterDeclaration): GenericInfo {
435    const genericInfo: GenericInfo = new GenericInfo();
436    genericInfo.setIsGenericity(true);
437    genericInfo.setGenericContent(typeParameter.getText());
438    return genericInfo;
439  }
440  /**
441   * 处理class节点
442   *
443   * @param { ts.Node } node 当前节点
444   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
445   * @returns { ClassInfo } 返回处理后得到的ClassInfo对象
446   */
447  static processClass(node: ts.Node, parentApi: BasicApiInfo): ClassInfo {
448    const classDeclaration: ts.ClassDeclaration = node as ts.ClassDeclaration;
449    const classInfo: ClassInfo = new ClassInfo(ApiType.CLASS, node, parentApi);
450    const className: string = classDeclaration.name ? classDeclaration.name.getText() : '';
451    classInfo.setApiName(className);
452    classDeclaration.typeParameters?.forEach((typeParameter: ts.TypeParameterDeclaration) => {
453      classInfo.setGenericInfo(NodeProcessorHelper.processGenericity(typeParameter));
454    });
455    ModifierHelper.processModifiers(classDeclaration.modifiers, classInfo);
456    if (classDeclaration.heritageClauses === undefined) {
457      return classInfo;
458    }
459    classDeclaration.heritageClauses.forEach((value: ts.HeritageClause) => {
460      if (value.token === ts.SyntaxKind.ExtendsKeyword) {
461        value.types.forEach((value: ts.ExpressionWithTypeArguments) => {
462          const parentClass: ParentClass = new ParentClass();
463          parentClass.setExtendClass(value.getText());
464          parentClass.setImplementClass('');
465          classInfo.setParentClasses(parentClass);
466        });
467      } else if (value.token === ts.SyntaxKind.ImplementsKeyword) {
468        value.types.forEach((value: ts.ExpressionWithTypeArguments) => {
469          const parentClass: ParentClass = new ParentClass();
470          parentClass.setImplementClass(value.getText());
471          parentClass.setExtendClass('');
472          classInfo.setParentClasses(parentClass);
473        });
474      }
475    });
476    return classInfo;
477  }
478
479  /**
480   * 处理module节点,分为外部模块(module)和内部模块(namespace)
481   *
482   * @param { ts.Node } node 当前节点
483   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
484   * @returns { NamespaceInfo } 返回处理后得到的NamespaceInfo对象
485   */
486  static processBaseModule(node: ts.Node, parentApi: BasicApiInfo): NamespaceInfo {
487    const moduleDeclaration: ts.ModuleDeclaration = node as ts.ModuleDeclaration;
488    if (!ts.isIdentifier(moduleDeclaration.name)) {
489      return NodeProcessorHelper.processModule(node, parentApi);
490    }
491    return NodeProcessorHelper.processNamespace(node, parentApi);
492  }
493
494  /**
495   * 处理module节点-外部模块
496   *
497   * @param { ts.Node } node 当前节点
498   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
499   * @returns { ModuleInfo } 返回处理后得到的ModuleInfo对象
500   */
501  static processModule(node: ts.Node, parentApi: BasicApiInfo): ModuleInfo {
502    const moduleDeclaration: ts.ModuleDeclaration = node as ts.ModuleDeclaration;
503    const moduleInfo: ModuleInfo = new ModuleInfo(ApiType.MODULE, node, parentApi);
504    moduleInfo.setApiName(moduleDeclaration.name.getText());
505    ModifierHelper.processModifiers(moduleDeclaration.modifiers, moduleInfo);
506    return moduleInfo;
507  }
508
509  /**
510   * 处理namespace节点-内部模块
511   *
512   * @param { ts.Node } node 当前节点
513   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
514   * @returns { NamespaceInfo } 返回处理后得到的NamespaceInfo对象
515   */
516  static processNamespace(node: ts.Node, parentApi: BasicApiInfo): NamespaceInfo {
517    const moduleDeclaration: ts.ModuleDeclaration = node as ts.ModuleDeclaration;
518    const namespaceInfo: NamespaceInfo = new NamespaceInfo(ApiType.NAMESPACE, node, parentApi);
519    namespaceInfo.setApiName(moduleDeclaration.name.getText());
520    ModifierHelper.processModifiers(moduleDeclaration.modifiers, namespaceInfo);
521    return namespaceInfo;
522  }
523
524  /**
525   * 处理enum节点
526   *
527   * @param { ts.Node } node 当前节点
528   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
529   * @returns { EnumInfo } 返回处理后得到的EnumInfo对象
530   */
531  static processEnum(node: ts.Node, parentApi: BasicApiInfo): EnumInfo {
532    const enumDeclaration: ts.EnumDeclaration = node as ts.EnumDeclaration;
533    const enumInfo: EnumInfo = new EnumInfo(ApiType.ENUM, node, parentApi);
534    enumInfo.setApiName(enumDeclaration.name.getText());
535    ModifierHelper.processModifiers(enumDeclaration.modifiers, enumInfo);
536    return enumInfo;
537  }
538
539  /**
540   * 处理枚举值节点
541   *
542   * @param { ts.Node } node 当前节点
543   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
544   * @returns { EnumValueInfo } 返回处理后得到的EnumValueInfo对象
545   */
546  static processEnumValue(node: ts.Node, parentApi: BasicApiInfo): EnumValueInfo {
547    const enumValueNode: ts.EnumMember = node as ts.EnumMember;
548    const enumValueInfo: EnumValueInfo = new EnumValueInfo(ApiType.ENUM_VALUE, node, parentApi);
549    enumValueInfo.setApiName(enumValueNode.name.getText());
550    enumValueInfo.setDefinedText(enumValueNode.getText());
551    const enumInfo: EnumInfo = parentApi as EnumInfo;
552    enumValueInfo.setValue(NodeProcessorHelper.getCurrentEnumValue(enumInfo));
553    if (enumValueNode.initializer) {
554      const value: string = enumValueNode.initializer.getText().replace(NodeProcessorHelper.regQuotation, '$1');
555      enumValueInfo.setValue(value);
556    }
557    return enumValueInfo;
558  }
559
560  /**
561   *
562   * @param  { EnumInfo } enumInfo Enum枚举类节点的信息
563   * @returns { string } 返回当前遍历到的枚举成员的可能的枚举值
564   */
565  static getCurrentEnumValue(enumInfo: EnumInfo): string {
566    const length: number = enumInfo.getChildApis().length;
567    if (length === 0) {
568      return String(0);
569    }
570    const preEnumValueInfo: EnumValueInfo = enumInfo.getChildApis()[length - 1] as EnumValueInfo;
571    const preEnumValue: string = preEnumValueInfo.getValue();
572    return isNaN(Number(preEnumValue)) ? '' : `${Number(preEnumValue) + 1}`;
573  }
574
575  /**
576   * 处理interface或class下面的属性节点
577   *
578   * @param { ts.Node } node 当前节点
579   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
580   * @returns { PropertyInfo } 返回处理后得到的PropertyInfo对象
581   */
582  static processPropertySigAndDec(node: ts.Node, parentApi: BasicApiInfo): PropertyInfo {
583    const propertyNode: PropertyNode = node as PropertyNode;
584    const propertyInfo: PropertyInfo = new PropertyInfo(ApiType.PROPERTY, node, parentApi);
585    propertyInfo.setApiName(propertyNode.name.getText());
586    propertyInfo.setDefinedText(propertyNode.getText());
587    ModifierHelper.processModifiers(propertyNode.modifiers, propertyInfo);
588    propertyInfo.setIsRequired(!propertyNode.questionToken ? true : false);
589    propertyInfo.addType(NodeProcessorHelper.processDataType(propertyNode.type));
590    if (Boolean(process.env.NEED_DETECTION) && propertyNode.type) {
591      NodeProcessorHelper.processFunctionTypeNode(
592        propertyNode.type,
593        propertyInfo,
594        new ParamInfo(ApiType.PARAM),
595        false
596      );
597    }
598    propertyInfo.setTypeKind(propertyNode.type?.kind);
599    return propertyInfo;
600  }
601
602  /**
603   * 处理.d.ets文件中的Struct节点
604   *
605   * @param { ts.Node } node 当前节点
606   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
607   * @returns { StructInfo } 返回处理后得到的StructInfo对象
608   */
609  static processStruct(node: ts.Node, parentApi: BasicApiInfo): StructInfo {
610    const structNode: ts.StructDeclaration = node as ts.StructDeclaration;
611    const structInfo: StructInfo = new StructInfo(ApiType.STRUCT, node, parentApi);
612    const structName: string = structNode.name ? structNode.name.getText() : '';
613    structInfo.setApiName(structName);
614    structInfo.setDefinedText(structInfo.getApiName());
615    ModifierHelper.processModifiers(structNode.modifiers, structInfo);
616    return structInfo;
617  }
618
619  /**
620   * 处理方法节点
621   *
622   * @param { ts.Node } node 当前节点
623   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
624   * @returns { MethodInfo } 返回处理后得到的MethodInfo对象
625   */
626  static processMethod(node: ts.Node, parentApi: BasicApiInfo): MethodInfo {
627    const methodNode: MethodType = node as MethodType;
628    const methodInfo: MethodInfo = new MethodInfo(ApiType.METHOD, node, parentApi);
629    methodInfo.setDefinedText(methodNode.getText());
630    let methodName: string = methodNode.name ? methodNode.name.getText() : '';
631    if (
632      ts.isConstructorDeclaration(methodNode) ||
633      ts.isConstructSignatureDeclaration(methodNode) ||
634      ts.isCallSignatureDeclaration(methodNode)
635    ) {
636      methodName = StringConstant.CONSTRUCTOR_API_NAME;
637    }
638    methodInfo.setApiName(methodName);
639    methodInfo.setIsRequired(!methodNode.questionToken ? true : false);
640    methodNode.typeParameters?.forEach((typeParameter: ts.TypeParameterDeclaration) => {
641      methodInfo.setGenericInfo(NodeProcessorHelper.processGenericity(typeParameter));
642    });
643    const callForm: string = methodNode.getText().replace(/export\s+|declare\s+|function\s+|\r\n|\;/g, '');
644    methodInfo.setCallForm(callForm);
645    if (methodNode.type && ts.SyntaxKind.VoidKeyword !== methodNode.type.kind) {
646      const returnValues: string[] = NodeProcessorHelper.processDataType(methodNode.type);
647      methodInfo.setReturnValue(returnValues);
648      methodInfo.setReturnValueType(methodNode.type.kind);
649      if (Boolean(process.env.NEED_DETECTION)) {
650        NodeProcessorHelper.processFunctionTypeNode(
651          methodNode.type,
652          methodInfo,
653          new ParamInfo(ApiType.PARAM),
654          false
655        );
656      }
657    }
658    for (let i = 0; i < methodNode.parameters.length; i++) {
659      const param: ts.ParameterDeclaration = methodNode.parameters[i];
660      const paramInfo: ParamInfo = NodeProcessorHelper.processParam(param, methodInfo);
661      methodInfo.addParam(paramInfo);
662    }
663    if (!ts.isCallSignatureDeclaration(methodNode) && !ts.isConstructSignatureDeclaration(methodNode)) {
664      ModifierHelper.processModifiers(methodNode.modifiers, methodInfo);
665    }
666    return methodInfo;
667  }
668
669  /**
670   * 处理方法入参
671   *
672   * @param { ts.ParameterDeclaration } param 参数节点
673   * @param { MethodInfo } methodInfo MethodInfo对象
674   * @returns { ParamInfo } 返回处理后的ParamInfo对象
675   */
676  static processParam(param: ts.ParameterDeclaration, methodInfo: MethodInfo): ParamInfo {
677    const paramInfo: ParamInfo = new ParamInfo(ApiType.PARAM);
678    paramInfo.setApiName(param.name.getText());
679    paramInfo.setIsRequired(!param.questionToken ? true : false);
680    paramInfo.setDefinedText(param.getText());
681    paramInfo.setParamType(param.type?.kind);
682    if (param.type === undefined) {
683      return paramInfo;
684    }
685    let typeMapValue: string | undefined = undefined;
686    if (Boolean(process.env.NEED_DETECTION)) {
687      NodeProcessorHelper.processFunctionTypeNode(param.type, methodInfo, paramInfo, true);
688    }
689    if (ts.isLiteralTypeNode(param.type)) {
690      typeMapValue = typeMap.get(param.type.literal.kind);
691    }
692    paramInfo.setType(NodeProcessorHelper.processDataType(param.type));
693    return paramInfo;
694  }
695
696  /**
697   * 根据node节点获取当前文件名称
698   *
699   * @param {ts.Node} node
700   * @return {string} 文件名称
701   */
702  static getFilePathFromNode(node: ts.Node): string {
703    if (ts.isSourceFile(node)) {
704      return node.fileName;
705    } else {
706      return NodeProcessorHelper.getFilePathFromNode(node.parent);
707    }
708  }
709
710  /**
711   * 设置SymbolOfTypeReferenceMap对象
712   *
713   * @param {string} filePath 文件路径
714   * @param {ts.TypeReferenceNode} tsNode 文件中的typeReference
715   * @param {ts.Symbol} symbol typereference对应symbol
716   */
717  static setSymbolOfTypeReferenceMap(filePath: string, tsNode: ts.TypeReferenceNode, symbol: ts.Symbol): void {
718    if (!NodeProcessorHelper.symbolOfTypeReferenceMap.has(filePath)) {
719      NodeProcessorHelper.symbolOfTypeReferenceMap.set(filePath, new Map<string, ts.Symbol>());
720    }
721    const typeSymbolMap: Map<string, ts.Symbol> | undefined =
722      NodeProcessorHelper.symbolOfTypeReferenceMap.get(filePath);
723    if (!typeSymbolMap) {
724      return;
725    }
726    if (!typeSymbolMap.has(tsNode.getFullText().trim())) {
727      typeSymbolMap.set(tsNode.getFullText().trim(), symbol);
728    }
729  }
730
731  /**
732   * 从symbolOfTypeReferenceMap获取值
733   *
734   * @param {string} filePath 文件路径
735   * @param {ts.TypeReferenceNode} tsNode 文件中的typeReference
736   * @return {(ts.Symbol | undefined)} symbol值
737   */
738  static getSymbolOfTypeReferenceMap(filePath: string, tsNode: ts.TypeReferenceNode): ts.Symbol | undefined {
739    const fileSymbolMap: Map<string, ts.Symbol> | undefined =
740      NodeProcessorHelper.symbolOfTypeReferenceMap.get(filePath);
741    if (!fileSymbolMap) {
742      return undefined;
743    }
744    const typeSymbol: ts.Symbol | undefined = fileSymbolMap.get(tsNode.getFullText().trim());
745    if (!typeSymbol) {
746      return undefined;
747    }
748    return typeSymbol;
749  }
750
751  /**
752   * 处理方法入参的类型、联合类型时会将多个类型遍历传入
753   * 引用类型获取对应文件中的jsdoc
754   * 匿名类型获取属性的doc信息
755   *
756   * @param { ts.TypeNode } typeNode 参数类型
757   * @param { MethodInfo } methodInfo MethodInfo对象
758   * @param { ParamInfo } paramInfo ParamInfo对象
759   * @param { boolean } [isParam = true] 是否是参数的type,
760   * true:类型为参数(入参)的数据
761   * false:类型为返回值(出参)的数据
762   */
763  static processFunctionTypeNode(
764    typeNode: ts.TypeNode,
765    methodInfo: MethodInfo | PropertyInfo,
766    paramInfo: ParamInfo,
767    isParam: boolean = true
768  ): void {
769    if (ts.isTypeLiteralNode(typeNode)) {
770      NodeProcessorHelper.processFunctionTypeObject(typeNode, methodInfo, paramInfo, isParam);
771    } else if (ts.isUnionTypeNode(typeNode)) {
772      typeNode.types.forEach((type: ts.TypeNode) => {
773        NodeProcessorHelper.processFunctionTypeNode(type, methodInfo, paramInfo, isParam);
774      });
775    } else if (ts.isFunctionTypeNode(typeNode)) {
776      typeNode.parameters.forEach((parameter: ts.ParameterDeclaration) => {
777        if (parameter.type) {
778          NodeProcessorHelper.processFunctionTypeNode(parameter.type, methodInfo, paramInfo, isParam);
779        }
780      });
781      NodeProcessorHelper.processFunctionTypeNode(typeNode.type, methodInfo, paramInfo, isParam);
782    }
783    if (!ts.isTypeReferenceNode(typeNode)) {
784      return;
785    }
786    NodeProcessorHelper.processFunctionTypeReference(typeNode, methodInfo, paramInfo, isParam);
787  }
788
789  /**
790   * 处理方法引用类型
791   *
792   * @param { ts.TypeNode } typeNode 参数类型
793   * @param { MethodInfo } methodInfo MethodInfo对象
794   * @param { ParamInfo } paramInfo ParamInfo对象
795   * @param { boolean } [isParam = true] 是否是参数的type,
796   * true:类型为参数(入参)的数据
797   * false:类型为返回值(出参)的数据
798   */
799  static processFunctionTypeReference(
800    typeNode: ts.TypeReferenceNode,
801    methodInfo: MethodInfo | PropertyInfo,
802    paramInfo: ParamInfo,
803    isParam: boolean = true
804  ): void {
805    const typeArguments: ts.NodeArray<ts.TypeNode> | undefined = typeNode.typeArguments;
806    typeArguments?.forEach((typeArgument: ts.TypeNode) => {
807      NodeProcessorHelper.processFunctionTypeNode(typeArgument, methodInfo, paramInfo, isParam);
808    });
809    try {
810      const tsProgram: ts.Program = parserParam.getTsProgram();
811      const filePath: string = parserParam.getFilePath();
812      Object.assign(tsProgram, {
813        getSymbolOfTypeReference: (tsNode: ts.TypeReferenceNode, symbol: ts.Symbol) => {
814          const currentFilePath: string = NodeProcessorHelper.getFilePathFromNode(tsNode);
815          if (path.resolve(currentFilePath) !== path.resolve(filePath)) {
816            return;
817          }
818          NodeProcessorHelper.setSymbolOfTypeReferenceMap(filePath, tsNode, symbol);
819        }
820      });
821      tsProgram.emit();
822      const currentTypeSymbol: ts.Symbol | undefined =
823        NodeProcessorHelper.getSymbolOfTypeReferenceMap(filePath, typeNode);
824      if (!currentTypeSymbol) {
825        return;
826      }
827      const declarations: ts.Declaration[] | undefined = currentTypeSymbol.declarations;
828      if (!declarations) {
829        return;
830      }
831      const declaration: ts.Declaration = declarations[0];
832      const fileTags: FileTag = methodInfo.getKitInfoFromParent(methodInfo);
833      const jsDocInfos: Comment.JsDocInfo[] = JsDocProcessorHelper.processJsDocInfos(
834        declaration,
835        ApiType.TYPE_ALIAS,
836        fileTags.kitInfo,
837        fileTags.isFile
838      );
839      if (jsDocInfos.length === 0) {
840        return;
841      }
842      const typeLocationInfo: TypeLocationInfo = jsDocInfos[jsDocInfos.length - 1] as TypeLocationInfo;
843      typeLocationInfo.removeTags();
844      new TypeLocationInfo().setTypeName.apply(typeLocationInfo, [typeNode.getFullText().trim()]);
845      if (isParam) {
846        paramInfo.addTypeLocations(typeLocationInfo);
847      } else {
848        methodInfo.addTypeLocations(typeLocationInfo);
849      }
850    } catch (error) {
851    } finally {
852    }
853  }
854
855  /**
856   * 处理方法入参的匿名类型
857   * 将匿名类型的每个属性的doc存储
858   *
859   * @param {ts.TypeLiteralNode} typeObject 匿名对象
860   * @param {MethodInfo} methodInfo MethodInfo对象
861   * @param {ParamInfo} paramInfo ParamInfo对象
862   * @param { boolean } [isParam = true] 是否是参数的type,
863   * true:类型为参数(入参)的数据
864   * false:类型为返回值(出参)的数据
865   */
866  static processFunctionTypeObject(
867    typeObject: ts.TypeLiteralNode,
868    methodInfo: MethodInfo | PropertyInfo,
869    paramInfo: ParamInfo,
870    isParam: boolean = true
871  ): void {
872    const fileTags: FileTag = methodInfo.getKitInfoFromParent(methodInfo);
873    typeObject.members.forEach((member: ts.TypeElement) => {
874      const jsDocInfos: Comment.JsDocInfo[] = JsDocProcessorHelper.processJsDocInfos(
875        member,
876        ApiType.TYPE_ALIAS,
877        fileTags.kitInfo,
878        fileTags.isFile
879      );
880      if (jsDocInfos.length === 0) {
881        return;
882      }
883      const typeLocationInfo: TypeLocationInfo = jsDocInfos[jsDocInfos.length - 1] as TypeLocationInfo;
884      if (isParam) {
885        paramInfo.addObjLocations(typeLocationInfo);
886      } else {
887        methodInfo.addObjLocations(typeLocationInfo);
888      }
889      if (ts.isPropertySignature(member) && member.type) {
890        NodeProcessorHelper.processFunctionTypeNode(member.type, methodInfo, paramInfo, isParam);
891      }
892    });
893  }
894
895  /**
896   * 处理数据类型,因为会存在联合类型的情况
897   *
898   * @param { string } dataType 类型信息的字符串
899   * @returns { string[] } 返回处理后的数组
900   */
901  static processDataType(dataType: ts.TypeNode | undefined): string[] {
902    const typeArr: string[] = [];
903    if (!dataType) {
904      return typeArr;
905    }
906    if (ts.isUnionTypeNode(dataType)) {
907      dataType.types.forEach((type: ts.TypeNode) => {
908        typeArr.push(type.getText());
909      });
910      return typeArr;
911    }
912    typeArr.push(dataType.getText());
913    return typeArr;
914  }
915
916  /**
917   * 处理type关键字定义的节点TypeAliasDeclaration,包含定义别名(包含联合类型)以及自定义对象(归为interface)
918   *
919   * @param { ts.Node } node 当前节点
920   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
921   * @returns { ApiInfo } 返回处理后的ApiInfo对象
922   */
923  static TypeAliasDeclaration(node: ts.Node, parentApi: BasicApiInfo): ApiInfo {
924    const typeAliasNode: ts.TypeAliasDeclaration = node as ts.TypeAliasDeclaration;
925    if (typeAliasNode.type.kind === ts.SyntaxKind.TypeLiteral) {
926      return NodeProcessorHelper.processTypeInterface(typeAliasNode, parentApi);
927    } else {
928      return NodeProcessorHelper.processTypeAlias(typeAliasNode, parentApi);
929    }
930  }
931
932  /**
933   * 处理type关键字定义的对象,如type sample = { count: number }
934   *
935   * @param { ts.TypeAliasDeclaration } node 当前节点
936   * @returns { InterfaceInfo } 返回处理后的InterfaceInfo对象
937   */
938  static processTypeInterface(node: ts.TypeAliasDeclaration, parentApi: BasicApiInfo): InterfaceInfo {
939    const interfaceInfo: InterfaceInfo = new InterfaceInfo(ApiType.INTERFACE, node, parentApi);
940    interfaceInfo.setApiName(node.name.getText());
941    interfaceInfo.setDefinedText(interfaceInfo.getApiName());
942    ModifierHelper.processModifiers(node.modifiers, interfaceInfo);
943    return interfaceInfo;
944  }
945
946  /**
947   * 处理type关键字定义的类型别名,包含联合类型
948   *
949   * @param { ts.Node } node 当前节点
950   * @returns { TypeAliasInfo } 返回处理后的TypeAliasInfo对象
951   */
952  static processTypeAlias(node: ts.TypeAliasDeclaration, parentApi: BasicApiInfo): TypeAliasInfo {
953    const typeNameMap: Map<number, string> = new Map([
954      [ts.SyntaxKind.UnionType, TypeAliasType.UNION_TYPE],
955      [ts.SyntaxKind.TypeLiteral, TypeAliasType.OBJECT_TYPE],
956      [ts.SyntaxKind.TupleType, TypeAliasType.TUPLE_TYPE],
957      [ts.SyntaxKind.TypeReference, TypeAliasType.REFERENCE_TYPE],
958    ]);
959    const typeAliasInfo: TypeAliasInfo = new TypeAliasInfo(ApiType.TYPE_ALIAS, node, parentApi);
960    typeAliasInfo.setApiName(node.name.getText());
961    const typeName: string | undefined = typeNameMap.get(node.type.kind);
962    if (typeName) {
963      typeAliasInfo.setTypeName(typeName);
964    }
965    let nodeType: ts.TypeNode = node.type;
966    if (ts.isFunctionTypeNode(nodeType)) {
967      const typeParameters = nodeType.parameters;
968      typeParameters.forEach((typeParameter: ts.ParameterDeclaration) => {
969        const typeParamInfo: ParamInfo = NodeProcessorHelper.processParam(
970          typeParameter,
971          new MethodInfo(ApiType.METHOD, node, parentApi)
972        );
973        typeAliasInfo.setParamInfos(typeParamInfo);
974      });
975      typeAliasInfo.setReturnType(nodeType.type.getText());
976      typeAliasInfo.setTypeIsFunction(true);
977    }
978
979    typeAliasInfo.setDefinedText(node.getText());
980    ModifierHelper.processModifiers(node.modifiers, typeAliasInfo);
981    typeAliasInfo.addType(NodeProcessorHelper.processDataType(node.type));
982    return typeAliasInfo;
983  }
984
985  /**
986   * 处理VariableStatement节点,根据节点定义的情况会将其处理为常量或属性
987   *
988   * @param { ts.Node } node 当前节点
989   * @param { BasicApiInfo } parentApi 存储父节点信息的对象
990   * @returns { BasicApiInfo } 返回处理后的节点对象
991   */
992  static processVariableStat(node: ts.Node, parentApi: BasicApiInfo): BasicApiInfo {
993    const variableNode: ts.VariableStatement = node as ts.VariableStatement;
994    const definedText: string = variableNode.getText();
995    const declarationNode: ts.VariableDeclaration = variableNode.declarationList.declarations[0];
996    const REG_DECLARE_CONSTANT: RegExp = /declare\s+const/;
997    const REG_COMPONENT: RegExp = /[a-zA-Z]+(Attribute|Interface)/;
998    // declare const
999    let variableType: string = '';
1000    let value: string = '';
1001    if (declarationNode.type) {
1002      if (ts.isLiteralTypeNode(declarationNode.type)) {
1003        const typeOfLiteral: string | undefined = typeMap.get(declarationNode.type.literal.kind);
1004        variableType = typeOfLiteral ? typeOfLiteral : '';
1005        value = declarationNode.type.literal.getText().replace(NodeProcessorHelper.regQuotation, '$1');
1006      } else {
1007        variableType = declarationNode.type.getText();
1008      }
1009    }
1010    if (REG_DECLARE_CONSTANT.test(variableNode.getText()) && REG_COMPONENT.test(variableType)) {
1011      return NodeProcessorHelper.processDeclareConstant(variableNode, definedText, variableType, parentApi);
1012    }
1013    // 节点有初始化值,如const a = 1,归为常量
1014    if (declarationNode.initializer) {
1015      const constantValue: string = declarationNode.initializer.getText();
1016      return NodeProcessorHelper.processConstant(variableNode, definedText, constantValue, parentApi);
1017    }
1018    // 节点的类型为字面量值,如const a: 111,归为常量
1019    const typeNode: ts.TypeNode | undefined = declarationNode.type;
1020    if (typeNode && ts.isLiteralTypeNode(typeNode)) {
1021      const constantValue: string = typeNode.getText();
1022      return NodeProcessorHelper.processConstant(variableNode, definedText, constantValue, parentApi);
1023    }
1024    // 除了上述两种常量的情况,其他归为属性
1025    return NodeProcessorHelper.processVaribleProperty(variableNode, definedText, parentApi);
1026  }
1027
1028  /**
1029   * 处理常量节点
1030   *
1031   * @param { ts.VariableDeclaration } node 当前节点
1032   * @param { string } definedText 节点定义的字符串
1033   * @param { string } value 常量的取值
1034   * @param { BasicApiInfo } parentApi 父节点解析后的对象
1035   * @returns { ConstantInfo } 返回解析后的常量对象
1036   */
1037  static processConstant(
1038    node: ts.VariableStatement,
1039    definedText: string,
1040    value: string,
1041    parentApi: BasicApiInfo
1042  ): ConstantInfo {
1043    const declarationNode: ts.VariableDeclaration = node.declarationList.declarations[0] as ts.VariableDeclaration;
1044    const constantInfo: ConstantInfo = new ConstantInfo(ApiType.CONSTANT, node, parentApi);
1045    constantInfo.setDefinedText(definedText);
1046    constantInfo.setApiName(declarationNode.name.getText());
1047    constantInfo.setValue(value);
1048    return constantInfo;
1049  }
1050
1051  /**
1052   * 处理declare常量节点
1053   *
1054   * @param { ts.VariableDeclaration } node 当前节点
1055   * @param { string } definedText 节点定义的字符串
1056   * @param { string } value 常量的取值
1057   * @param { BasicApiInfo } parentApi 父节点解析后的对象
1058   * @returns { ConstantInfo } 返回解析后的常量对象
1059   */
1060  static processDeclareConstant(
1061    node: ts.VariableStatement,
1062    definedText: string,
1063    value: string,
1064    parentApi: BasicApiInfo
1065  ): ConstantInfo {
1066    const declarationNode: ts.VariableDeclaration = node.declarationList.declarations[0] as ts.VariableDeclaration;
1067    const constantInfo: ConstantInfo = new ConstantInfo(ApiType.DECLARE_CONST, node, parentApi);
1068    constantInfo.setDefinedText(definedText);
1069    constantInfo.setApiName(declarationNode.name.getText());
1070    constantInfo.setValue(value);
1071    return constantInfo;
1072  }
1073
1074  /**
1075   * 处理VariableDeclaration节点类型的属性节点
1076   *
1077   * @param { ts.VariableDeclaration } node 当前节点
1078   * @param { string } definedText 节点定义的字符串
1079   * @param { BasicApiInfo } parentApi 父节点解析后的对象
1080   * @returns { ConstantInfo } 返回解析后的属性对象
1081   */
1082  static processVaribleProperty(
1083    node: ts.VariableStatement,
1084    definedText: string,
1085    parentApi: BasicApiInfo
1086  ): PropertyInfo {
1087    const declarationNode: ts.VariableDeclaration = node.declarationList.declarations[0] as ts.VariableDeclaration;
1088    const propertyInfo: PropertyInfo = new PropertyInfo(ApiType.PROPERTY, node, parentApi);
1089    propertyInfo.setDefinedText(definedText);
1090    propertyInfo.setApiName(declarationNode.name.getText());
1091    propertyInfo.addType(NodeProcessorHelper.processDataType(declarationNode.type));
1092    propertyInfo.setIsRequired(true);
1093    propertyInfo.setTypeKind(declarationNode?.type?.kind);
1094    if (StringUtils.hasSubstring(definedText, StringConstant.CONST_KEY_WORD)) {
1095      propertyInfo.setIsReadOnly(true);
1096    }
1097    return propertyInfo;
1098  }
1099}
1100
1101/**
1102 * 处理export readonly、static等修饰关键字
1103 */
1104export class ModifierHelper {
1105  static setIsStatic(apiInfo: BasicApiInfo): void {
1106    const propertyOrMethodInfo: PropertyInfo | MethodInfo = apiInfo as PropertyInfo | MethodInfo;
1107    propertyOrMethodInfo.setIsStatic(true);
1108  }
1109
1110  static setIsReadonly(apiInfo: BasicApiInfo): void {
1111    const propertyInfo: PropertyInfo = apiInfo as PropertyInfo;
1112    if (propertyInfo.setIsReadOnly) {
1113      propertyInfo.setIsReadOnly(true);
1114    }
1115  }
1116
1117  static setIsExport(apiInfo: BasicApiInfo): void {
1118    apiInfo.setIsExport(true);
1119  }
1120
1121  static processModifiers(modifiers: ts.NodeArray<ts.Modifier> | undefined, apiInfo: BasicApiInfo): void {
1122    let definedText: string = '';
1123    if (modifiers) {
1124      modifiers.forEach((modifier: ts.Modifier) => {
1125        if (containerApiTypes.has(apiInfo.apiType) && !ts.isDecorator(modifier)) {
1126          definedText += ` ${modifier.getText()}`;
1127        }
1128
1129        const setModifier: ModifierProcessorInterface | undefined = modifierProcessorMap.get(modifier.kind);
1130        setModifier ? setModifier(apiInfo) : undefined;
1131      });
1132    }
1133    if (containerApiTypes.has(apiInfo.apiType)) {
1134      definedText += ` ${apiInfo.getApiType().toLowerCase()} ${apiInfo.getApiName()}`;
1135      apiInfo.setDefinedText(definedText.trim());
1136    }
1137  }
1138}
1139
1140export const nodeProcessorMap: Map<ts.SyntaxKind, NodeProcessorInterface> = new Map([
1141  [ts.SyntaxKind.ExportAssignment, NodeProcessorHelper.processExportAssignment],
1142  [ts.SyntaxKind.ExportDeclaration, NodeProcessorHelper.processExportDeclaration],
1143  // [ts.SyntaxKind.ImportEqualsDeclaration, NodeProcessorHelper.processImportEqualsDeclaration],
1144  [ts.SyntaxKind.ImportDeclaration, NodeProcessorHelper.processImportInfo],
1145  [ts.SyntaxKind.VariableStatement, NodeProcessorHelper.processVariableStat],
1146  [ts.SyntaxKind.MethodDeclaration, NodeProcessorHelper.processMethod],
1147  [ts.SyntaxKind.MethodSignature, NodeProcessorHelper.processMethod],
1148  [ts.SyntaxKind.FunctionDeclaration, NodeProcessorHelper.processMethod],
1149  [ts.SyntaxKind.Constructor, NodeProcessorHelper.processMethod],
1150  [ts.SyntaxKind.ConstructSignature, NodeProcessorHelper.processMethod],
1151  [ts.SyntaxKind.CallSignature, NodeProcessorHelper.processMethod],
1152  [ts.SyntaxKind.PropertyDeclaration, NodeProcessorHelper.processPropertySigAndDec],
1153  [ts.SyntaxKind.PropertySignature, NodeProcessorHelper.processPropertySigAndDec],
1154  [ts.SyntaxKind.EnumMember, NodeProcessorHelper.processEnumValue],
1155  [ts.SyntaxKind.EnumDeclaration, NodeProcessorHelper.processEnum],
1156  [ts.SyntaxKind.TypeAliasDeclaration, NodeProcessorHelper.processTypeAlias],
1157  [ts.SyntaxKind.ClassDeclaration, NodeProcessorHelper.processClass],
1158  [ts.SyntaxKind.InterfaceDeclaration, NodeProcessorHelper.processInterface],
1159  [ts.SyntaxKind.ModuleDeclaration, NodeProcessorHelper.processBaseModule],
1160  [ts.SyntaxKind.StructDeclaration, NodeProcessorHelper.processStruct],
1161]);
1162
1163export const modifierProcessorMap: Map<ts.SyntaxKind, ModifierProcessorInterface> = new Map([
1164  [ts.SyntaxKind.ConstKeyword, ModifierHelper.setIsReadonly],
1165  [ts.SyntaxKind.ReadonlyKeyword, ModifierHelper.setIsReadonly],
1166  [ts.SyntaxKind.StaticKeyword, ModifierHelper.setIsStatic],
1167  [ts.SyntaxKind.ExportKeyword, ModifierHelper.setIsExport],
1168]);
1169
1170export const typeMap: Map<ts.SyntaxKind, string> = new Map([
1171  [ts.SyntaxKind.StringLiteral, 'string'],
1172  [ts.SyntaxKind.NumericLiteral, 'number'],
1173]);
1174