• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
15const path = require('path');
16const fs = require('fs');
17const result = require('../check_result.json');
18const { apiCheckArr, getApiInfo, ErrorLevel, ApiCheckResult, apiCheckInfoArr, requireTypescriptModule } = require('../src/utils');
19const ts = requireTypescriptModule();
20
21/**
22 *
23 * @param {ts.Node} node current node
24 * @param {ts.Sourcefile} sourcefile root node
25 * @param {String} fileName full file name
26 * @param {String} errorType enum object:ErrorType
27 * @param {String} errorInfo error infomation
28 * @param {String} type jsdoc | api
29 * @param {Enum} level enum object:ErrorLevel
30 */
31function addAPICheckErrorLogs(node, sourcefile, fileName, errorType, errorInfo, type, level) {
32  const checkFailFileNameSet = new Set(result.apiFiles);
33  if (!checkFailFileNameSet.has(fileName)) {
34    result.apiFiles.push(fileName);
35  }
36  const posOfNode = sourcefile.getLineAndCharacterOfPosition(node.getStart());
37  const baseFileName = fileName.substring(fileName.indexOf('api'), fileName.length);
38  const errorMessage = `API check error of [${errorType.description}]: ${errorInfo}`;
39  const needMask = checkMarkError(node, errorMessage, baseFileName);
40  if (needMask) {
41    return;
42  }
43  if (level === ErrorLevel.HIGH || level === ErrorLevel.MIDDLE) {
44    ApiCheckResult.formatCheckResult = false;
45  }
46
47  apiCheckArr.push({
48    errorType: errorType.description,
49    fileName: `${baseFileName}(line: ${posOfNode.line + 1}, col: ${posOfNode.character + 1})`,
50    type,
51    errorInfo,
52    version: getApiInfo(node).version,
53    basename: path.basename(fileName).replace(/\.d\.ts/g, ''),
54    level,
55    apiName: node.symbol ? node.symbol.escapedName : '',
56    apiFullText: node.getFullText(),
57  });
58
59  apiCheckInfoArr.push({
60    id: errorType.id,
61    level,
62    location: `${baseFileName}(line: ${posOfNode.line + 1}, col: ${posOfNode.character + 1})`,
63    filePath: baseFileName,
64    message: errorMessage,
65  });
66}
67exports.addAPICheckErrorLogs = addAPICheckErrorLogs;
68
69function checkMarkError(node, errorMessage, baseFileName) {
70  let needMasking = false;
71  let apiName = '';
72  if (node.name?.text) {
73    apiName = node.name.text;
74  } else if (node.escapedText) {
75    apiName = node.escapedText;
76  }
77  const apiText = node.getText().replace(/\r|\n|(\r\n)|\s/g, '');
78  const apiKindName = Object.keys(ts.SyntaxKind).find(k => ts.SyntaxKind[k] === node?.kind);
79  const apiParentKind = [apiKindName];
80  getParentkind(node, apiParentKind);
81
82  // unicode->json
83  const maskInfos = parseUnicodeConfig();
84  if (maskInfos === '') {
85    return needMasking;
86  }
87  maskInfos.maskInformations.forEach(maskInfo => {
88    if (maskInfo.kind === apiKindName &&
89      maskInfo.name === apiName &&
90      maskInfo.hierarchicalRelationship === JSON.stringify(apiParentKind) &&
91      maskInfo.text.replace(/\s/g, '') === apiText &&
92      maskInfo.errorMassage === errorMessage &&
93      JSON.stringify(maskInfo.fileName) === JSON.stringify(baseFileName.split(path.sep).join('\\'))) {
94      needMasking = true;
95    }
96  });
97  return needMasking;
98}
99
100function getParentkind(node, parentkindArr) {
101  if (ts.isSourceFile(node)) {
102    return;
103  }
104  if (ts.isSourceFile(node.parent)) {
105    parentkindArr.push(Object.keys(ts.SyntaxKind).find(k => ts.SyntaxKind[k] === node.parent.kind));
106    return;
107  }
108  if (!ts.isModuleBlock(node.parent)) {
109    parentkindArr.push(Object.keys(ts.SyntaxKind).find(k => ts.SyntaxKind[k] === node.parent.kind));
110    getParentkind(node.parent, parentkindArr);
111  } else if (ts.isModuleBlock(node.parent)) {
112    getParentkind(node.parent, parentkindArr);
113  }
114}
115exports.getParentkind = getParentkind;
116
117function parseUnicodeConfig() {
118  let maskInfos = '';
119  if (!fs.existsSync(path.resolve(__dirname, '../config/errorMaskWhiteList.txt'))) {
120    return maskInfos;
121  }
122  const maskInformations = fs.readFileSync(path.resolve(__dirname, '../config/errorMaskWhiteList.txt'), 'utf-8');
123  let maskInfoString = '';
124  if (maskInformations && maskInformations.indexOf('\\u') === -1) {
125    return JSON.parse(maskInfoString);
126  }
127  let valArr = maskInformations.split('\\u');
128  for (let j = 0; j < valArr.length; j++) {
129    if (valArr[j] === '') {
130      continue;
131    }
132    maskInfoString += String.fromCharCode(parseInt(valArr[j], 16));
133  }
134  maskInfos = JSON.parse(maskInfoString);
135  return maskInfos;
136}
137
138function string2unicode() {
139  const str = fs.readFileSync('../test/errorlist.json', 'utf-8');
140  let ret = '';
141  let ustr = '';
142
143  for (let i = 0; i < str.length; i++) {
144    let code = str.charCodeAt(i);
145    let code16 = code.toString(16);
146    if (code < 0xf) {
147      ustr = '\\u' + '000' + code16;
148    } else if (code < 0xff) {
149      ustr = '\\u' + '00' + code16;
150    } else if (code < 0xfff) {
151      ustr = '\\u' + '0' + code16;
152    } else {
153      ustr = '\\u' + code16;
154    }
155    ret += ustr;
156  }
157  fs.writeFileSync('errorlist.txt', ret);
158  return ret;
159}