Skip to content

Commit

Permalink
report baselined errors that can be represented with a hint diagnosti…
Browse files Browse the repository at this point in the history
…c (eg. unused, deprecated) as such
  • Loading branch information
DetachHead committed Aug 29, 2024
1 parent bb7af61 commit f9a944f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 deletions.
60 changes: 41 additions & 19 deletions packages/pyright-internal/src/baseline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { FileDiagnostics } from './common/diagnosticSink';
import { Range } from './common/textRange';
import { mkdirSync, readFileSync, writeFileSync } from 'fs';
import { Uri } from './common/uri/uri';
import { DiagnosticCategory } from './common/diagnostic';
import { convertLevelToCategory, Diagnostic, DiagnosticCategory } from './common/diagnostic';
import { extraOptionDiagnosticRules } from './common/configOptions';

interface BaselineFile {
files: {
Expand Down Expand Up @@ -79,33 +80,54 @@ export const getBaselinedErrors = (rootDir: Uri): BaselineFile => {
return JSON.parse(baselineFileContents);
};

interface FileDiagnosticsWithBaselineInfo extends FileDiagnostics {
containsNewErrors: boolean;
}

export const filterOutBaselinedDiagnostics = (
rootDir: Uri,
filesWithDiagnostics: readonly FileDiagnostics[]
): FileDiagnostics[] => {
): FileDiagnosticsWithBaselineInfo[] => {
const baselineFile = getBaselinedErrors(rootDir);
return filesWithDiagnostics.map((fileWithDiagnostics) => {
const baselinedErrorsForFile =
baselineFile.files[rootDir.getRelativePath(fileWithDiagnostics.fileUri)!.toString()];
if (!baselinedErrorsForFile) {
return fileWithDiagnostics;
return { ...fileWithDiagnostics, containsNewErrors: true };
}
return {
...fileWithDiagnostics,
diagnostics: fileWithDiagnostics.diagnostics.filter((diagnostic) => {
const matchedIndex = baselinedErrorsForFile.findIndex(
(baselinedError) =>
baselinedError.code === diagnostic.getRule() &&
baselinedError.range.start.character === diagnostic.range.start.character &&
baselinedError.range.end.character === diagnostic.range.end.character
);
if (matchedIndex >= 0) {
baselinedErrorsForFile.splice(matchedIndex, 1);
return false;
} else {
return true;
const filteredDiagnostics = [];
let containsNewErrors = false;
for (let diagnostic of fileWithDiagnostics.diagnostics) {
const diagnosticRule = diagnostic.getRule() as DiagnosticRule | undefined;
const matchedIndex = baselinedErrorsForFile.findIndex(
(baselinedError) =>
baselinedError.code === diagnosticRule &&
baselinedError.range.start.character === diagnostic.range.start.character &&
baselinedError.range.end.character === diagnostic.range.end.character
);
if (matchedIndex >= 0) {
baselinedErrorsForFile.splice(matchedIndex, 1);
// if the baselined error can be reported as a hint (eg. unreachable/deprecated), keep it and change its diagnostic to that instead
if (diagnosticRule) {
for (const { name, get } of extraOptionDiagnosticRules) {
if (get().includes(diagnosticRule)) {
diagnostic = new Diagnostic(
convertLevelToCategory(name),
diagnostic.message,
diagnostic.range,
diagnostic.priority
);
filteredDiagnostics.push(diagnostic);
// none of these rules should have multiple extra diagnostic levels so we break after the first match
break;
}
}
}
}),
};
} else {
containsNewErrors = true;
filteredDiagnostics.push(diagnostic);
}
}
return { ...fileWithDiagnostics, diagnostics: filteredDiagnostics, containsNewErrors };
});
};
14 changes: 12 additions & 2 deletions packages/pyright-internal/src/common/diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { Commands } from '../commands/commands';
import { appendArray } from './collectionUtils';
import { DiagnosticLevel } from './configOptions';
import { LspDiagnosticLevel } from './configOptions';
import { Range, TextRange } from './textRange';
import { Uri } from './uri/uri';

Expand Down Expand Up @@ -43,7 +43,7 @@ export const enum DiagnosticCategory {
TaskItem,
}

export function convertLevelToCategory(level: DiagnosticLevel) {
export function convertLevelToCategory(level: LspDiagnosticLevel) {
switch (level) {
case 'error':
return DiagnosticCategory.Error;
Expand All @@ -54,7 +54,17 @@ export function convertLevelToCategory(level: DiagnosticLevel) {
case 'information':
return DiagnosticCategory.Information;

case 'unreachable':
return DiagnosticCategory.UnreachableCode;

case 'unused':
return DiagnosticCategory.UnusedCode;

case 'deprecated':
return DiagnosticCategory.Deprecated;

default:
level satisfies 'none';
throw new Error(`${level} is not expected`);
}
}
Expand Down
3 changes: 1 addition & 2 deletions packages/pyright-internal/src/languageServerBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1180,8 +1180,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
const baselineFile = getBaselinedErrors(rootUri);
const fileKey = rootUri.getRelativePath(fileUri)!;
const diagnosticsForFile = this.documentsWithDiagnostics[params.textDocument.uri];
const newDiagnostics = filterOutBaselinedDiagnostics(rootUri, [diagnosticsForFile])[0];
if (newDiagnostics.diagnostics.length) {
if (diagnosticsForFile && filterOutBaselinedDiagnostics(rootUri, [diagnosticsForFile])[0].containsNewErrors) {
// there are new diagnostics that haven't been baselined, so we don't want to write them
// because the user will have to either fix the diagnostics or explicitly write them to the
// baseline themselves
Expand Down

0 comments on commit f9a944f

Please sign in to comment.