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