161847f8eSopenharmony_ci/*
261847f8eSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
361847f8eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the 'License');
461847f8eSopenharmony_ci * you may not use this file except in compliance with the License.
561847f8eSopenharmony_ci * You may obtain a copy of the License at
661847f8eSopenharmony_ci *
761847f8eSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
861847f8eSopenharmony_ci *
961847f8eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1061847f8eSopenharmony_ci * distributed under the License is distributed on an 'AS IS' BASIS,
1161847f8eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1261847f8eSopenharmony_ci * See the License for the specific language governing permissions and
1361847f8eSopenharmony_ci * limitations under the License.
1461847f8eSopenharmony_ci */
1561847f8eSopenharmony_ci
1661847f8eSopenharmony_ciconst path = require('path');
1761847f8eSopenharmony_ciconst { ErrorLevel, LogType, hasAPINote, getApiInfo, requireTypescriptModule, ErrorType, getApiVersion, getCheckApiVersion } = require('./utils');
1861847f8eSopenharmony_ciconst { addAPICheckErrorLogs } = require('./compile_info');
1961847f8eSopenharmony_ciconst ts = requireTypescriptModule();
2061847f8eSopenharmony_ci
2161847f8eSopenharmony_ci/**
2261847f8eSopenharmony_ci * 大驼峰
2361847f8eSopenharmony_ci * class、interface、枚举名
2461847f8eSopenharmony_ci * 小驼峰
2561847f8eSopenharmony_ci * 变量名、方法名、参数名、namespace
2661847f8eSopenharmony_ci * 全大写
2761847f8eSopenharmony_ci * 常量命名、枚举值
2861847f8eSopenharmony_ci */
2961847f8eSopenharmony_ci
3061847f8eSopenharmony_ci// 大驼峰检查
3161847f8eSopenharmony_cifunction checkLargeHump(word) {
3261847f8eSopenharmony_ci  return /^([A-Z][a-z0-9]*)*$/g.test(word);
3361847f8eSopenharmony_ci}
3461847f8eSopenharmony_ci
3561847f8eSopenharmony_ci// 小驼峰检查
3661847f8eSopenharmony_cifunction checkSmallHump(word) {
3761847f8eSopenharmony_ci  return /^[a-z]+[0-9]*([A-Z][a-z0-9]*)*$/g.test(word);
3861847f8eSopenharmony_ci}
3961847f8eSopenharmony_ciexports.checkSmallHump = checkSmallHump;
4061847f8eSopenharmony_ci
4161847f8eSopenharmony_ci// 全大写检查
4261847f8eSopenharmony_cifunction checkAllUppercaseHump(word) {
4361847f8eSopenharmony_ci  return /^[A-Z]+[0-9]*([\_][A-Z0-9]+)*$/g.test(word);
4461847f8eSopenharmony_ci}
4561847f8eSopenharmony_ci
4661847f8eSopenharmony_cifunction getName(node) {
4761847f8eSopenharmony_ci  let str = '';
4861847f8eSopenharmony_ci  if (node.name.escapedText) {
4961847f8eSopenharmony_ci    str = node.name.escapedText.toString();
5061847f8eSopenharmony_ci  } else if (node.name.text) {
5161847f8eSopenharmony_ci    str = node.name.text.toString();
5261847f8eSopenharmony_ci  }
5361847f8eSopenharmony_ci  return str;
5461847f8eSopenharmony_ci}
5561847f8eSopenharmony_ci
5661847f8eSopenharmony_cifunction isConstantDecorator(node, name) {
5761847f8eSopenharmony_ci  return hasAPINote(node) && getApiInfo(node).isConstant && !checkAllUppercaseHump(name);
5861847f8eSopenharmony_ci}
5961847f8eSopenharmony_ci
6061847f8eSopenharmony_cifunction filterApiVersion(node, version) {
6161847f8eSopenharmony_ci  const apiVersion = getApiVersion(node);
6261847f8eSopenharmony_ci  return apiVersion === version;
6361847f8eSopenharmony_ci}
6461847f8eSopenharmony_ci
6561847f8eSopenharmony_cifunction checkAPINameOfHump(node, sourcefile, fileName) {
6661847f8eSopenharmony_ci  let checkResult = '';
6761847f8eSopenharmony_ci  const apiInfo = getApiInfo(node);
6861847f8eSopenharmony_ci  if (ts.isEnumMember(node) || (ts.isVariableDeclaration(node) && !(fileName.indexOf('component\\ets\\') >= 0 ||
6961847f8eSopenharmony_ci    fileName.indexOf('component/ets/') >= 0))) {
7061847f8eSopenharmony_ci    const name = getName(node);
7161847f8eSopenharmony_ci    if (!checkAllUppercaseHump(name)) {
7261847f8eSopenharmony_ci      checkResult = `This name [${name}] should be named by all uppercase.`;
7361847f8eSopenharmony_ci    }
7461847f8eSopenharmony_ci  } else if (ts.isInterfaceDeclaration(node) || ts.isClassDeclaration(node) || ts.isTypeAliasDeclaration(node) ||
7561847f8eSopenharmony_ci    ts.isEnumDeclaration(node)) {
7661847f8eSopenharmony_ci    const name = getName(node);
7761847f8eSopenharmony_ci    if (isConstantDecorator(node, name)) {
7861847f8eSopenharmony_ci      checkResult = `This name [${name}] should be named by all uppercase.`;
7961847f8eSopenharmony_ci    } else if (!apiInfo.isConstant && !checkLargeHump(name)) {
8061847f8eSopenharmony_ci      checkResult = `This name [${name}] should be named by large hump.`;
8161847f8eSopenharmony_ci    }
8261847f8eSopenharmony_ci  } else if (ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isMethodDeclaration(node) ||
8361847f8eSopenharmony_ci    ts.isFunctionDeclaration(node) || ts.isParameter(node) || ts.isModuleDeclaration(node)) {
8461847f8eSopenharmony_ci    const name = getName(node);
8561847f8eSopenharmony_ci    if (isConstantDecorator(node, name)) {
8661847f8eSopenharmony_ci      checkResult = `This name [${name}] should be named by all uppercase.`;
8761847f8eSopenharmony_ci    } else if (!apiInfo.isConstant && !checkSmallHump(name)) {
8861847f8eSopenharmony_ci      checkResult = `This name [${name}] should be named by small hump.`;
8961847f8eSopenharmony_ci    }
9061847f8eSopenharmony_ci  }
9161847f8eSopenharmony_ci
9261847f8eSopenharmony_ci  if (checkResult !== '' && filterApiVersion(node, getCheckApiVersion()) && (!apiInfo.deprecated || apiInfo.deprecated === '')) {
9361847f8eSopenharmony_ci    addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.NAMING_ERRORS, checkResult, LogType.LOG_API,
9461847f8eSopenharmony_ci      ErrorLevel.MIDDLE);
9561847f8eSopenharmony_ci  }
9661847f8eSopenharmony_ci}
9761847f8eSopenharmony_ciexports.checkAPINameOfHump = checkAPINameOfHump;
9861847f8eSopenharmony_ci
9961847f8eSopenharmony_cifunction checkAPIFileName(sourcefile, fileName) {
10061847f8eSopenharmony_ci  if (fileName.indexOf('component\\ets\\') < 0 && fileName.indexOf('component/ets/') < 0) {
10161847f8eSopenharmony_ci    let moduleName = '';
10261847f8eSopenharmony_ci    let exportAssignment = '';
10361847f8eSopenharmony_ci    sourcefile.statements.forEach(statement => {
10461847f8eSopenharmony_ci      if (ts.isModuleDeclaration(statement) && statement.name && ts.isIdentifier(statement.name)) {
10561847f8eSopenharmony_ci        moduleName = statement.name.escapedText.toString();
10661847f8eSopenharmony_ci      }
10761847f8eSopenharmony_ci      if (ts.isExportAssignment(statement) && statement.expression && ts.isIdentifier(statement.expression)) {
10861847f8eSopenharmony_ci        exportAssignment = statement.expression.escapedText.toString();
10961847f8eSopenharmony_ci      }
11061847f8eSopenharmony_ci    });
11161847f8eSopenharmony_ci    const basename = path.basename(fileName).replace(/\.d\.ts$/, '');
11261847f8eSopenharmony_ci    const lastModuleName = basename.split('.').pop();
11361847f8eSopenharmony_ci    let checkResult = '';
11461847f8eSopenharmony_ci
11561847f8eSopenharmony_ci    if (moduleName !== '' && exportAssignment === moduleName && !checkSmallHump(lastModuleName)) {
11661847f8eSopenharmony_ci      checkResult = 'This API file should be named by small hump.';
11761847f8eSopenharmony_ci    } else if (moduleName === '' && exportAssignment !== moduleName && !checkLargeHump(lastModuleName)) {
11861847f8eSopenharmony_ci      checkResult = 'This API file should be named by large hump.';
11961847f8eSopenharmony_ci    }
12061847f8eSopenharmony_ci    if (checkResult !== '' && filterApiVersion(sourcefile, getCheckApiVersion())) {
12161847f8eSopenharmony_ci      addAPICheckErrorLogs(sourcefile, sourcefile, fileName, ErrorType.NAMING_ERRORS, checkResult, LogType.LOG_FILE,
12261847f8eSopenharmony_ci        ErrorLevel.MIDDLE);
12361847f8eSopenharmony_ci    }
12461847f8eSopenharmony_ci  }
12561847f8eSopenharmony_ci}
12661847f8eSopenharmony_ciexports.checkAPIFileName = checkAPIFileName;
127