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 { ErrorTagFormat, ErrorMessage, PermissionData } from '../../../typedef/checker/result_type'; 17import { Comment } from '../../../typedef/parser/Comment'; 18import { CommonFunctions } from '../../../utils/checkUtils'; 19import { ApiInfo, ApiType, ClassInfo, GenericInfo, TypeAliasInfo, TypeAliasType, TypeParamInfo } from '../../../typedef/parser/ApiInfoDefination'; 20import { MethodInfo, PropertyInfo, ParamInfo } from '../../../typedef/parser/ApiInfoDefination'; 21import { PunctuationMark } from '../../../utils/Constant'; 22import { SystemCapability } from '../config/syscapConfigFile.json'; 23import { module } from '../config/permissionConfigFile.json'; 24 25export class TagValueCheck { 26 /** 27 * all jsdoc tag value check 28 * @param { ApiInfo } singleApi 29 * @param { Comment.JsDocInfo } apiJsdoc 30 * @returns { ErrorTagFormat[] } 31 */ 32 static tagValueCheck(singleApi: ApiInfo, apiJsdoc: Comment.JsDocInfo): ErrorTagFormat[] { 33 const tagValueError: ErrorTagFormat[] = []; 34 const tagsName: Comment.CommentTag[] | undefined = apiJsdoc.tags; 35 let throwsIndex: number = 0; 36 let paramIndex: number = -1; 37 if (tagsName === undefined) { 38 return tagValueError; 39 } 40 const tagsTag: string[] = []; 41 tagsName.forEach((tagName: Comment.CommentTag) => { tagsTag.push(tagName.tag); }); 42 const isDeprecated: boolean = tagsTag.includes('deprecated'); 43 tagsName.forEach((tag) => { 44 let errorTagInfo: ErrorTagFormat = { 45 state: true, 46 errorInfo: '', 47 }; 48 switch (tag.tag) { 49 case 'since': 50 errorTagInfo = TagValueCheck.sinceTagValueCheck(tag); 51 break; 52 case 'extends': 53 case 'implements': 54 errorTagInfo = !isDeprecated ? TagValueCheck.extendsTagValueCheck(singleApi, tag) : errorTagInfo; 55 break; 56 case 'enum': 57 errorTagInfo = !isDeprecated ? TagValueCheck.enumTagValueCheck(tag) : errorTagInfo; 58 break; 59 case 'returns': 60 errorTagInfo = !isDeprecated ? TagValueCheck.returnsTagValueCheck(singleApi, tag) : errorTagInfo; 61 break; 62 case 'namespace': 63 case 'typedef': 64 case 'struct': 65 errorTagInfo = !isDeprecated ? TagValueCheck.outerTagValueCheck(singleApi as ClassInfo, tag) : errorTagInfo; 66 break; 67 case 'type': 68 errorTagInfo = !isDeprecated ? TagValueCheck.typeTagValueCheck(singleApi, tag) : errorTagInfo; 69 break; 70 case 'syscap': 71 errorTagInfo = TagValueCheck.syscapTagValueCheck(tag); 72 break; 73 case 'default': 74 errorTagInfo = !isDeprecated ? TagValueCheck.defaultTagValueCheck(tag) : errorTagInfo; 75 break; 76 case 'deprecated': 77 errorTagInfo = TagValueCheck.deprecatedTagValueCheck(tag); 78 break; 79 case 'permission': 80 errorTagInfo = !isDeprecated ? TagValueCheck.permissionTagValueCheck(tag) : errorTagInfo; 81 break; 82 case 'throws': 83 if (singleApi.getLastJsDocInfo()?.deprecatedVersion === '-1') { 84 throwsIndex += 1; 85 errorTagInfo = !isDeprecated ? TagValueCheck.throwsTagValueCheck(tag, throwsIndex, tagsName) : errorTagInfo; 86 } 87 break; 88 case 'param': 89 paramIndex += 1; 90 errorTagInfo = !isDeprecated ? TagValueCheck.paramTagValueCheck(singleApi, tag, paramIndex) : errorTagInfo; 91 break; 92 case 'useinstead': 93 errorTagInfo = TagValueCheck.useinsteadTagValueCheck(tag); 94 break; 95 default: 96 break; 97 } 98 if (!errorTagInfo.state) { 99 tagValueError.push(errorTagInfo); 100 } 101 }); 102 return tagValueError; 103 } 104 105 /** 106 * since tag value check 107 * @param { Comment.CommentTag } tag 108 * @returns { ErrorTagFormat } 109 */ 110 static sinceTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 111 const sinceValueCheckResult: ErrorTagFormat = { 112 state: true, 113 errorInfo: '', 114 }; 115 const sinceValue: string = CommonFunctions.getSinceVersion(tag.name); 116 const sinceValueIsNumber: boolean = /^\d+$/.test(sinceValue); 117 118 if (!sinceValueIsNumber) { 119 sinceValueCheckResult.state = false; 120 sinceValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_SINCE; 121 } 122 return sinceValueCheckResult; 123 } 124 125 /** 126 * extends tag value check 127 * @param { ApiInfo } singleApi 128 * @param { Comment.CommentTag } tag 129 * @returns { ErrorTagFormat } 130 */ 131 static extendsTagValueCheck(singleApi: ApiInfo, tag: Comment.CommentTag): ErrorTagFormat { 132 const extendsValueCheckResult: ErrorTagFormat = { 133 state: true, 134 errorInfo: '', 135 }; 136 let extendsTagValue: string = tag.name; 137 if (singleApi.getApiType() === ApiType.CLASS || singleApi.getApiType() === ApiType.INTERFACE) { 138 const extendsApiValue: string = CommonFunctions.getExtendsApiValue(singleApi); 139 const ImplementsApiValue: string = CommonFunctions.getImplementsApiValue(singleApi); 140 if (tag.tag === 'extends' && extendsTagValue !== extendsApiValue) { 141 extendsValueCheckResult.state = false; 142 extendsValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_EXTENDS; 143 } 144 if (tag.tag === 'implements' && extendsTagValue !== ImplementsApiValue) { 145 extendsValueCheckResult.state = false; 146 extendsValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_IMPLEMENTS; 147 } 148 } 149 return extendsValueCheckResult; 150 } 151 152 /** 153 * enum tag value check 154 * @param { Comment.CommentTag } tag 155 * @returns { ErrorTagFormat } 156 */ 157 static enumTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 158 const enumValueCheckResult: ErrorTagFormat = { 159 state: true, 160 errorInfo: '', 161 }; 162 const enumValues = ['string', 'number']; 163 if (enumValues.indexOf(tag.type) === -1) { 164 enumValueCheckResult.state = false; 165 enumValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_ENUM; 166 } 167 return enumValueCheckResult; 168 } 169 170 /** 171 * retuens tag value check 172 * @param { ApiInfo } singleApi 173 * @param { Comment.CommentTag } tag 174 * @returns { ErrorTagFormat } 175 */ 176 static returnsTagValueCheck(singleApi: ApiInfo, tag: Comment.CommentTag): ErrorTagFormat { 177 const returnsValueCheckResult: ErrorTagFormat = { 178 state: true, 179 errorInfo: '', 180 }; 181 const returnsTagValue: string = tag.type.replace(/\s/g, ''); 182 let returnsApiValue: string[] = []; 183 const legalApiArr: string[] = [ApiType.METHOD, ApiType.TYPE_ALIAS]; 184 if (!legalApiArr.includes(singleApi.getApiType())) { 185 return returnsValueCheckResult; 186 } 187 const spacealCase: string[] = CommonFunctions.judgeSpecialCase((singleApi as MethodInfo).returnValueType); 188 if (singleApi.getApiType() === ApiType.TYPE_ALIAS) { 189 returnsApiValue.push((singleApi as TypeAliasInfo).getReturnType()); 190 } else { 191 returnsApiValue = spacealCase.length > 0 ? spacealCase : (singleApi as MethodInfo).getReturnValue(); 192 } 193 194 if (returnsApiValue.length === 0) { 195 returnsValueCheckResult.state = false; 196 returnsValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_RETURNS; 197 } else if (returnsTagValue !== returnsApiValue.join('|').replace(/\s/g, '')) { 198 returnsValueCheckResult.state = false; 199 returnsValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_RETURNS; 200 } 201 return returnsValueCheckResult; 202 } 203 204 /** 205 * namespace tag value check 206 * @param { ClassInfo } singleApi 207 * @param { Comment.CommentTag } tag 208 * @returns { ErrorTagFormat } 209 */ 210 static outerTagValueCheck(singleApi: ClassInfo, tag: Comment.CommentTag): ErrorTagFormat { 211 const outerValueCheckResult: ErrorTagFormat = { 212 state: true, 213 errorInfo: '', 214 }; 215 let tagValue: string = tag.name; 216 let tagType: string = tag.type; 217 let apiValue: string = singleApi.getApiName(); 218 const definedText: string = singleApi.getDefinedText(); 219 if (tag.tag === 'namespace' && tagValue !== apiValue) { 220 outerValueCheckResult.state = false; 221 outerValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_NAMESPACE; 222 } 223 if (tag.tag === 'typedef') { 224 if (singleApi.getApiType() === ApiType.TYPE_ALIAS) { 225 const ordinaryTagValue: string = (singleApi as ApiInfo as TypeAliasInfo).getType().join('|').replace(/\s/g, ''); 226 const typeIsFuction: boolean = (singleApi as ApiInfo as TypeAliasInfo).getTypeIsFunction(); 227 const typeIsObject: boolean = (singleApi as ApiInfo as TypeAliasInfo).getTypeName() === TypeAliasType.OBJECT_TYPE; 228 apiValue = typeIsFuction ? 'function' : typeIsObject ? 'object' : ordinaryTagValue; 229 } else { 230 const genericArr: GenericInfo[] = singleApi.getGenericInfo(); 231 if (genericArr.length > 0) { 232 let genericInfo = genericArr.map((generic) => { 233 return generic.getGenericContent(); 234 }).join(','); 235 apiValue = apiValue + '<' + genericInfo + '>'; 236 } 237 } 238 if (singleApi.getApiType() === 'Interface' && tagValue !== apiValue) { 239 outerValueCheckResult.state = false; 240 outerValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_TYPEDEF; 241 } else if (singleApi.getApiType() === ApiType.TYPE_ALIAS && !singleApi.getIsExport() && 242 tagType.replace(/\s/g, '') !== apiValue) { 243 outerValueCheckResult.state = false; 244 outerValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_TYPEDEF; 245 } 246 } 247 if (tag.tag === 'struct' && tagType !== apiValue) { 248 outerValueCheckResult.state = false; 249 outerValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_STRUCT; 250 } 251 return outerValueCheckResult; 252 } 253 254 /** 255 * type tag value check 256 * @param { ApiInfo } singleApi 257 * @param { Comment.CommentTag } tag 258 * @returns { ErrorTagFormat } 259 */ 260 static typeTagValueCheck(singleApi: ApiInfo, tag: Comment.CommentTag): ErrorTagFormat { 261 const typeValueCheckResult: ErrorTagFormat = { 262 state: true, 263 errorInfo: '', 264 }; 265 if (singleApi.getApiType() !== ApiType.PROPERTY) { 266 return typeValueCheckResult; 267 } 268 let typeTagValue: string = tag.type.replace(/\s/g, ''); 269 let typeApiValue: string[] = []; 270 const spacealCase: string[] = CommonFunctions.judgeSpecialCase((singleApi as PropertyInfo).typeKind); 271 if (spacealCase.length > 0) { 272 typeApiValue = spacealCase; 273 } else { 274 typeApiValue = (singleApi as PropertyInfo).type; 275 } 276 277 let typeApiUnionValue: string = typeApiValue.join('|').replace(/\s/g, ''); 278 const isOptional: boolean = !(singleApi as PropertyInfo).getIsRequired(); 279 if (isOptional && typeApiValue.length === 1) { 280 typeApiUnionValue = '?' + typeApiUnionValue; 281 } else if (isOptional && typeApiValue.length > 1) { 282 typeApiUnionValue = '?(' + typeApiUnionValue + ')'; 283 } 284 if (typeTagValue.replace(/\s/g, '') !== typeApiUnionValue.replace(/\s/g, '')) { 285 typeValueCheckResult.state = false; 286 typeValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_TYPE; 287 } 288 return typeValueCheckResult; 289 } 290 /** 291 * syacap tag value check 292 * @param { Comment.CommentTag } tag 293 * @returns { ErrorTagFormat } 294 */ 295 static syscapTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 296 const syscapValueCheckResult: ErrorTagFormat = { 297 state: true, 298 errorInfo: '', 299 }; 300 const syscapRule: string[] = SystemCapability; 301 const syscapTagValue: string = tag.name; 302 if (!syscapRule.includes(syscapTagValue)) { 303 syscapValueCheckResult.state = false; 304 syscapValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_SYSCAP; 305 } 306 return syscapValueCheckResult; 307 } 308 /** 309 * default tag value check 310 * @param { Comment.CommentTag } tag 311 * @returns { ErrorTagFormat } 312 */ 313 static defaultTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 314 const defaultValueCheckResult: ErrorTagFormat = { 315 state: true, 316 errorInfo: '', 317 }; 318 const defaultTagValue: string = tag.name + tag.type; 319 if (defaultTagValue.length === 0) { 320 defaultValueCheckResult.state = false; 321 defaultValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_DEFAULT; 322 } 323 return defaultValueCheckResult; 324 } 325 326 /** 327 * deprecated tag value check 328 * @param { Comment.CommentTag } tag 329 * @returns { ErrorTagFormat } 330 */ 331 static deprecatedTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 332 const deprecatedValueCheckResult: ErrorTagFormat = { 333 state: true, 334 errorInfo: '', 335 }; 336 const deprecatedFixedField: string = tag.name; 337 338 const deprecatedVersion: string = CommonFunctions.getSinceVersion(tag.description); 339 const isNumber: boolean = /^\d+$/.test(deprecatedVersion); 340 if (deprecatedFixedField !== 'since' || !isNumber) { 341 deprecatedValueCheckResult.state = false; 342 deprecatedValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_DEPRECATED; 343 } 344 return deprecatedValueCheckResult; 345 } 346 /** 347 * permission tag value check 348 * @param { Comment.CommentTag } tag 349 * @returns { ErrorTagFormat } 350 */ 351 static permissionTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 352 const permissionValueCheckResult: ErrorTagFormat = { 353 state: true, 354 errorInfo: '', 355 }; 356 357 const permissionRuleDatas: PermissionData[] = module.definePermissions as PermissionData[]; 358 const permissionRule: string[] = []; 359 permissionRuleDatas.forEach((permissionRuleData: PermissionData) => { 360 permissionRule.push(permissionRuleData.name); 361 }); 362 const permissionTagValue: string = tag.name + tag.description; 363 const permissionArr = permissionTagValue 364 .replace(/(\s|\(|\))/g, '') 365 .replace(/(or|and)/g, '$') 366 .split('$'); 367 permissionArr.forEach((permissionItem) => { 368 if (!permissionRule.includes(permissionItem)) { 369 permissionValueCheckResult.state = false; 370 permissionValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_PERMISSION; 371 } 372 }); 373 return permissionValueCheckResult; 374 } 375 376 /** 377 * throws tag value check 378 * @param { Comment.CommentTag } tag 379 * @param { number } throwsIndex 380 * @returns { ErrorTagFormat } 381 */ 382 static throwsTagValueCheck(tag: Comment.CommentTag, throwsIndex: number, tagsName: Comment.CommentTag[] | undefined): ErrorTagFormat { 383 const throwsValueCheckResult: ErrorTagFormat = { 384 state: true, 385 errorInfo: '', 386 }; 387 const throwsTagType: string = tag.type; 388 const throwsTagName: string = tag.name; 389 const isNumber: boolean = /^\d+$/.test(throwsTagName); 390 if (throwsTagType !== 'BusinessError') { 391 throwsValueCheckResult.state = false; 392 throwsValueCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_INFO_VALUE1_THROWS, [ 393 JSON.stringify(throwsIndex), 394 ]); 395 } else if (!isNumber) { 396 throwsValueCheckResult.state = false; 397 throwsValueCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_INFO_VALUE2_THROWS, [ 398 JSON.stringify(throwsIndex), 399 ]); 400 } 401 const allTagName: string[] = []; 402 tagsName?.forEach((tag: Comment.CommentTag) => { 403 allTagName.push(tag.tag); 404 }); 405 return throwsValueCheckResult; 406 } 407 408 /** 409 * param tag value check 410 * @param { ApiInfo } singleApi 411 * @param { Comment.CommentTag } tag 412 * @param { number } paramIndex 413 * @returns { ErrorTagFormat } 414 */ 415 static paramTagValueCheck(singleApi: ApiInfo, tag: Comment.CommentTag, paramIndex: number): ErrorTagFormat { 416 const paramValueCheckResult: ErrorTagFormat = { 417 state: true, 418 errorInfo: '', 419 }; 420 const legalApiArr: string[] = [ApiType.METHOD, ApiType.TYPE_ALIAS]; 421 if (!legalApiArr.includes(singleApi.getApiType())) { 422 return paramValueCheckResult; 423 } 424 const paramTagType: string = tag.type.replace(/\s/g, ''); 425 const paramTagName: string = tag.name; 426 427 428 let paramApiName: string = ''; 429 let paramApiType: string[] = []; 430 431 if (singleApi.getApiType() === ApiType.TYPE_ALIAS) { 432 const typeParams: ParamInfo[] = (singleApi as TypeAliasInfo).getParamInfos(); 433 paramApiName = typeParams.length > paramIndex ? typeParams[paramIndex].getApiName() : ''; 434 paramApiType = typeParams.length > paramIndex ? typeParams[paramIndex].getType() : ['']; 435 } else { 436 const paramApiInfos: ParamInfo[] = (singleApi as MethodInfo).getParams(); 437 paramApiName = paramApiInfos[paramIndex]?.getApiName(); 438 const spacealCase: string[] = paramApiInfos[paramIndex] ? 439 CommonFunctions.judgeSpecialCase(paramApiInfos[paramIndex].paramType) : []; 440 paramApiType = spacealCase.length > 0 ? spacealCase : paramApiInfos[paramIndex]?.getType(); 441 } 442 443 if (paramTagName !== paramApiName) { 444 paramValueCheckResult.state = false; 445 paramValueCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_INFO_VALUE_PARAM, [ 446 JSON.stringify(paramIndex + 1), 447 JSON.stringify(paramIndex + 1), 448 ]); 449 } 450 if (paramApiType === undefined || paramTagType !== paramApiType.join('|').replace(/\s/g, '')) { 451 paramValueCheckResult.state = false; 452 paramValueCheckResult.errorInfo = 453 paramValueCheckResult.errorInfo + 454 CommonFunctions.createErrorInfo(ErrorMessage.ERROR_INFO_TYPE_PARAM, [ 455 JSON.stringify(paramIndex + 1), 456 JSON.stringify(paramIndex + 1), 457 ]); 458 } 459 460 return paramValueCheckResult; 461 } 462 463 /** 464 * 465 * 1.引用不同文件的api接口 466 * xxx.xxx#xxx 467 * 468 * 2.引用不同文件的模块接口 469 * xxx.xxx 470 * 471 * 3.引用不同文件的api事件接口 472 * xxx.xxx#event:xxx 473 */ 474 /** 475 * useinstead format check 476 * @param { string } moduleValue 477 * @returns { boolean } 478 */ 479 static checkModule(moduleValue: string): boolean { 480 return ( 481 /^[A-Za-z0-9_]+\b(\.[A-Za-z0-9_]+\b)*$/.test(moduleValue) || 482 /^[A-Za-z0-9_]+\b(\.[A-Za-z0-9_]+\b)*\#[A-Za-z0-9_]+\b$/.test(moduleValue) || 483 /^[A-Za-z0-9_]+\b(\.[A-Za-z0-9_]+\b)*\#event:[A-Za-z0-9_]+\b$/.test(moduleValue) 484 ); 485 } 486 /** 487 * Split useinstead value to determine if the file belongs to arkui. 488 * @param { string } useinsteadTagValue 489 * @param { ErrorTagFormat } useinsteadValueCheckResult 490 */ 491 static splitUseinsteadValue(useinsteadTagValue: string, useinsteadValueCheckResult: ErrorTagFormat): void { 492 if (!useinsteadTagValue || useinsteadTagValue === '') { 493 useinsteadValueCheckResult.state = false; 494 useinsteadValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_USEINSTEAD; 495 } 496 // 拆分字符串 497 const splitArray: string[] = useinsteadTagValue.split(/\//g); 498 const MODEL_COUNT: number = 1; 499 const MODEL_COUNTS: number = 2; 500 const FILENAME_MODEL_COUNT: number = 1; 501 if (splitArray.length === MODEL_COUNT) { 502 // 同一文件 503 useinsteadValueCheckResult.state = 504 splitArray[0].indexOf(PunctuationMark.LEFT_BRACKET) === -1 && 505 splitArray[0].indexOf(PunctuationMark.RIGHT_BRACKET) === -1 && 506 TagValueCheck.checkModule(splitArray[0]); 507 } else if (splitArray.length === MODEL_COUNTS) { 508 // 不同文件 509 const fileNameArray: string[] = splitArray[0].split('.'); 510 if (fileNameArray.length === FILENAME_MODEL_COUNT) { 511 // arkui 512 useinsteadValueCheckResult.state = 513 useinsteadValueCheckResult.state && 514 /^[A-Za-z0-9_]+\b$/.test(fileNameArray[0]) && 515 TagValueCheck.checkModule(splitArray[1]); 516 } else { 517 // 非arkui 518 let checkFileName: boolean = true; 519 for (let i = 0; i < fileNameArray.length; i++) { 520 checkFileName = 521 checkFileName && 522 fileNameArray[0] === 'ohos' && 523 /^[A-Za-z0-9_]+\b$/.test(fileNameArray[i]); 524 } 525 if ( 526 !checkFileName || 527 (!TagValueCheck.checkModule(splitArray[1]) && 528 splitArray[1].indexOf(PunctuationMark.LEFT_BRACKET) === -1 && 529 splitArray[1].indexOf(PunctuationMark.RIGHT_BRACKET) === -1) 530 ) { 531 useinsteadValueCheckResult.state = false; 532 } 533 } 534 } else { 535 // 格式错误 536 useinsteadValueCheckResult.state = false; 537 } 538 if (!useinsteadValueCheckResult.state) { 539 useinsteadValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_USEINSTEAD; 540 } 541 } 542 /** 543 * useinstead tag value check 544 * @param { Comment.CommentTag } tag 545 * @returns { ErrorTagFormat } 546 */ 547 static useinsteadTagValueCheck(tag: Comment.CommentTag): ErrorTagFormat { 548 let useinsteadValueCheckResult: ErrorTagFormat = { 549 state: true, 550 errorInfo: '', 551 }; 552 const useinsteadTagValue: string = tag.name; 553 if (useinsteadTagValue === '') { 554 useinsteadValueCheckResult.state = false; 555 useinsteadValueCheckResult.errorInfo = ErrorMessage.ERROR_INFO_VALUE_USEINSTEAD; 556 } else { 557 TagValueCheck.splitUseinsteadValue(useinsteadTagValue, useinsteadValueCheckResult); 558 } 559 return useinsteadValueCheckResult; 560 } 561} 562