• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-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 */
15
16namespace ts {
17export namespace ArkTSLinter_1_1 {
18
19export interface ArkTSProgram {
20  builderProgram: BuilderProgram,
21  wasStrict: boolean
22}
23
24function makeDiag(category: DiagnosticCategory, code: number, file: SourceFile, start: number, length: number, messageText: string): Diagnostic {
25  return { category, code, file, start, length, messageText };
26}
27
28export function translateDiag(srcFile: SourceFile, problemInfo: ProblemInfo): Diagnostic {
29  const LINTER_MSG_CODE_START = -1;
30  const severity = (problemInfo.severity === Common.ProblemSeverity.ERROR ? DiagnosticCategory.Error : DiagnosticCategory.Warning);
31  return makeDiag(severity, LINTER_MSG_CODE_START /*+ problemInfo.ruleTag */, srcFile , problemInfo.start, (problemInfo.end - problemInfo.start + 1), problemInfo.rule);
32}
33
34export function runArkTSLinter(tsBuilderProgram: ArkTSProgram, reverseStrictBuilderProgram: ArkTSProgram,
35  srcFile?: SourceFile, buildInfoWriteFile?: WriteFileCallback): Diagnostic[] {
36  TypeScriptLinter.errorLineNumbersString = "";
37  TypeScriptLinter.warningLineNumbersString = "";
38  let diagnostics: Diagnostic[] = [];
39
40  LinterConfig.initStatic();
41
42  const tscDiagnosticsLinter = new TSCCompiledProgram(tsBuilderProgram, reverseStrictBuilderProgram);
43  const strictProgram = tscDiagnosticsLinter.getStrictProgram();
44  tscDiagnosticsLinter.doAllGetDiagnostics();
45
46  let srcFiles: SourceFile[] = [];
47  if(!!srcFile) {
48    srcFiles.push(srcFile);
49  }
50  else {
51    srcFiles = strictProgram.getSourceFiles() as SourceFile[];
52  }
53
54  const tscStrictDiagnostics = getTscDiagnostics(tscDiagnosticsLinter, srcFiles);
55
56  if (!!buildInfoWriteFile) {
57    tscDiagnosticsLinter.getStrictBuilderProgram().emitBuildInfo(buildInfoWriteFile);
58    tscDiagnosticsLinter.getNonStrictBuilderProgram().emitBuildInfo(buildInfoWriteFile);
59  }
60
61  TypeScriptLinter.initGlobals();
62
63  for(const fileToLint of srcFiles) {
64    TypeScriptLinter.initStatic();
65    if(TypeScriptLinter.lintEtsOnly && fileToLint.scriptKind !==ScriptKind.ETS) {
66      continue;
67    }
68
69    const linter = new TypeScriptLinter(fileToLint, strictProgram, tscStrictDiagnostics);
70    Utils.setTypeChecker(TypeScriptLinter.tsTypeChecker);
71    linter.lint();
72
73    // Get list of bad nodes from the current run.
74    const currentDiagnostics = tscStrictDiagnostics.get(fileToLint.fileName) ?? [];
75    TypeScriptLinter.problemsInfos.forEach(
76      (x) => currentDiagnostics.push(translateDiag(fileToLint, x))
77    );
78    diagnostics.push(...currentDiagnostics);
79  }
80
81  releaseReferences();
82  return diagnostics;
83}
84
85// reclaiming memory for Hvigor with "no-parallel" and "daemon", .
86function releaseReferences(): void {
87  TypeScriptLinter.clearTsTypeChecker();
88  Utils.clearTypeChecker();
89  Utils.clearTrueSymbolAtLocationCache();
90}
91
92/**
93 * Extracts TSC diagnostics emitted by strict checks.
94 * Function might be time-consuming, as it runs second compilation.
95 * @param sourceFiles AST of the processed files
96 * @param tscDiagnosticsLinter linter initialized with the processed program
97 * @returns problems found by TSC, mapped by `SourceFile.fileName` field
98 */
99function getTscDiagnostics(
100  tscDiagnosticsLinter: TSCCompiledProgram,
101  sourceFiles: SourceFile[],
102): Map<Diagnostic[]> {
103  const strictDiagnostics = new Map<string, Diagnostic[]>();
104  sourceFiles.forEach(file => {
105    const diagnostics = tscDiagnosticsLinter.getStrictDiagnostics(file.fileName);
106    if (diagnostics.length !== 0) {
107      strictDiagnostics.set(normalizePath(file.fileName), diagnostics);
108    }
109  });
110  return strictDiagnostics;
111}
112
113}
114}