1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import type ts from 'typescript'; 17 18export class JsDocInfo { 19 syscap: string = ''; // api的系统能力 20 since: number = -1; // api的起始版本 21 isForm: boolean = false; // api是否支持卡片应用 22 isCrossPlatForm: boolean = false; // api是否支持跨平台 23 isSystemApi: boolean = false; // api是否是系统api 24 isStageModelOnly: boolean = false; // api是否仅Stage模型可用 25 isFaModelOnly: boolean = false; // api是否仅FA模型可用 26 deprecatedVersion: number = -1; // api的废弃版本 27 useinstead: string = ''; // api的替换接口 28 permission: string = ''; 29 errorCodes: number[] = []; 30 typeInfo: string = ''; 31 isConstant: boolean = false; 32 33 constructor() { } 34 35 setSyscap(syscap?: string): void { 36 if (!syscap) { 37 return; 38 } 39 this.syscap = syscap; 40 } 41 42 getSyscap(): string { 43 return this.syscap; 44 } 45 46 setSince(since: number): void { 47 this.since = since; 48 } 49 50 getSince(): number { 51 return this.since; 52 } 53 54 setIsForm(): void { 55 this.isForm = true; 56 } 57 58 getIsForm(): boolean { 59 return this.isForm; 60 } 61 62 setIsCrossPlatForm(): void { 63 this.isCrossPlatForm = true; 64 } 65 66 getIsCrossPlatForm(): boolean { 67 return this.isCrossPlatForm; 68 } 69 70 setIsSystemApi(): void { 71 this.isSystemApi = true; 72 } 73 74 getIsSystemApi(): boolean { 75 return this.isSystemApi; 76 } 77 78 setIsStageModelOnly(): void { 79 this.isStageModelOnly = true; 80 } 81 82 getIsStageModelOnly(): boolean { 83 return this.isStageModelOnly; 84 } 85 86 setIsFaModelOnly(): void { 87 this.isFaModelOnly = true; 88 } 89 90 getIsFaModelOnly(): boolean { 91 return this.isFaModelOnly; 92 } 93 94 setDeprecatedVersion(deprecatedVersion: number): void { 95 this.deprecatedVersion = deprecatedVersion; 96 } 97 98 getDeprecatedVersion(): number { 99 return this.deprecatedVersion; 100 } 101 102 setUseinstead(useinstead: string): void { 103 this.useinstead = useinstead; 104 } 105 106 getUseinstead(): string { 107 return this.useinstead; 108 } 109 110 setPermission(permission: string): void { 111 this.permission = permission; 112 } 113 114 getPermission(): string { 115 return this.permission; 116 } 117 118 addErrorCode(errorCode: number): void { 119 this.errorCodes.push(errorCode); 120 } 121 122 getErrorCode(): number[] { 123 return this.errorCodes; 124 } 125 126 setTypeInfo(typeInfo: string): void { 127 this.typeInfo = typeInfo; 128 } 129 130 getTypeInfo(): string { 131 return this.typeInfo; 132 } 133 134 setIsConstant(): void { 135 this.isConstant = true; 136 } 137 138 getIsConstant(): boolean { 139 return this.isConstant; 140 } 141 142} 143 144 145export class BasicApiInfo { 146 apiType: string = ''; // api 类型 147 constructor(apiType: string) { 148 this.apiType = apiType; 149 } 150} 151 152export class ApiInfo extends BasicApiInfo { 153 name: string = ''; // api的名称 154 syscap: string = ''; // api的系统能力 155 since: number = -1; // api的起始版本 156 isForm: boolean = false; // api是否支持卡片应用 157 isCrossPlatForm: boolean = false; // api是否支持跨平台 158 isSystemApi: boolean = false; // api是否是系统api 159 isStageModelOnly: boolean = false; // api是否仅Stage模型可用 160 isFaModelOnly: boolean = false; // api是否仅FA模型可用 161 deprecatedVersion: number = -1; // api的废弃版本 162 useinstead: string = ''; // api的替换接口 163 164 constructor(apiType: string, jsDocInfo: JsDocInfo) { 165 super(apiType); 166 this.setJsDocInfo(jsDocInfo); 167 } 168 169 setJsDocInfo(jsDocInfo: JsDocInfo): void { 170 this.syscap = jsDocInfo.getSyscap(); 171 this.since = jsDocInfo.getSince(); 172 this.isForm = jsDocInfo.getIsForm(); 173 this.isCrossPlatForm = jsDocInfo.getIsCrossPlatForm(); 174 this.isSystemApi = jsDocInfo.getIsSystemApi(); 175 this.isStageModelOnly = jsDocInfo.getIsStageModelOnly(); 176 this.isFaModelOnly = jsDocInfo.getIsFaModelOnly(); 177 this.deprecatedVersion = jsDocInfo.getDeprecatedVersion(); 178 this.useinstead = jsDocInfo.getUseinstead(); 179 } 180 181 setName(name: string | undefined): void { 182 if (!name) { 183 return; 184 } 185 this.name = name; 186 } 187 188} 189 190export class DeclareConstInfo extends ApiInfo { 191 type: string = ''; 192 193 setType(type: string): void { 194 this.type = type; 195 } 196} 197 198export class PropertyInfo extends ApiInfo { 199 type: string = ''; 200 isReadOnly: boolean = false; 201 isRequired: boolean = false; 202 isStatic: boolean = false; 203 permission: string = ''; 204 205 constructor(apiType: string, jsDocInfo: JsDocInfo) { 206 super(apiType, jsDocInfo); 207 this.setPermission(jsDocInfo.getPermission()); 208 } 209 210 setType(type: string): void { 211 this.type = type; 212 } 213 214 setIsReadOnly(): void { 215 this.isReadOnly = true; 216 } 217 218 setIsRequired(isRequired: boolean): void { 219 this.isRequired = isRequired; 220 } 221 222 setIsStatic(): void { 223 this.isStatic = true; 224 } 225 226 setPermission(permission: string): void { 227 this.permission = permission; 228 } 229} 230 231export class ConstantInfo extends ApiInfo { 232 type: string = ''; 233 value: string = ''; 234 235 setType(type: string): void { 236 this.type = type; 237 } 238 239 setValue(value: string): void { 240 this.value = value; 241 } 242} 243 244export class UnionTypeInfo extends ApiInfo { 245 valueRange: string[] = []; 246 247 addValueRange(value: string): void { 248 this.valueRange.push(value); 249 } 250} 251 252export class EnumValueInfo extends ApiInfo { 253 value: string = ''; 254 255 setValue(value: string): void { 256 this.value = value; 257 } 258} 259 260export class TypeAliasInfo extends ApiInfo { 261 type: string = ''; 262 263 setType(type: string): void { 264 this.type = type; 265 } 266} 267 268export class MethodInfo extends ApiInfo { 269 callForm: string = ''; 270 params: ParamInfo[] = []; 271 returnValue: string = ''; 272 isStatic: boolean = false; 273 permission: string = ''; 274 errorCodes: number[] = []; 275 276 constructor(apiType: string, jsDocInfo: JsDocInfo) { 277 super(apiType, jsDocInfo); 278 this.setPermission(jsDocInfo.getPermission()); 279 this.setErrorCodes(jsDocInfo.getErrorCode()); 280 } 281 282 setCallForm(callForm: string): void { 283 this.callForm = callForm; 284 } 285 286 addParam(paramInfo: ParamInfo): void { 287 this.params.push(paramInfo); 288 } 289 290 setReturnValue(returnValue: string): void { 291 this.returnValue = returnValue; 292 } 293 294 setIsStatic(): void { 295 this.isStatic = true; 296 } 297 298 setPermission(permission: string): void { 299 this.permission = permission; 300 } 301 302 setErrorCodes(errorCodes: number[]): void { 303 this.errorCodes.push(...errorCodes); 304 } 305} 306 307export class ParamInfo extends ApiInfo { 308 type: string = ''; 309 isRequired: boolean = false; 310 311 setType(type: string | undefined): void { 312 if (!type) { 313 return; 314 } 315 this.type = type; 316 } 317 318 setIsRequired(isRequired: boolean): void { 319 this.isRequired = isRequired; 320 } 321} 322 323export class NamespaceEnumInfo extends ApiInfo { 324 childApis: BasicApiInfo[] = []; 325 326 addChildApi(childApis: BasicApiInfo[]): void { 327 this.childApis.push(...childApis); 328 } 329} 330 331export class ClassInterfaceInfo extends NamespaceEnumInfo { 332 parentClasses: string[] = []; 333 334 setParentClasses(parentClasses: string[]): void { 335 this.parentClasses.push(...parentClasses); 336 } 337} 338 339export class ExportDefaultInfo extends BasicApiInfo { 340 name: string = ''; 341 342 createObject(): ExportDefaultInfo { 343 return new ExportDefaultInfo(this.apiType); 344 } 345 346 setName(name: string): void { 347 this.name = name; 348 } 349} 350 351export class ImportInfo extends BasicApiInfo { 352 importValues: string[] = []; 353 354 addImportValue(value: string | undefined): void { 355 if (!value) { 356 return; 357 } 358 this.importValues.push(value); 359 } 360} 361 362export interface JsDocProcessorInterface { 363 (jsDocInfo: JsDocInfo, option?: string): void; 364} 365 366export interface ModifierProcessorInterface { 367 (propertyInfo: PropertyInfo | MethodInfo): void; 368} 369 370export class Options { 371 isConstant: boolean = false; 372 value: string = ''; 373 jsDocInfo: JsDocInfo = new JsDocInfo(); 374 375 constructor() { } 376 377 setIsConstant(isConstant: boolean): void { 378 this.isConstant = isConstant; 379 } 380 381 getIsConstant(): boolean { 382 return this.isConstant; 383 } 384 385 setValue(value: string): void { 386 this.value = value; 387 } 388 389 getValue(): string { 390 return this.value; 391 } 392 393 setJsDocInfo(jsDocInfo: JsDocInfo): void { 394 this.jsDocInfo = jsDocInfo; 395 } 396 397 getJsDocInfo(): JsDocInfo { 398 return this.jsDocInfo; 399 } 400} 401 402export interface NodeProcessorInterface { 403 (node: ts.Node, jsDocInfo: JsDocInfo, option?: Options): BasicApiInfo; 404} 405 406 407export enum JsDocTag { 408 SYSCAP = 'syscap', 409 SINCE = 'since', 410 FORM = 'form', 411 CROSS_PLAT_FORM = 'crossplatform', 412 SYSTEM_API = 'systemapi', 413 STAGE_MODEL_ONLY = 'stagemodelonly', 414 FA_MODEL_ONLY = 'famodelonly', 415 DEPRECATED = 'deprecated', 416 USEINSTEAD = 'useinstead', 417 TYPE = 'type', 418 CONSTANT = 'constant', 419 PERMISSION = 'permission', 420 THROWS = 'throws', 421} 422 423export enum ApiType { 424 PROPERTY = 'property', 425 CLASS = 'class', 426 INTERFACE = 'interface', 427 NAMESPACE = 'namespace', 428 METHOD = 'method', 429 EXPORT_DEFAULT = 'exportDefault', 430 CONSTANT = 'constant', 431 IMPORT = 'import', 432 DECLARE_CONST = 'declareConst', 433 UNIONTYPE = 'unionType', 434 ENUM_VALUE = 'enumValue', 435 TYPE_ALIAS = 'typeAlias', 436 PARAM = 'param', 437 ENUM = 'enum' 438} 439 440export type PropertyNode = ts.PropertyDeclaration | ts.PropertySignature; 441 442export type MethodType = ts.MethodDeclaration | ts.MethodSignature | ts.FunctionDeclaration | ts.CallSignatureDeclaration; 443 444export namespace comment { 445 /** 446 * 注释信息 447 */ 448 export interface CommentInfo { 449 450 /** 451 * 原始注释文本 452 */ 453 text: string; 454 455 /** 456 * 是否为多行注释 457 */ 458 isMultiLine: boolean; 459 460 /** 461 * true为头注释,false为未注释 462 */ 463 isLeading: boolean; 464 465 /** 466 * 注释描述 467 */ 468 description: string; 469 470 /** 471 * 注释标签列表 472 */ 473 commentTags: Array<CommentTag>; 474 475 /** 476 * 结构化的注释对象 477 */ 478 parsedComment: any; 479 480 /** 481 * 注释起始位置 482 */ 483 pos: number; 484 485 /** 486 * 注释结束位置 487 */ 488 end: number; 489 490 /** 491 * 是否忽略此注释 492 */ 493 ignore: boolean; 494 495 /** 496 * 是否是api注释 497 */ 498 isApiComment: boolean, 499 500 /** 501 * 是否为特殊日志。例如,为了增加空行而添加的特殊单行日志。 502 */ 503 isInstruct: boolean; 504 } 505 506 export interface CommentTag { 507 508 /** 509 * 注释标签,例如 @param 510 */ 511 tag: string; 512 513 /** 514 * 标签名称, 例如 @param name 515 */ 516 name: string; 517 518 /** 519 * 类型, 例如 @param { type } name 520 */ 521 type: string; 522 523 /** 524 * 是否可选 525 */ 526 optional: boolean; 527 528 /** 529 * 描述 530 */ 531 description: string; 532 533 /** 534 * 默认值 535 */ 536 defaultValue?: string; 537 538 /** 539 * 原始注释内容 540 */ 541 source: string; 542 543 /** 544 * 行号 545 */ 546 lineNumber: number; 547 548 /** 549 * tag 的描述可能有多行, 首行包含tag信息,其余包含tag的描述信息。 550 */ 551 tokenSource: Array<comment.CommentSource>; 552 } 553 554 export interface CommentSource { 555 556 /** 557 * 行号 558 */ 559 number: number; 560 561 /** 562 * 原始注释行 563 */ 564 source: string; 565 566 /** 567 * 注释被拆分后的对象 568 */ 569 tokens: CommentToken; 570 } 571 572 /** 573 * 注释被拆分为以下部分: 574 * |start|delimiter|postDelimiter|tag|postTag|name|postName|type|postType|description|end\ 575 */ 576 export interface CommentToken { 577 578 /** 579 * 注释每行起始字符 580 */ 581 start: string; 582 583 /** 584 * 注释行开始定界符 585 */ 586 delimiter: string; 587 588 /** 589 * 定界符之后的字符 590 */ 591 postDelimiter: string; 592 593 /** 594 * 标签 595 */ 596 tag: string; 597 598 /** 599 * 标签之后的字符 600 */ 601 postTag: string; 602 603 /** 604 * 标签名称 605 */ 606 name: string; 607 608 /** 609 * 标签后的字符 610 */ 611 postName: string; 612 613 /** 614 * 类型 615 */ 616 type: string; 617 618 /** 619 * 类型后的字符 620 */ 621 postType: string; 622 623 /** 624 * 描述 625 */ 626 description: string; 627 628 /** 629 * 结束字符 630 */ 631 end: string; 632 633 /** 634 * 行结束字符 635 */ 636 lineEnd: string; 637 } 638 639}