• 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 */
15import fs from 'fs';
16import path from 'path';
17import { Parser, FilesMap } from '../../parser/parser';
18import { ApiInfo, BasicApiInfo, notJsDocApiTypes } from '../../../typedef/parser/ApiInfoDefination';
19import {
20  ErrorType,
21  ErrorID,
22  LogType,
23  ErrorLevel,
24  ErrorTagFormat,
25  ErrorMessage,
26  ApiCheckInfo,
27  ErrorBaseInfo,
28} from '../../../typedef/checker/result_type';
29import { ClassInfo } from '../../../typedef/parser/ApiInfoDefination';
30import { Comment } from '../../../typedef/parser/Comment';
31import { compositiveResult, compositiveLocalResult, CommonFunctions } from '../../../utils/checkUtils';
32import { OrderCheck } from './tag_order_check';
33import { TagNameCheck } from './tag_name_check';
34import { LegalityCheck } from './tag_legality_check';
35import { TagRepeatCheck } from './tag_repeat_check';
36import { AddErrorLogs } from './compile_info';
37import { TagValueCheck } from './tag_value_check';
38import { WordsCheck } from './words_check';
39import { ForbiddenWordsCheck } from './forbidden_words_check';
40import { ApiNamingCheck } from './naming_check';
41import { CheckHump } from './check_hump';
42import { EventMethodChecker } from './event_method_check';
43import { EventMethodData } from '../../../typedef/checker/event_method_check_interface';
44import { ApiChangeCheck } from './check_api_diff';
45import { TagInheritCheck } from './tag_inherit_check';
46import { ChineseCheck } from './check_chinese';
47import { AnonymousFunctionCheck } from './check_anonymous_function';
48import { CheckErrorCode } from './check_error_code';
49
50export let currentFilePath: string = '';
51
52export class Check {
53  /**
54   * checker tool main entrance
55   * @param { string[] } files -File path for storing file information.
56   */
57  static scanEntry(files: string[], prId: string): void {
58    ApiChangeCheck.checkApiChange(prId);
59    files.forEach((filePath: string, index: number) => {
60      currentFilePath = filePath;
61      if (filePath.indexOf('build-tools') !== -1) {
62        return;
63      }
64      console.log(`scaning file in no ${++index}!`);
65      const fileParseResult: FilesMap = Check.parseAPICodeStyle(filePath);
66      const baseInfos: BasicApiInfo[] = Parser.getAllBasicApi(fileParseResult);
67      Check.checkNodeInfos(baseInfos as ClassInfo[]);
68      const currFileInfo = fileParseResult.get(path.basename(filePath));
69      if (currFileInfo) {
70        CheckHump.checkAPIFileName(currFileInfo);
71      }
72      CheckHump.checkAllAPINameOfHump(baseInfos);
73      //words check
74      WordsCheck.wordCheckResultsProcessing(baseInfos);
75      // event check
76      const eventMethodChecker: EventMethodChecker = new EventMethodChecker(fileParseResult);
77      const eventMethodDataMap: Map<string, EventMethodData> = eventMethodChecker.getAllEventMethod();
78      eventMethodChecker.checkEventMethod(eventMethodDataMap);
79    });
80  }
81
82  /**
83   * Obtain the path of the file to be checked.
84   * @param { string } url -File path for storing file information.
85   * @returns { Array<string> } -file path array
86   */
87  static getMdFiles(url: string): Array<string> {
88    const content: string = fs.readFileSync(url, 'utf-8');
89    const mdFiles: Array<string> = content.split(/[(\r\n)\r\n]+/);
90    return mdFiles;
91  }
92
93  /**
94   * Based on a single file path,parse it using the Parser method.
95   * @param { string } filePath -single file path to be checked
96   * @returns { FilesMap }
97   */
98  static parseAPICodeStyle(filePath: string): FilesMap {
99    const parseResult: FilesMap = Parser.parseFile(path.resolve(filePath, '..'), filePath);
100    return parseResult;
101  }
102
103  /**
104   * Obtain all API information and check api jsdoc
105   * @param { ClassInfo[] } baseInfos
106   */
107  static checkNodeInfos(baseInfos: ClassInfo[]): void {
108    let allNodeInfos: ApiInfo[] = [];
109    Check.getHasJsdocApiInfos(baseInfos, allNodeInfos);
110    // for all nodes of the current file
111    allNodeInfos.forEach((singleApi: ApiInfo) => {
112      const apiJsdoc: Comment.JsDocInfo | undefined = singleApi.getLastJsDocInfo();
113      const apiJsdocTextLength: number = singleApi.getJsDocText().length;
114      if (singleApi.getApiType() === 'Method' && singleApi.getParentApi()?.apiType === 'Struct') {
115        return;
116      }
117      if (apiJsdoc === undefined || apiJsdocTextLength === 0) {
118        const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
119        errorBaseInfo
120          .setErrorID(ErrorID.NO_JSDOC_ID)
121          .setErrorLevel(ErrorLevel.MIDDLE)
122          .setErrorType(ErrorType.NO_JSDOC)
123          .setLogType(LogType.LOG_JSDOC)
124          .setErrorInfo(ErrorMessage.ERROR_NO_JSDOC);
125        const apiInfoNojsdoc: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
126          errorBaseInfo);
127        AddErrorLogs.addAPICheckErrorLogs(apiInfoNojsdoc, compositiveResult, compositiveLocalResult);
128      } else {
129        if (apiJsdoc.getKit().length === 0) {
130          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
131          errorBaseInfo
132            .setErrorID(ErrorID.WRONG_SCENE_ID)
133            .setErrorLevel(ErrorLevel.MIDDLE)
134            .setErrorType(ErrorType.WRONG_SCENE)
135            .setLogType(LogType.LOG_JSDOC)
136            .setErrorInfo(CommonFunctions.createErrorInfo(ErrorMessage.ERROR_LOST_LABEL, ['kit']));
137          const apiInfoNoKit: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
138            errorBaseInfo);
139          AddErrorLogs.addAPICheckErrorLogs(apiInfoNoKit, compositiveResult, compositiveLocalResult);
140        }
141        if (!apiJsdoc.getIsFile()) {
142          const apiInfo: ApiCheckInfo = new ApiCheckInfo();
143          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
144          errorBaseInfo
145            .setErrorID(ErrorID.WRONG_SCENE_ID)
146            .setErrorLevel(ErrorLevel.MIDDLE)
147            .setErrorType(ErrorType.WRONG_SCENE)
148            .setLogType(LogType.LOG_JSDOC)
149            .setErrorInfo(CommonFunctions.createErrorInfo(ErrorMessage.ERROR_LOST_LABEL, ['file']));
150          const apiInfoNoFile: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
151            errorBaseInfo);
152          AddErrorLogs.addAPICheckErrorLogs(apiInfoNoFile, compositiveResult, compositiveLocalResult);
153        }
154        // legality check
155        const tagLegalityCheckResult: ErrorTagFormat[] = LegalityCheck.apiLegalityCheck(singleApi, apiJsdoc);
156        // order check
157        const orderCheckResult: ErrorTagFormat = OrderCheck.orderCheck(singleApi, apiJsdoc);
158        // api naming check
159        const namingCheckResult: ErrorTagFormat = ApiNamingCheck.namingCheck(singleApi);
160        // check jsdoc chinese
161        const chineseCheckResult: ErrorTagFormat = ChineseCheck.checkChinese(apiJsdoc);
162        // check error code
163        const errorCodeResult: ErrorTagFormat = CheckErrorCode.checkErrorCode(apiJsdoc);
164        // tags name check
165        const tagNameCheckResult: ErrorTagFormat = TagNameCheck.tagNameCheck(apiJsdoc);
166        // tags inherit check
167        const tagInheritCheckResult: ErrorTagFormat[] = TagInheritCheck.tagInheritCheck(singleApi);
168        // tags value check
169        const tagValueCheckResult: ErrorTagFormat[] = TagValueCheck.tagValueCheck(singleApi, apiJsdoc);
170        // tags repeat check
171        const tagRepeatCheckResult: ErrorTagFormat[] = TagRepeatCheck.tagRepeatCheck(apiJsdoc);
172        // api forbidden wors check
173        const forbiddenWordsCheckResult: ErrorTagFormat = ForbiddenWordsCheck.forbiddenWordsCheck(singleApi as ClassInfo);
174
175        const anonymousFunction: ErrorTagFormat = AnonymousFunctionCheck.checkAnonymousFunction(singleApi);
176
177        if (!orderCheckResult.state) {
178          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
179          errorBaseInfo
180            .setErrorID(ErrorID.WRONG_ORDER_ID)
181            .setErrorLevel(ErrorLevel.MIDDLE)
182            .setErrorType(ErrorType.WRONG_ORDER)
183            .setLogType(LogType.LOG_JSDOC)
184            .setErrorInfo(orderCheckResult.errorInfo);
185          const apiInfoOrder: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
186            errorBaseInfo);
187          AddErrorLogs.addAPICheckErrorLogs(apiInfoOrder, compositiveResult, compositiveLocalResult);
188        }
189        if (!tagNameCheckResult.state) {
190          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
191          errorBaseInfo
192            .setErrorID(ErrorID.UNKNOW_DECORATOR_ID)
193            .setErrorLevel(ErrorLevel.MIDDLE)
194            .setErrorType(ErrorType.UNKNOW_DECORATOR)
195            .setLogType(LogType.LOG_JSDOC)
196            .setErrorInfo(tagNameCheckResult.errorInfo);
197          const apiInfoName: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
198            errorBaseInfo);
199          AddErrorLogs.addAPICheckErrorLogs(apiInfoName, compositiveResult, compositiveLocalResult);
200        }
201        if (!forbiddenWordsCheckResult.state) {
202          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
203          errorBaseInfo
204            .setErrorID(ErrorID.FORBIDDEN_WORDS_ID)
205            .setErrorLevel(ErrorLevel.MIDDLE)
206            .setErrorType(ErrorType.FORBIDDEN_WORDS)
207            .setLogType(LogType.LOG_JSDOC)
208            .setErrorInfo(forbiddenWordsCheckResult.errorInfo);
209          const apiInfoForbiddenWords: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
210            errorBaseInfo);
211          AddErrorLogs.addAPICheckErrorLogs(apiInfoForbiddenWords, compositiveResult, compositiveLocalResult);
212        }
213        if (!namingCheckResult.state) {
214          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
215          errorBaseInfo
216            .setErrorID(ErrorID.NAMING_ERRORS_ID)
217            .setErrorLevel(ErrorLevel.MIDDLE)
218            .setErrorType(ErrorType.NAMING_ERRORS)
219            .setLogType(LogType.LOG_JSDOC)
220            .setErrorInfo(namingCheckResult.errorInfo);
221          const apiInfoNaming: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
222            errorBaseInfo);
223          AddErrorLogs.addAPICheckErrorLogs(apiInfoNaming, compositiveResult, compositiveLocalResult);
224        }
225        if (!chineseCheckResult.state) {
226          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
227          errorBaseInfo
228            .setErrorID(ErrorID.JSDOC_HAS_CHINESE)
229            .setErrorLevel(ErrorLevel.MIDDLE)
230            .setErrorType(ErrorType.JSDOC_HAS_CHINESE)
231            .setLogType(LogType.LOG_JSDOC)
232            .setErrorInfo(chineseCheckResult.errorInfo);
233          const apiInfoChineseCheck: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
234            errorBaseInfo);
235          AddErrorLogs.addAPICheckErrorLogs(apiInfoChineseCheck, compositiveResult, compositiveLocalResult);
236        }
237        if (!errorCodeResult.state) {
238          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
239          errorBaseInfo
240            .setErrorID(ErrorID.ERROR_ERROR_CODE)
241            .setErrorLevel(ErrorLevel.MIDDLE)
242            .setErrorType(ErrorType.ERROR_ERROR_CODE)
243            .setLogType(LogType.LOG_JSDOC)
244            .setErrorInfo(errorCodeResult.errorInfo);
245          const apiInfoErrorCode: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
246            errorBaseInfo);
247          AddErrorLogs.addAPICheckErrorLogs(apiInfoErrorCode, compositiveResult, compositiveLocalResult);
248        }
249        tagInheritCheckResult.forEach((inheritCheckResult: ErrorTagFormat) => {
250          if (!inheritCheckResult.state) {
251            const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
252            errorBaseInfo
253              .setErrorID(ErrorID.WRONG_SCENE_ID)
254              .setErrorLevel(ErrorLevel.MIDDLE)
255              .setErrorType(ErrorType.WRONG_SCENE)
256              .setLogType(LogType.LOG_JSDOC)
257              .setErrorInfo(inheritCheckResult.errorInfo);
258            const apiInfoInherit: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
259              errorBaseInfo);
260            AddErrorLogs.addAPICheckErrorLogs(apiInfoInherit, compositiveResult, compositiveLocalResult);
261          }
262        });
263        tagLegalityCheckResult.forEach((legalityResult) => {
264          if (legalityResult.state === false) {
265            const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
266            errorBaseInfo
267              .setErrorID(ErrorID.WRONG_SCENE_ID)
268              .setErrorLevel(ErrorLevel.MIDDLE)
269              .setErrorType(ErrorType.WRONG_SCENE)
270              .setLogType(LogType.LOG_JSDOC)
271              .setErrorInfo(legalityResult.errorInfo);
272            const apiInfoInherit: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
273              errorBaseInfo);
274            AddErrorLogs.addAPICheckErrorLogs(apiInfoInherit, compositiveResult, compositiveLocalResult);
275          }
276        });
277        tagValueCheckResult.forEach((valueResult) => {
278          if (valueResult.state === false) {
279            const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
280            errorBaseInfo
281              .setErrorID(ErrorID.WRONG_VALUE_ID)
282              .setErrorLevel(ErrorLevel.MIDDLE)
283              .setErrorType(ErrorType.WRONG_VALUE)
284              .setLogType(LogType.LOG_JSDOC)
285              .setErrorInfo(valueResult.errorInfo);
286            const apiInfoValue: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
287              errorBaseInfo);
288            AddErrorLogs.addAPICheckErrorLogs(apiInfoValue, compositiveResult, compositiveLocalResult);
289          }
290        });
291        tagRepeatCheckResult.forEach((repeatResult) => {
292          if (repeatResult.state === false) {
293            const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
294            errorBaseInfo
295              .setErrorID(ErrorID.WRONG_SCENE_ID)
296              .setErrorLevel(ErrorLevel.MIDDLE)
297              .setErrorType(ErrorType.WRONG_SCENE)
298              .setLogType(LogType.LOG_JSDOC)
299              .setErrorInfo(repeatResult.errorInfo);
300            const apiInfoRepeat: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
301              errorBaseInfo);
302            AddErrorLogs.addAPICheckErrorLogs(apiInfoRepeat, compositiveResult, compositiveLocalResult);
303          }
304        });
305        if (!anonymousFunction.state) {
306          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
307          errorBaseInfo
308            .setErrorID(ErrorID.WRONG_SCENE_ID)
309            .setErrorLevel(ErrorLevel.MIDDLE)
310            .setErrorType(ErrorType.WRONG_SCENE)
311            .setLogType(LogType.LOG_JSDOC)
312            .setErrorInfo(anonymousFunction.errorInfo);
313          const apiInfoAnonymous: ApiCheckInfo = CommonFunctions.getErrorInfo(singleApi, apiJsdoc, currentFilePath,
314            errorBaseInfo);
315          AddErrorLogs.addAPICheckErrorLogs(apiInfoAnonymous, compositiveResult, compositiveLocalResult);
316        }
317      }
318    });
319  }
320  /**
321   * Filter out all nodes with comments.
322   * @param { BasicApiInfo[] } childNodeApis -original data.
323   * @param { ApiInfo[] } childNodeInfos -processed data.
324   */
325  static getHasJsdocApiInfos(childNodeApis: BasicApiInfo[], childNodeInfos: ApiInfo[]): void {
326    childNodeApis.forEach((childNodeApi) => {
327      if (!notJsDocApiTypes.has(childNodeApi.getApiType())) {
328        childNodeInfos.push(childNodeApi as ApiInfo);
329      }
330    });
331    return;
332  }
333}
334