• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2024 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 type * as ts from 'typescript';
17
18/**
19 * Returns diagnostics which appear in strict compilation mode only
20 */
21export function getStrictDiagnostics(
22  strictProgram: ts.Program,
23  nonStrictProgram: ts.Program,
24  fileName: string,
25  cancellationToken?: ts.CancellationToken
26): ts.Diagnostic[] {
27  // applying filter is a workaround for tsc bug
28  const strict = getAllDiagnostics(strictProgram, fileName, cancellationToken).filter((diag) => {
29    return !(diag.length === 0 && diag.start === 0);
30  });
31  const nonStrict = getAllDiagnostics(nonStrictProgram, fileName, cancellationToken);
32
33  // collect hashes for later easier comparison
34  const nonStrictHashes = nonStrict.reduce((result, value) => {
35    const hash = hashDiagnostic(value);
36    if (hash) {
37      result.add(hash);
38    }
39    return result;
40  }, new Set<string>());
41  // return diagnostics which weren't detected in non-strict mode
42  return strict.filter((value) => {
43    const hash = hashDiagnostic(value);
44    return hash && !nonStrictHashes.has(hash);
45  });
46}
47
48function getAllDiagnostics(
49  program: ts.Program,
50  fileName: string,
51  cancellationToken?: ts.CancellationToken
52): ts.Diagnostic[] {
53  const sourceFile = program.getSourceFile(fileName);
54  return program.getSemanticDiagnostics(sourceFile, cancellationToken).filter((diag) => {
55    return diag.file === sourceFile;
56  });
57}
58
59function hashDiagnostic(diagnostic: ts.Diagnostic): string | undefined {
60  if (diagnostic.start === undefined || diagnostic.length === undefined) {
61    return undefined;
62  }
63  return `${diagnostic.code}%${diagnostic.start}%${diagnostic.length}`;
64}
65