• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 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 { faultsAttrs } from '../FaultAttrs';
17import { Logger } from '../Logger';
18import { FaultID } from '../Problems';
19import { ProblemSeverity } from '../ProblemSeverity';
20import type { ProblemInfo } from '../ProblemInfo';
21import { faultDesc } from '../FaultDesc';
22import type { FileStatistics } from './FileStatistics';
23import type { FileProblemStatistics } from './FileProblemStatistics';
24import type { ProjectStatistics } from './ProjectStatistics';
25
26export function log(...args: unknown[]): void {
27  let outLine = '';
28  for (let k = 0; k < args.length; k++) {
29    outLine += `${args[k]} `;
30  }
31  Logger.info(outLine);
32}
33
34function logReport(srcFileName: string, problemInfo: ProblemInfo): void {
35  const faultDescr = faultDesc[problemInfo.faultId];
36  const faultType = problemInfo.type;
37  Logger.info(
38    `Warning: ${srcFileName} (${problemInfo.line}, ${problemInfo.column}): ${faultDescr ? faultDescr : faultType}`
39  );
40}
41
42function logFileProblems(fileStats: FileStatistics): void {
43  for (const problem of fileStats.problems) {
44    logReport(fileStats.srcFileName, problem);
45  }
46}
47
48function countProblemStats(fileStats: FileStatistics): FileProblemStatistics {
49  let errors = 0;
50  let warnings = 0;
51  const errorLines = new Set<number>();
52  const warningLines = new Set<number>();
53  fileStats.problems.forEach((problemInfo: ProblemInfo) => {
54    const line = problemInfo.line;
55    switch (faultsAttrs[problemInfo.faultId].severity) {
56      case ProblemSeverity.ERROR: {
57        errors++;
58        errorLines.add(line);
59        break;
60      }
61      case ProblemSeverity.WARNING: {
62        warnings++;
63        warningLines.add(line);
64        break;
65      }
66      default:
67    }
68  });
69  const sortFunc = (a, b): number => {
70    return a - b;
71  };
72  let errorLineNumbersString = '';
73  Array.from(errorLines).
74    sort(sortFunc).
75    forEach((line) => {
76      errorLineNumbersString += line + ', ';
77    });
78  let warningLineNumbersString = '';
79  Array.from(warningLines).
80    sort(sortFunc).
81    forEach((line) => {
82      warningLineNumbersString += line + ', ';
83    });
84  return {
85    errors,
86    warnings,
87    errorLines: errorLines.size,
88    warningLines: warningLines.size,
89    errorLineNumbersString,
90    warningLineNumbersString
91  };
92}
93
94function logProblemFileInfo(fileStats: FileStatistics, problemStats: FileProblemStatistics): void {
95  if (problemStats.errors > 0) {
96    const errorRate = (problemStats.errors / fileStats.visitedNodes * 100).toFixed(2);
97    const warningRate = (problemStats.warnings / fileStats.visitedNodes * 100).toFixed(2);
98    log(fileStats.srcFileName, ': ', '\n\tError lines: ', problemStats.errorLineNumbersString);
99    log(fileStats.srcFileName, ': ', '\n\tWarning lines: ', problemStats.warningLineNumbersString);
100    log(
101      '\n\tError constructs (%): ',
102      errorRate,
103      '\t[ of ',
104      fileStats.visitedNodes,
105      ' constructs ], \t',
106      problemStats.errorLines,
107      ' lines'
108    );
109    log(
110      '\n\tWarning constructs (%): ',
111      warningRate,
112      '\t[ of ',
113      fileStats.visitedNodes,
114      ' constructs ], \t',
115      problemStats.warningLines,
116      ' lines'
117    );
118  }
119}
120
121function logTotalProblemsInfo(
122  totalErrors: number,
123  totalWarnings: number,
124  totalErrorLines: number,
125  totalWarningLines: number,
126  totalVisitedNodes: number
127): void {
128  const errorRate = (totalErrors / totalVisitedNodes * 100).toFixed(2);
129  const warningRate = (totalWarnings / totalVisitedNodes * 100).toFixed(2);
130  log('\nTotal error constructs (%): ', errorRate);
131  log('\nTotal warning constructs (%): ', warningRate);
132  log('\nTotal error lines:', totalErrorLines, ' lines\n');
133  log('\nTotal warning lines:', totalWarningLines, ' lines\n');
134}
135
136function logProblemsPercentageByFeatures(projectStats: ProjectStatistics, totalVisitedNodes: number): void {
137  log('\nPercent by features: ');
138  for (let i = 0; i < FaultID.LAST_ID; i++) {
139    let nodes = 0;
140    let lines = 0;
141    for (const fileStats of projectStats.fileStats) {
142      nodes += fileStats.nodeCounters[i];
143      lines += fileStats.lineCounters[i].size;
144    }
145    const pecentage = (nodes / totalVisitedNodes * 100).toFixed(2).padEnd(7, ' ');
146    log(faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]');
147  }
148}
149
150export function logStatistics(projectStats: ProjectStatistics): void {
151  let filesWithErrors = 0;
152  let totalErrors = 0;
153  let totalWarnings = 0;
154  let totalErrorLines = 0;
155  let totalWarningLines = 0;
156  let totalVisitedNodes = 0;
157
158  for (const fileStats of projectStats.fileStats) {
159    logFileProblems(fileStats);
160
161    const problemStats = countProblemStats(fileStats);
162    logProblemFileInfo(fileStats, problemStats);
163
164    if (problemStats.errors > 0) {
165      filesWithErrors++;
166    }
167
168    totalErrors += problemStats.errors;
169    totalWarnings += problemStats.warnings;
170    totalErrorLines += problemStats.errorLines;
171    totalWarningLines += problemStats.warningLines;
172    totalVisitedNodes += fileStats.visitedNodes;
173  }
174
175  log('\n\n\nFiles scanned: ', projectStats.fileStats.length);
176  log('\nFiles with problems: ', filesWithErrors);
177
178  logTotalProblemsInfo(totalErrors, totalWarnings, totalErrorLines, totalWarningLines, totalVisitedNodes);
179  logProblemsPercentageByFeatures(projectStats, totalVisitedNodes);
180}
181