• 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 from 'typescript';
17
18import { Comment } from '../../typedef/parser/Comment';
19import { StringConstant } from '../../utils/Constant';
20import {
21  ApiInfo,
22  ApiType,
23  BasicApiInfo,
24  ContainerApiInfo,
25  containerApiTypes,
26  ClassInfo,
27  ConstantInfo,
28  EnumInfo,
29  EnumValueInfo,
30  ExportDeclareInfo,
31  ExportDefaultInfo,
32  ExportImportValue,
33  ImportInfo,
34  InterfaceInfo,
35  MethodInfo,
36  MethodType,
37  ModifierProcessorInterface,
38  ModuleInfo,
39  NamespaceInfo,
40  NodeProcessorInterface,
41  ParamInfo,
42  PropertyInfo,
43  PropertyNode,
44  TypeAliasInfo,
45  TypeAliasType,
46  LocationsAPIType,
47} from '../../typedef/parser/ApiInfoDefination';
48import * as ResultsInfo from '../../typedef/parser/ResultsInfo';
49import { ApiInfosMap, BasicApiInfoMap, FileInfoMap, FilesMap } from './parser';
50
51/**
52 * 处理解析完节点数据的方法
53 */
54export class ResultsProcessHelper {
55  // 如果是字符串的话,会出现单双引号重复的情况
56  static regQuotation: RegExp = /^[\'|\"](.*)[\'|\"]$/;
57  /**
58   * 获取fileMap里的对应的apiinfos
59   *
60   * @param { FileInfoMap } fileMap 文件解析结果
61   * @param { string } apiKey 获取api名称
62   * @return {BasicApiInfo[]} apiInfo
63   */
64  static getApiInfosInFileMap(fileMap: FileInfoMap, apiKey: string): BasicApiInfo[] {
65    if (apiKey === StringConstant.SELF) {
66      return [];
67    }
68    const apiInfoMap: ApiInfosMap = fileMap.get(apiKey) as ApiInfosMap;
69    return apiInfoMap.get(StringConstant.SELF) as BasicApiInfo[];
70  }
71
72  /**
73   * 获取SourceFile节点下的第一层节点解析后的对象
74   *
75   * @param { FileInfoMap } fileMap 获取到的一个文件解析到的map对象
76   * @return {BasicApiInfo[]}  SourceFile节点下的第一层节点解析后的对象
77   */
78  static processFileApiMap(fileMap: FileInfoMap): BasicApiInfo[] {
79    const apis: BasicApiInfo[] = [];
80    for (const apiKey of fileMap.keys()) {
81      const apiInfos: BasicApiInfo[] = ResultsProcessHelper.getApiInfosInFileMap(fileMap, apiKey);
82      apiInfos.forEach((apiInfo: BasicApiInfo) => {
83        ResultsProcessHelper.processApiInfo(apiInfo);
84        apis.push(apiInfo);
85      });
86    }
87    return apis;
88  }
89  /**
90   * 将每一个节点解析后的对象的parentApi属性置为undefined,防止循环引用
91   *
92   * @param { BasicApiInfo } basicApiInfo 解析后的api对象
93   */
94  static processApiInfo(basicApiInfo: BasicApiInfo | undefined): void {
95    if (!basicApiInfo) {
96      return;
97    }
98    ResultsProcessHelper.cleanApiInfo(basicApiInfo);
99    if (!containerApiTypes.has(basicApiInfo.getApiType())) {
100      return;
101    }
102    const containerApiInfo: ContainerApiInfo = basicApiInfo as ContainerApiInfo;
103    containerApiInfo.getChildApis().forEach((childApiInfo: BasicApiInfo) => {
104      ResultsProcessHelper.processApiInfo(childApiInfo);
105    });
106  }
107
108  static cleanApiInfo(basicApiInfo: BasicApiInfo | undefined): void {
109    if (!basicApiInfo) {
110      return;
111    }
112    basicApiInfo.setParentApi(undefined);
113    basicApiInfo.removeNode();
114    if (basicApiInfo instanceof MethodInfo || basicApiInfo instanceof PropertyInfo) {
115      basicApiInfo.setObjLocations([]);
116      basicApiInfo.setTypeLocations([]);
117      if (basicApiInfo instanceof MethodInfo) {
118        basicApiInfo.getParams().forEach((param: ParamInfo) => {
119          param.setObjLocations([]);
120          param.setTypeLocations([]);
121          ResultsProcessHelper.processApiInfo(param.getMethodApiInfo());
122        });
123      }
124    }
125    if (basicApiInfo instanceof TypeAliasInfo) {
126      ResultsProcessHelper.cleanChildrenApiInfo(basicApiInfo.getTypeLiteralApiInfos());
127      basicApiInfo.getParamInfos().forEach((param: ParamInfo) => {
128        param.setObjLocations([]);
129        param.setTypeLocations([]);
130        ResultsProcessHelper.processApiInfo(param.getMethodApiInfo());
131      });
132    }
133    ResultsProcessHelper.processJsDocInfos(basicApiInfo as ApiInfo);
134  }
135
136  static cleanChildrenApiInfo(basicApiInfos: BasicApiInfo[] | undefined): void {
137    if (!basicApiInfos) {
138      return;
139    }
140    basicApiInfos.forEach((basicApiInfos: BasicApiInfo) => {
141      ResultsProcessHelper.processApiInfo(basicApiInfos);
142    });
143  }
144
145  /**
146   * 判断jsdoc节点,去除tag数组
147   *
148   * @param {ApiInfo} apiInfo
149   * @return {void}
150   */
151  static processJsDocInfos(apiInfo: ApiInfo): void {
152    if (!(apiInfo instanceof ApiInfo)) {
153      return;
154    }
155    const jsDocInfos: Comment.JsDocInfo[] = apiInfo.getJsDocInfos();
156    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
157      jsDocInfo.removeTags();
158    });
159  }
160
161  /**
162   * 解析整个文件所有api
163   *
164   * @param {FileInfoMap} fileMap 文件对象
165   * @return {BasicApiInfo[]} 整个文件的所有api
166   */
167  static processFileApiMapForGetBasicApi(fileMap: FileInfoMap): BasicApiInfo[] {
168    let apis: BasicApiInfo[] = [];
169    for (const apiKey of fileMap.keys()) {
170      const apiInfos: BasicApiInfo[] = ResultsProcessHelper.getApiInfosInFileMap(fileMap, apiKey);
171      apiInfos.forEach((apiInfo: BasicApiInfo) => {
172        apis = apis.concat(ResultsProcessHelper.processApiInfoForGetBasicApi(apiInfo));
173      });
174    }
175    return apis;
176  }
177
178  /**
179   * 获取一个api的所有子节点,例如NamespaceInfo | ClassInfo | InterfaceInfo | EnumInfo | ModuleInfo | StructInfo
180   *
181   * @param { BasicApiInfo } basicApiInfo 解析后的api对象
182   * @return { BasicApiInfo[] } 递归获取有子节点的api的所有api
183   */
184  static processApiInfoForGetBasicApi(basicApiInfo: BasicApiInfo): BasicApiInfo[] {
185    let apis: BasicApiInfo[] = [];
186    apis = apis.concat(basicApiInfo);
187    if (!containerApiTypes.has(basicApiInfo.getApiType())) {
188      return apis;
189    }
190    const containerApiInfo: ContainerApiInfo = basicApiInfo as ContainerApiInfo;
191    containerApiInfo.getChildApis().forEach((childApiInfo: BasicApiInfo) => {
192      apis = apis.concat(ResultsProcessHelper.processApiInfoForGetBasicApi(childApiInfo));
193    });
194    return apis;
195  }
196  /**
197   * 获取SourceFile节点下的第一层节点解析后的对象,需要将JsDoc按照since的版本进行拆分
198   * 1、子节点的since必须大于等于父节点的since,小于的进行剔除
199   * 2、一个节点出现多段JsDoc时,将会拆分成多个节点,每个节点包含对应版本的子节点
200   * 3、JsDoc中since默认为-1,可以存在一段没有since的JsDoc
201   * 3、当节点没有JsDoc时设置since默认为-1,其他信息默认
202   *
203   * @param { FileInfoMap } fileMap
204   * @return  { Array<Comment.jsDocEachSince> }
205   */
206  static processFileApiMapForEachSince(fileMap: FileInfoMap): Array<ResultsInfo.BasicApiInfo> {
207    const apis: ResultsInfo.BasicApiInfo[] = [];
208    for (const apiKey of fileMap.keys()) {
209      const apiInfos: BasicApiInfo[] = ResultsProcessHelper.getApiInfosInFileMap(fileMap, apiKey);
210      apiInfos.forEach((apiInfo: BasicApiInfo) => {
211        const api: ResultsInfo.BasicApiInfo[] = ResultsProcessHelper.processApiInfoForEachSince(apiInfo);
212        if (api.length === 0) {
213          return;
214        }
215        apis.push(...api);
216      });
217    }
218    return apis;
219  }
220
221  /**
222   * 获取到文件下每个节点的数据,解析jsdoc中的since信息,根据规则提取出对应数组
223   *
224   * @param {BasicApiInfo} basicApiInfo 一级节点信息
225   * @return {ResultsInfo.BasicApiInfo[]}
226   */
227  static processApiInfoForEachSince(basicApiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
228    const resultApis: ResultsInfo.BasicApiInfo[] = ResultsProcessHelper.getNodeInfo(basicApiInfo);
229    if (!containerApiTypes.has(basicApiInfo.getApiType())) {
230      return resultApis;
231    }
232    const containerApiInfo: ContainerApiInfo = basicApiInfo as ContainerApiInfo;
233    containerApiInfo.getChildApis().forEach((childApiInfo: BasicApiInfo) => {
234      const childApis: ResultsInfo.BasicApiInfo[] = ResultsProcessHelper.processApiInfoForEachSince(childApiInfo);
235      ResultsProcessHelper.mergeResultApis(resultApis, childApis);
236    });
237    return resultApis;
238  }
239
240  /**
241   * 根据父节点和子节点,将子节点中满足父节点的版本要求的数据填充到父节点
242   *
243   * @param {ResultsInfo.BasicApiInfo[]} parentApis 父节点信息,根据jsdoc分段
244   * @param {ResultsInfo.BasicApiInfo[]} childApis 子节点信息,根据jsdoc分段
245   */
246  static mergeResultApis(parentApis: ResultsInfo.BasicApiInfo[], childApis: ResultsInfo.BasicApiInfo[]): void {
247    parentApis.forEach((parentApi: ResultsInfo.BasicApiInfo) => {
248      const containerApiInfo: ResultsInfo.NamespaceEnumInfo = parentApi as ResultsInfo.NamespaceEnumInfo;
249      const cApis: ResultsInfo.BasicApiInfo[] = ResultsProcessHelper.getResultApisVersion(
250        childApis,
251        Number(containerApiInfo.getSince())
252      );
253      containerApiInfo.addChildApi(cApis);
254    });
255  }
256
257  /**
258   * 在多段jsdoc数据中提取符合版本的数据
259   *
260   * @param {ResultsInfo.BasicApiInfo[]} resultApis
261   * @param {number} version
262   * @return {ResultsInfo.BasicApiInfo[]}
263   */
264  static getResultApisVersion(resultApis: ResultsInfo.BasicApiInfo[], version: number): ResultsInfo.BasicApiInfo[] {
265    return resultApis.filter((resultApi: ResultsInfo.BasicApiInfo) => {
266      const apiInfo: ResultsInfo.ApiInfo = resultApi as ResultsInfo.ApiInfo;
267      const since: number = Number(apiInfo.getSince());
268      return since === -1 || since >= version;
269    });
270  }
271
272  /**
273   * 按节点的类型分类处理,拆分多段jsdoc
274   *
275   * @param {BasicApiInfo} apiInfo 节点信息
276   * @return {ResultsInfo.BasicApiInfo[]}
277   */
278  static getNodeInfo(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
279    let apiType: string = apiInfo.getApiType();
280    const nodeProcessor: ResultsInfo.NodeProcessorInterface | undefined = resultsProcessMethod.get(apiType);
281    if (!nodeProcessor) {
282      return [];
283    }
284    const newApiInfos: ResultsInfo.BasicApiInfo[] = nodeProcessor(apiInfo);
285    return newApiInfos;
286  }
287
288  static processProperty(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
289    const infos: ResultsInfo.PropertyInfo[] = [];
290    const propertyInfo: PropertyInfo = apiInfo as PropertyInfo;
291    const jsDocInfos: Comment.JsDocInfo[] = propertyInfo.getJsDocInfos();
292    if (jsDocInfos.length === 0) {
293      const newInfo: ResultsInfo.PropertyInfo = new ResultsInfo.PropertyInfo(
294        apiInfo.getApiType(),
295        new Comment.JsDocInfo()
296      );
297      newInfo.setType(propertyInfo.getType().join(' | '));
298      newInfo.setName(apiInfo.getApiName());
299      newInfo.setIsRequired(propertyInfo.getIsRequired());
300      newInfo.setIsReadOnly(propertyInfo.getIsReadOnly());
301      newInfo.setIsStatic(propertyInfo.getIsStatic());
302      infos.push(newInfo);
303    }
304    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
305      const newInfo: ResultsInfo.PropertyInfo = new ResultsInfo.PropertyInfo(apiInfo.getApiType(), jsDocInfo);
306      const typeInfo: string = jsDocInfo.getTypeInfo();
307      newInfo.setType(typeInfo ? typeInfo.replace(/^[\?]*[\(](.*)[\)]$/, '$1') : propertyInfo.getType().join(' | '));
308      newInfo.setName(apiInfo.getApiName());
309      newInfo.setIsRequired(propertyInfo.getIsRequired());
310      newInfo.setIsReadOnly(propertyInfo.getIsReadOnly());
311      newInfo.setIsStatic(propertyInfo.getIsStatic());
312      infos.push(newInfo);
313    });
314    return infos;
315  }
316
317  static processClass(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
318    const infos: ResultsInfo.ClassInterfaceInfo[] = [];
319    const classInfo: ClassInfo = apiInfo as ClassInfo;
320    const jsDocInfos: Comment.JsDocInfo[] = classInfo.getJsDocInfos();
321    if (jsDocInfos.length === 0) {
322      const newInfo: ResultsInfo.ClassInterfaceInfo = new ResultsInfo.ClassInterfaceInfo(
323        apiInfo.getApiType(),
324        new Comment.JsDocInfo()
325      );
326      newInfo.setName(apiInfo.getApiName());
327      newInfo.setParentClasses(classInfo.getParentClasses());
328      infos.push(newInfo);
329    }
330    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
331      const newInfo: ResultsInfo.ClassInterfaceInfo = new ResultsInfo.ClassInterfaceInfo(
332        apiInfo.getApiType(),
333        jsDocInfo
334      );
335      newInfo.setName(apiInfo.getApiName());
336      newInfo.setParentClasses(classInfo.getParentClasses());
337      infos.push(newInfo);
338    });
339    return infos;
340  }
341
342  static processInterface(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
343    const infos: ResultsInfo.ClassInterfaceInfo[] = [];
344    const interfaceInfo: InterfaceInfo = apiInfo as InterfaceInfo;
345    const jsDocInfos: Comment.JsDocInfo[] = interfaceInfo.getJsDocInfos();
346    if (jsDocInfos.length === 0) {
347      const newInfo: ResultsInfo.ClassInterfaceInfo = new ResultsInfo.ClassInterfaceInfo(
348        apiInfo.getApiType(),
349        new Comment.JsDocInfo()
350      );
351      newInfo.setName(apiInfo.getApiName());
352      newInfo.setParentClasses(interfaceInfo.getParentClasses());
353      infos.push(newInfo);
354    }
355    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
356      const newInfo: ResultsInfo.ClassInterfaceInfo = new ResultsInfo.ClassInterfaceInfo(
357        apiInfo.getApiType(),
358        jsDocInfo
359      );
360      newInfo.setName(apiInfo.getApiName());
361      newInfo.setParentClasses(interfaceInfo.getParentClasses());
362      infos.push(newInfo);
363    });
364    return infos;
365  }
366
367  static processNamespace(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
368    const infos: ResultsInfo.NamespaceEnumInfo[] = [];
369    const interfaceInfo: NamespaceInfo = apiInfo as NamespaceInfo;
370    const jsDocInfos: Comment.JsDocInfo[] = interfaceInfo.getJsDocInfos();
371    if (jsDocInfos.length === 0) {
372      const newInfo: ResultsInfo.NamespaceEnumInfo = new ResultsInfo.NamespaceEnumInfo(
373        apiInfo.getApiType(),
374        new Comment.JsDocInfo()
375      );
376      newInfo.setName(apiInfo.getApiName());
377      infos.push(newInfo);
378    }
379    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
380      const newInfo: ResultsInfo.NamespaceEnumInfo = new ResultsInfo.NamespaceEnumInfo(apiInfo.getApiType(), jsDocInfo);
381      newInfo.setName(apiInfo.getApiName());
382      infos.push(newInfo);
383    });
384    return infos;
385  }
386
387  static processMethod(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
388    const infos: ResultsInfo.MethodInfo[] = [];
389    const methodInfo: MethodInfo = apiInfo as MethodInfo;
390    const jsDocInfos: Comment.JsDocInfo[] = methodInfo.getJsDocInfos();
391    if (jsDocInfos.length === 0) {
392      const newInfo: ResultsInfo.MethodInfo = new ResultsInfo.MethodInfo(apiInfo.getApiType(), new Comment.JsDocInfo());
393      newInfo.setName(apiInfo.getApiName());
394      newInfo.setCallForm(methodInfo.getCallForm());
395      newInfo.setReturnValue(methodInfo.getReturnValue().join(' | '));
396      methodInfo.getParams().forEach((param: ParamInfo) => {
397        const newParam: ResultsInfo.ParamInfo = new ResultsInfo.ParamInfo(param.getApiType(), new Comment.JsDocInfo());
398        newParam.setName(param.getApiName());
399        newParam.setType(param.getType().join(' | '));
400        newParam.setIsRequired(param.getIsRequired());
401        newInfo.addParam(newParam);
402      });
403      newInfo.setIsStatic(methodInfo.getIsStatic());
404      infos.push(newInfo);
405    }
406    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
407      const newInfo: ResultsInfo.MethodInfo = new ResultsInfo.MethodInfo(apiInfo.getApiType(), jsDocInfo);
408      newInfo.setName(apiInfo.getApiName());
409      newInfo.setCallForm(methodInfo.getCallForm());
410      newInfo.setReturnValue(methodInfo.getReturnValue().join(' | '));
411      methodInfo.getParams().forEach((param: ParamInfo) => {
412        const newParam: ResultsInfo.ParamInfo = new ResultsInfo.ParamInfo(param.getApiType(), new Comment.JsDocInfo());
413        newParam.setName(param.getApiName());
414        newParam.setType(param.getType().join(' | '));
415        newParam.setIsRequired(param.getIsRequired());
416        newInfo.addParam(newParam);
417      });
418      newInfo.setIsStatic(methodInfo.getIsStatic());
419      infos.push(newInfo);
420    });
421    return infos;
422  }
423
424  static processExportDefault(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
425    const infos: ResultsInfo.ExportDefaultInfo[] = [];
426    const newInfo: ResultsInfo.ExportDefaultInfo = new ResultsInfo.ExportDefaultInfo(apiInfo.getApiType());
427    newInfo.setName(apiInfo.getApiName());
428    infos.push(newInfo);
429    return infos;
430  }
431
432  static processImportInfo(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
433    const infos: ResultsInfo.ImportInfo[] = [];
434    const importInfo: ImportInfo = apiInfo as ImportInfo;
435    const newInfo: ResultsInfo.ImportInfo = new ResultsInfo.ImportInfo(apiInfo.getApiType());
436    importInfo.getImportValues().forEach((importValue: ExportImportValue) => {
437      newInfo.addImportValue(importValue.key, importValue.value);
438    });
439    infos.push(newInfo);
440    return infos;
441  }
442
443  static processConstant(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
444    const infos: ResultsInfo.ConstantInfo[] = [];
445    const constantInfo: ConstantInfo = apiInfo as ConstantInfo;
446    const jsDocInfos: Comment.JsDocInfo[] = constantInfo.getJsDocInfos();
447    if (jsDocInfos.length === 0) {
448      const newInfo: ResultsInfo.ConstantInfo = new ResultsInfo.ConstantInfo(
449        apiInfo.getApiType(),
450        new Comment.JsDocInfo()
451      );
452      newInfo.setName(apiInfo.getApiName());
453      const value: string = constantInfo.getValue();
454      newInfo.setValue(value.replace(ResultsProcessHelper.regQuotation, '$1'));
455      newInfo.setType(isNaN(Number(value)) ? 'string' : 'number');
456      const declarationNode: ts.VariableDeclaration = constantInfo.getNode() as ts.VariableDeclaration;
457      if (declarationNode.initializer) {
458        const typeOfLiteral: string | undefined = typeMap.get(declarationNode.initializer.kind);
459        newInfo.setType(typeOfLiteral ? typeOfLiteral : '');
460      }
461      infos.push(newInfo);
462    }
463    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
464      const newInfo: ResultsInfo.ConstantInfo = new ResultsInfo.ConstantInfo(apiInfo.getApiType(), jsDocInfo);
465      newInfo.setName(apiInfo.getApiName());
466      const value: string = constantInfo.getValue();
467      newInfo.setValue(value.replace(ResultsProcessHelper.regQuotation, '$1'));
468      newInfo.setType(isNaN(Number(value)) ? 'string' : 'number');
469      const declarationNode: ts.VariableDeclaration = constantInfo.getNode() as ts.VariableDeclaration;
470      if (declarationNode.initializer) {
471        const typeOfLiteral: string | undefined = typeMap.get(declarationNode.initializer.kind);
472        newInfo.setType(typeOfLiteral ? typeOfLiteral : '');
473      }
474      infos.push(newInfo);
475    });
476    return infos;
477  }
478
479  static processDeclareConstant(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
480    const infos: ResultsInfo.DeclareConstInfo[] = [];
481    const constantInfo: ConstantInfo = apiInfo as ConstantInfo;
482    const jsDocInfos: Comment.JsDocInfo[] = constantInfo.getJsDocInfos();
483    if (jsDocInfos.length === 0) {
484      const newInfo: ResultsInfo.DeclareConstInfo = new ResultsInfo.DeclareConstInfo(
485        apiInfo.getApiType(),
486        new Comment.JsDocInfo()
487      );
488      newInfo.setName(apiInfo.getApiName());
489      newInfo.setType(constantInfo.getValue());
490      const declarationNode: ts.VariableDeclaration = constantInfo.getNode() as ts.VariableDeclaration;
491      if (declarationNode.initializer) {
492        const typeOfLiteral: string | undefined = typeMap.get(declarationNode.initializer.kind);
493        newInfo.setType(typeOfLiteral ? typeOfLiteral : '');
494      }
495      infos.push(newInfo);
496    }
497    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
498      const newInfo: ResultsInfo.DeclareConstInfo = new ResultsInfo.DeclareConstInfo(apiInfo.getApiType(), jsDocInfo);
499      newInfo.setName(apiInfo.getApiName());
500      newInfo.setType(constantInfo.getValue());
501      const declarationNode: ts.VariableDeclaration = constantInfo.getNode() as ts.VariableDeclaration;
502      if (declarationNode.initializer) {
503        const typeOfLiteral: string | undefined = typeMap.get(declarationNode.initializer.kind);
504        newInfo.setType(typeOfLiteral ? typeOfLiteral : '');
505      }
506      infos.push(newInfo);
507    });
508    return infos;
509  }
510
511  static processEnum(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
512    const infos: ResultsInfo.NamespaceEnumInfo[] = [];
513    const enumInfo: EnumInfo = apiInfo as EnumInfo;
514    const jsDocInfos: Comment.JsDocInfo[] = enumInfo.getJsDocInfos();
515    if (jsDocInfos.length === 0) {
516      const newInfo: ResultsInfo.NamespaceEnumInfo = new ResultsInfo.NamespaceEnumInfo(
517        apiInfo.getApiType(),
518        new Comment.JsDocInfo()
519      );
520      newInfo.setName(apiInfo.getApiName());
521      infos.push(newInfo);
522    }
523    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
524      const newInfo: ResultsInfo.NamespaceEnumInfo = new ResultsInfo.NamespaceEnumInfo(apiInfo.getApiType(), jsDocInfo);
525      newInfo.setName(apiInfo.getApiName());
526      infos.push(newInfo);
527    });
528    return infos;
529  }
530
531  static processEnumMember(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
532    const infos: ResultsInfo.EnumValueInfo[] = [];
533    const enumValueInfo: EnumValueInfo = apiInfo as EnumValueInfo;
534    const jsDocInfos: Comment.JsDocInfo[] = enumValueInfo.getJsDocInfos();
535    if (jsDocInfos.length === 0) {
536      const newInfo: ResultsInfo.EnumValueInfo = new ResultsInfo.EnumValueInfo(
537        apiInfo.getApiType(),
538        new Comment.JsDocInfo()
539      );
540      newInfo.setName(apiInfo.getApiName());
541      newInfo.setValue(enumValueInfo.getValue());
542      infos.push(newInfo);
543    }
544    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
545      const newInfo: ResultsInfo.EnumValueInfo = new ResultsInfo.EnumValueInfo(apiInfo.getApiType(), jsDocInfo);
546      newInfo.setName(apiInfo.getApiName());
547      newInfo.setValue(enumValueInfo.getValue());
548      infos.push(newInfo);
549    });
550    return infos;
551  }
552
553  static processTypeAlias(apiInfo: BasicApiInfo): ResultsInfo.BasicApiInfo[] {
554    const infos: ResultsInfo.BasicApiInfo[] = [];
555    const typeAliasInfo: TypeAliasInfo = apiInfo as TypeAliasInfo;
556    const jsDocInfos: Comment.JsDocInfo[] = typeAliasInfo.getJsDocInfos();
557    if (jsDocInfos.length === 0) {
558      const newInfo: ResultsInfo.BasicApiInfo = ResultsProcessHelper.processTypeAliasGetNewInfo(
559        typeAliasInfo,
560        new Comment.JsDocInfo()
561      );
562      infos.push(newInfo);
563    }
564    jsDocInfos.forEach((jsDocInfo: Comment.JsDocInfo) => {
565      const newInfo: ResultsInfo.BasicApiInfo = ResultsProcessHelper.processTypeAliasGetNewInfo(
566        typeAliasInfo,
567        jsDocInfo
568      );
569      infos.push(newInfo);
570    });
571    return infos;
572  }
573  static processTypeAliasGetNewInfo(
574    typeAliasInfo: TypeAliasInfo,
575    jsDocInfo: Comment.JsDocInfo
576  ): ResultsInfo.BasicApiInfo {
577    if (typeAliasInfo.getTypeName() === TypeAliasType.UNION_TYPE) {
578      const newInfo: ResultsInfo.UnionTypeInfo = new ResultsInfo.UnionTypeInfo(typeAliasInfo.getTypeName(), jsDocInfo);
579      newInfo.setName(typeAliasInfo.getApiName());
580      newInfo.addValueRanges(
581        typeAliasInfo.getType().map((type: string) => {
582          return type.replace(ResultsProcessHelper.regQuotation, '$1');
583        })
584      );
585      return newInfo;
586    }
587    const newInfo: ResultsInfo.TypeAliasInfo = new ResultsInfo.TypeAliasInfo(typeAliasInfo.getApiType(), jsDocInfo);
588    newInfo.setName(typeAliasInfo.getApiName());
589    newInfo.setType(typeAliasInfo.getType().join(' | '));
590    return newInfo;
591  }
592}
593
594const typeMap: Map<ts.SyntaxKind, string> = new Map([
595  [ts.SyntaxKind.StringLiteral, 'string'],
596  [ts.SyntaxKind.NumericLiteral, 'number'],
597]);
598
599/**
600 * api节点类型对应的处理方法,获取diff信息
601 */
602export const resultsProcessMethod: Map<string, ResultsInfo.NodeProcessorInterface> = new Map([
603  [ApiType.PROPERTY, ResultsProcessHelper.processProperty],
604  [ApiType.CLASS, ResultsProcessHelper.processClass],
605  [ApiType.INTERFACE, ResultsProcessHelper.processInterface],
606  [ApiType.NAMESPACE, ResultsProcessHelper.processNamespace],
607  [ApiType.METHOD, ResultsProcessHelper.processMethod],
608  // [ApiType.PARAM, ResultsProcessHelper.processParam],
609  // [ApiType.MODULE, ResultsProcessHelper.processModule],
610  // [ApiType.EXPORT, ResultsProcessHelper.processExport],
611  [ApiType.EXPORT_DEFAULT, ResultsProcessHelper.processExportDefault],
612  [ApiType.IMPORT, ResultsProcessHelper.processImportInfo],
613  [ApiType.CONSTANT, ResultsProcessHelper.processConstant],
614  [ApiType.DECLARE_CONST, ResultsProcessHelper.processDeclareConstant],
615  [ApiType.ENUM, ResultsProcessHelper.processEnum],
616  [ApiType.ENUM_VALUE, ResultsProcessHelper.processEnumMember],
617  [ApiType.TYPE_ALIAS, ResultsProcessHelper.processTypeAlias],
618]);
619