• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 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 */
15const {
16  requireTypescriptModule, tagsArrayOfOrder, commentNodeWhiteList, parseJsDoc, ErrorType, ErrorLevel, FileType,
17  inheritArr, ErrorValueInfo, createErrorInfo, isAscending } = require('../utils');
18const { addAPICheckErrorLogs } = require('../compile_info');
19const rules = require('../../code_style_rule.json');
20const whiteLists = require('../../config/jsdocCheckWhiteList.json');
21const ts = requireTypescriptModule();
22
23/**
24 * 判断标签是否为官方标签
25 */
26function isOfficialTag(tagName) {
27  return tagsArrayOfOrder.indexOf(tagName) === -1;
28}
29
30/**
31 * 对form标签的顺序做兼容处理
32 */
33function formOrderCheck(tags, tagIndex, firstIndex, secondIndex) {
34  const frontFirstIndex = tagIndex - 1 > -1 ? tagsArrayOfOrder.indexOf(tags[tagIndex - 1].tag) : 0;
35  const formNeighborArr = [frontFirstIndex, firstIndex];
36  const newTagIndex = tagsArrayOfOrder.lastIndexOf(tags[tagIndex].tag);
37  const newFormNeighborArr = [frontFirstIndex, newTagIndex];
38  if (secondIndex > -1) {
39    formNeighborArr.push(secondIndex);
40    newFormNeighborArr.push(secondIndex);
41  }
42  if (!isAscending(formNeighborArr) && !isAscending(newFormNeighborArr)) {
43    return false;
44  }
45  return true;
46}
47
48
49
50/**
51 * 判断标签排列是否为升序
52 */
53function isAscendingOrder(tags) {
54  let checkResult = true;
55  for (let tagIndex = 0; tagIndex < tags.length; tagIndex++) {
56    if (tagIndex + 1 < tags.length) {
57      // 获取前后两个tag下标
58      const firstIndex = tagsArrayOfOrder.indexOf(tags[tagIndex].tag);
59      const secondIndex = tagsArrayOfOrder.indexOf(tags[tagIndex + 1].tag);
60      // 判断标签是否为官方标签
61      const firstTag = isOfficialTag(tags[tagIndex].tag);
62      // 非自定义标签在前或数组降序时报错
63      if (tags[tagIndex].tag !== 'form' && tags[tagIndex + 1].tag !== 'form' &&
64        ((firstTag && secondIndex > -1) || (firstIndex > secondIndex && secondIndex > -1))) {
65        checkResult = false;
66        break;
67      } else if (tags[tagIndex].tag === 'form') {
68        checkResult = formOrderCheck(tags, tagIndex, firstIndex, secondIndex);
69      }
70    }
71  };
72  return checkResult;
73}
74
75// check jsdoc order
76function checkApiOrder(comments) {
77  const checkOrderRusult = [];
78  comments.forEach(docInfo => {
79    if (isAscendingOrder(docInfo.tags)) {
80      checkOrderRusult.push({
81        checkResult: true,
82        errorInfo: '',
83      });
84    } else {
85      const errorInfo = ErrorValueInfo.ERROR_ORDER;
86      checkOrderRusult.push({
87        checkResult: false,
88        errorInfo: errorInfo,
89      });
90    }
91  });
92  return checkOrderRusult;
93}
94exports.checkApiOrder = checkApiOrder;
95
96function checkAPITagName(tag, node, sourcefile, fileName, JSDocIndec) {
97  const APITagNameResult = {
98    checkResult: true,
99    errorInfo: '',
100  };
101  const tagName = tag.tag;
102  const docTags = [...rules.decorators.customDoc, ...rules.decorators.jsDoc];
103  const decoratorRuleSet = new Set(docTags);
104  if (!decoratorRuleSet.has(tagName) && commentNodeWhiteList.includes(node.kind)) {
105    APITagNameResult.checkResult = false;
106    APITagNameResult.errorInfo = createErrorInfo(ErrorValueInfo.ERROR_LABELNAME, [tagName]);
107    addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.WRONG_SCENE, APITagNameResult.errorInfo,
108      FileType.JSDOC, ErrorLevel.MIDDLE);
109  }
110  return APITagNameResult;
111}
112exports.checkAPITagName = checkAPITagName;
113
114function checkParentInheritTag(node, inheritTag, inheritResult, JSocIndex) {
115  const parentTagArr = [];
116  if (ts.isSourceFile(node.parent)) {
117    return inheritResult;
118  }
119  if (!ts.isModuleBlock(node.parent)) {
120    const comments = parseJsDoc(node.parent);
121    if (comments.length > 0 && Array.isArray(comments[comments.length - 1].tags)) {
122      comments[comments.length - 1].tags.forEach(tag => {
123        parentTagArr.push(tag.tag);
124      });
125      if (parentTagArr.includes(inheritTag)) {
126        inheritResult.checkResult = false;
127        inheritResult.errorInfo += createErrorInfo(ErrorValueInfo.ERROR_INFO_INHERIT, [inheritTag]);
128      } else {
129        checkParentInheritTag(node.parent, inheritTag, inheritResult, JSocIndex);
130      }
131    }
132  } else if (ts.isModuleBlock(node.parent)) {
133    checkParentInheritTag(node.parent, inheritTag, inheritResult, JSocIndex);
134  }
135
136  return inheritResult;
137}
138
139function checkInheritTag(comment, node, sourcefile, fileName, JSocIndex) {
140  const inheritResult = {
141    checkResult: true,
142    errorInfo: '',
143  };
144  const tagArr = [];
145  if (commentNodeWhiteList.includes(node.kind)) {
146    comment.tags.forEach(tag => {
147      tagArr.push(tag.tag);
148    });
149    inheritArr.forEach((inheritTag, index) => {
150      if (!tagArr.includes(inheritTag)) {
151        checkParentInheritTag(node, inheritArr[index], inheritResult, JSocIndex);
152      }
153    });
154    if (!inheritResult.checkResult) {
155      addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.WRONG_SCENE, inheritResult.errorInfo, FileType.API,
156        ErrorLevel.MIDDLE);
157    }
158  }
159  return inheritResult;
160}
161exports.checkInheritTag = checkInheritTag;
162