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 */ 15 16const path = require('path'); 17const ts = require(path.resolve(__dirname, "../node_modules/typescript")); 18const { error_type } = require('./utils'); 19const rules = require("../code_style_rule.json"); 20const { addAPICheckErrorLogs } = require('./compile_info'); 21 22function checkAPINameOfHump(node, sourcefile, fileName) { 23 let errorInfo = ''; 24 if (node.parent && !ts.isImportClause(node.parent) && !ts.isImportSpecifier(node.parent) && 25 (ts.isInterfaceDeclaration(node.parent) || ts.isClassDeclaration(node.parent) || 26 ts.isEnumDeclaration(node.parent))) { 27 if (!checkLargeHump(node.escapedText.toString())) { 28 errorInfo = `This moduleName [${node.escapedText.toString()}] should be used by large hump.`; 29 } 30 } else if (!node.parent || (!ts.isImportClause(node.parent) && !ts.isImportSpecifier(node.parent) && 31 !ts.isTypeReferenceNode(node.parent) && !ts.isQualifiedName(node.parent) && 32 !ts.isTypeParameterDeclaration(node.parent))) { 33 if (!checkSmallHump(node.escapedText.toString())) { 34 errorInfo = `This moduleName [${node.escapedText.toString()}] should be used by small hump.`; 35 } 36 } 37 if (errorInfo !== '') { 38 addAPICheckErrorLogs(node, sourcefile, fileName, error_type.NAMING_ERRORS, errorInfo); 39 } 40} 41exports.checkAPINameOfHump = checkAPINameOfHump; 42 43function checkAPIFileName(sourcefile, fileName) { 44 const moduleNames = new Set([]); 45 const exportAssignments = new Set([]); 46 sourcefile.statements.forEach((statement, index) => { 47 if (ts.isModuleDeclaration(statement) && statement.name && ts.isIdentifier(statement.name)) { 48 moduleNames.add(statement.name.escapedText.toString()); 49 } 50 if (ts.isExportAssignment(statement) && statement.expression && ts.isIdentifier(statement.expression)) { 51 exportAssignments.add(statement.expression.escapedText.toString()); 52 } 53 }); 54 if (exportAssignments.size > 1) { 55 addAPICheckErrorLogs(sourcefile, sourcefile, fileName, error_type.NAMING_ERRORS, 56 `This API file can only have one export default statement.`); 57 } else if (exportAssignments.size === 1) { 58 const basename = path.basename(fileName); 59 if (/^@ohos|@system/g.test(basename)) { 60 for (const exportAssignment of exportAssignments) { 61 const lastModuleName = basename.split('.').at(-1); 62 if (moduleNames.has(exportAssignment) && !checkSmallHump(lastModuleName)) { 63 addAPICheckErrorLogs(sourcefile, sourcefile, fileName, error_type.NAMING_ERRORS, 64 `This API file should be named by small hump.`); 65 } else if (!checkLargeHump(lastModuleName)) { 66 addAPICheckErrorLogs(sourcefile, sourcefile, fileName, error_type.NAMING_ERRORS, 67 `This API file should be named by large hump.`); 68 } 69 } 70 } else if (!checkSmallHump(basename)) { 71 addAPICheckErrorLogs(sourcefile, sourcefile, fileName, error_type.NAMING_ERRORS, 72 `This API file should be named by small hump.`); 73 } 74 } 75} 76 77function spliteByHump(word) { 78 let firstBasicWord = word; 79 if (/(?<!^)(?=[A-Z])/g.test(word)) { 80 firstBasicWord = word.split(/(?<!^)(?=[A-Z])/g)[0]; 81 } 82 return firstBasicWord; 83} 84 85function checkLargeHump(word) { 86 return /^[A-Z]/.test(spliteByHump(word)); 87} 88 89function checkSmallHump(word) { 90 const namingWhitelistSet = new Set(rules.namingWhitelist) 91 if (namingWhitelistSet.has(word)) { 92 return true; 93 } 94 return /^[a-z]/.test(spliteByHump(word)); 95} 96