• 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 { 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