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