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 { 16 ErrorTagFormat, 17 NameDictionaryType, 18 NameScenarioType, 19 ErrorMessage, 20} from '../../../typedef/checker/result_type'; 21import { ApiInfo } from '../../../typedef/parser/ApiInfoDefination'; 22import { CommonFunctions } from '../../../utils/checkUtils'; 23const nameDictionary = require('../config/name_dictionary.json'); 24const nameScenarioScope = require('../config/name_scenario_scope.json'); 25 26export class ApiNamingCheck { 27 /** 28 * Check if the Api name is correct. 29 * @param { Comment.JsDocInfo } apiJsdoc -api jsdoc all infomation 30 * @returns { boolean } 31 */ 32 static namingCheck(singleApi: ApiInfo): ErrorTagFormat { 33 const tagNameCheckResult: ErrorTagFormat = { 34 state: true, 35 errorInfo: '', 36 }; 37 const apiVersionToBeVerified: number = CommonFunctions.getCheckApiVersion(); 38 const lowIdentifier: string = singleApi.getDefinedText().toLowerCase(); 39 ApiNamingCheck.checkApiNamingWords(lowIdentifier, tagNameCheckResult); 40 ApiNamingCheck.checkApiNamingScenario(lowIdentifier, tagNameCheckResult, singleApi); 41 return tagNameCheckResult; 42 } 43 44 /** 45 * 46 * @param { string } lowIdentifier 47 * @param { ErrorTagFormat } tagNameCheckResult 48 */ 49 static checkApiNamingWords(lowIdentifier: string, tagNameCheckResult: ErrorTagFormat): void { 50 const lowercaseNamingMap: Map<string, NameDictionaryType> = ApiNamingCheck.getlowercaseNamingMap(); 51 for (const [key, value] of lowercaseNamingMap) { 52 const prohibitedWordIndex: number = lowIdentifier.indexOf(key); 53 if (prohibitedWordIndex === -1) { 54 continue; 55 } 56 const lowercaseIgnoreWordArr: string[] = value.ignore.map((word: string) => word.toLowerCase()); 57 const internalWord: string = lowIdentifier.substr(prohibitedWordIndex, key.length); 58 if (lowercaseIgnoreWordArr.length === 0) { 59 tagNameCheckResult.state = false; 60 tagNameCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_NAMING, [ 61 lowIdentifier, 62 internalWord, 63 value.suggestion, 64 ]); 65 break; 66 } else { 67 const isIgnoreWord: boolean = ApiNamingCheck.checkIgnoreWord(lowercaseIgnoreWordArr, lowIdentifier); 68 if (isIgnoreWord === false) { 69 tagNameCheckResult.state = false; 70 tagNameCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_NAMING, [ 71 lowIdentifier, 72 internalWord, 73 value.suggestion, 74 ]); 75 } 76 } 77 } 78 } 79 80 /** 81 * 82 * @param {string} lowIdentifier 83 * @param {ErrorTagFormat} tagNameCheckResult 84 * @param {ApiInfo} singleApi 85 */ 86 static checkApiNamingScenario(lowIdentifier: string, tagNameCheckResult: ErrorTagFormat, singleApi: ApiInfo): void { 87 const lowercaseNamingScenarioMap = ApiNamingCheck.getlowercaseNamingScenarioMap(); 88 for (const [key, value] of lowercaseNamingScenarioMap) { 89 const prohibitedWordIndex: number = lowIdentifier.indexOf(key); 90 if (prohibitedWordIndex !== -1 && !ApiNamingCheck.isInAllowedFiles(value.files, singleApi.getFilePath())) { 91 const internalWord = lowIdentifier.substr(prohibitedWordIndex, key.length); 92 tagNameCheckResult.state = false; 93 tagNameCheckResult.errorInfo = CommonFunctions.createErrorInfo(ErrorMessage.ERROR_SCENARIO, [ 94 lowIdentifier, 95 internalWord, 96 singleApi.getFilePath(), 97 ]); 98 } 99 } 100 } 101 102 /** 103 * 104 * @returns 105 */ 106 static getlowercaseNamingMap(): Map<string, NameDictionaryType> { 107 const lowercaseNamingMap: Map<string, NameDictionaryType> = new Map(); 108 for (const item of nameDictionary) { 109 const namingKey: string = item.badWord.toLowerCase(); 110 const namingValue: NameDictionaryType = item; 111 lowercaseNamingMap.set(namingKey, namingValue); 112 } 113 return lowercaseNamingMap; 114 } 115 116 /** 117 * 118 * @param { string[] } lowercaseIgnoreWordArr 119 * @param { string }lowIdentifier 120 * @returns { boolean } 121 */ 122 static checkIgnoreWord(lowercaseIgnoreWordArr: string[], lowIdentifier: string): boolean { 123 let isIgnoreWord: boolean = false; 124 for (let i = 0; i < lowercaseIgnoreWordArr.length; i++) { 125 if (lowercaseIgnoreWordArr[i] && lowIdentifier.indexOf(lowercaseIgnoreWordArr[i]) !== -1) { 126 isIgnoreWord = true; 127 break; 128 } 129 } 130 return isIgnoreWord; 131 } 132 133 /** 134 * 135 * @returns { Map<string, NameScenarioType> } 136 */ 137 static getlowercaseNamingScenarioMap(): Map<string, NameScenarioType> { 138 const lowercaseNamingScenarioMap: Map<string, NameScenarioType> = new Map(); 139 for (const item of nameScenarioScope) { 140 const scenarioKey = item.word.toLowerCase(); 141 const scenarioValue: NameScenarioType = item; 142 lowercaseNamingScenarioMap.set(scenarioKey, scenarioValue); 143 } 144 return lowercaseNamingScenarioMap; 145 } 146 147 /** 148 * 149 * @param { string[] } files 150 * @param { string } fileName 151 * @returns { boolean } 152 */ 153 static isInAllowedFiles(files: string[], fileName: string): boolean { 154 for (const item of files) { 155 const pattern: RegExp = new RegExp(item); 156 pattern.test(fileName); 157 if (pattern.test(fileName)) { 158 return true; 159 } 160 } 161 return false; 162 } 163} 164