• 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 { ApiType, ExportImportValue, ImportInfo } from '../../../typedef/parser/ApiInfoDefination';
17import {
18  ErrorType,
19  ErrorID,
20  LogType,
21  ErrorLevel,
22  ErrorTagFormat,
23  ErrorMessage,
24  ApiCheckInfo,
25  ErrorBaseInfo,
26} from '../../../typedef/checker/result_type';
27import { BasicApiInfo } from '../../../typedef/parser/ApiInfoDefination';
28import { tagsArrayOfOrder, officialTagArr, CommonFunctions } from '../../../utils/checkUtils';
29import { AddErrorLogs } from './compile_info';
30import { compositiveResult, compositiveLocalResult, punctuationMarkSet } from '../../../utils/checkUtils';
31import { Set } from 'typescript';
32import { dictionariesArr } from '../config/dictionaries.json';
33import { dictionariesSupplementaryArr } from '../config/dictionaries_supplementary.json';
34const dictionariesSet: Set<string> = new Set([
35  ...dictionariesArr,
36  ...dictionariesSupplementaryArr,
37  ...tagsArrayOfOrder,
38  ...officialTagArr,
39]);
40
41export class WordsCheck {
42  /**
43   * words spell check
44   * @param { BasicApiInfo[] } baseInfos
45   */
46  static wordCheckResultsProcessing(baseInfos: BasicApiInfo[]): void {
47    baseInfos.forEach((baseInfo) => {
48      if (baseInfo.getApiType() === ApiType.SOURCE_FILE) {
49        return;
50      }
51      let apiText: string = baseInfo.getJsDocText() + baseInfo.getDefinedText();
52      if (baseInfo.getApiType() === ApiType.IMPORT) {
53        const importText: Array<ExportImportValue> = (baseInfo as ImportInfo).getImportValues();
54        const importValueArr: string[] = [];
55        importText.forEach(importValue => {
56          importValueArr.push(importValue.key);
57        });
58        apiText = importValueArr.join('|');
59      }
60      WordsCheck.wordsCheck(apiText, baseInfo);
61    });
62  }
63
64  /**
65   * Break the obtained api information into single words.
66   * @param { string } apiText
67   * @param { BasicApiInfo } baseInfo
68   */
69  static wordsCheck(apiText: string, baseInfo: BasicApiInfo): void {
70    const reg = /\s{2,}/g;
71    const regx = /(\/\*|\*\/|\*)|\n|\r/g;
72    let fullText: string = apiText.replace(regx, ' ');
73    punctuationMarkSet.forEach(punctuationMark => {
74      const punctuationMarkReg = new RegExp(punctuationMark, 'g');
75      if (punctuationMarkReg.test(fullText)) {
76        fullText = fullText.replace(punctuationMarkReg, ' ').replace(reg, ' ');
77      }
78    });
79    let apiWordsArr = fullText.split(/\s/g);
80    const errorWords: string[] = [];
81    apiWordsArr.forEach((apiWord) => {
82      const basicWords: string[] = [];
83      WordsCheck.splitComplexWords(apiWord, basicWords);
84      basicWords.forEach((basicWord) => {
85        if (!WordsCheck.checkBaseWord(basicWord.toLowerCase())) {
86          errorWords.push(basicWord);
87          const wordsCheckFormat: ErrorTagFormat = {
88            state: false,
89            errorInfo: CommonFunctions.createErrorInfo(ErrorMessage.ERROR_WORD, [apiWord, basicWord]),
90          };
91          const errorBaseInfo: ErrorBaseInfo = new ErrorBaseInfo();
92          errorBaseInfo
93            .setErrorID(ErrorID.MISSPELL_WORDS_ID)
94            .setErrorLevel(ErrorLevel.MIDDLE)
95            .setErrorType(ErrorType.MISSPELL_WORDS)
96            .setLogType(LogType.LOG_JSDOC)
97            .setErrorInfo(wordsCheckFormat.errorInfo);
98          const apiInfoSpell: ApiCheckInfo = CommonFunctions.getErrorInfo(baseInfo, undefined, baseInfo.getFileAbsolutePath(), errorBaseInfo);
99          AddErrorLogs.addAPICheckErrorLogs(apiInfoSpell, compositiveResult, compositiveLocalResult);
100        }
101      });
102    });
103  }
104
105  /**
106   * Whether compound words are underlined
107   * @param { string } word
108   * @returns { boolean }
109   */
110  static hasUnderline(word: string): boolean {
111    return /(?<!^)\_/g.test(word);
112  }
113
114  /**
115   * split complex words
116   * @param { string } complexWord
117   * @returns { string[] }
118   */
119  static splitComplexWords(complexWord: string, basicWords: string[]): void {
120    let baseWords: string[] = [];
121    // splite underlineWord
122    if (WordsCheck.hasUnderline(complexWord)) {
123      baseWords = complexWord.split(/(?<!^)\_/g);
124    } else {
125      // splite complexWord
126      if (!/(?<!^)(?=[A-Z])/g.test(complexWord)) {
127        baseWords.push(complexWord);
128      } else {
129        baseWords = complexWord.split(/(?<!^)(?=[A-Z])/g);
130      }
131    }
132    baseWords.forEach((word) => {
133      if (/[0-9]/g.test(word)) {
134        basicWords.concat(word.split(/0-9/g));
135      } else {
136        basicWords.push(word);
137      }
138    });
139  }
140
141  /**
142   * check base word
143   * @param { string } word
144   * @returns { boolean }
145   */
146  static checkBaseWord(word: string): boolean {
147    if (/^[a-z][0-9]+$/g.test(word)) {
148      return false;
149    } else if (/^[A-Za-z]+/g.test(word) && !dictionariesSet.has(word.toLowerCase())) {
150      return false;
151    }
152    return true;
153  }
154}
155