Skip to content

Commit 428f042

Browse files
committed
fix / avoid throwing out hidden and filtered diagnostics
1 parent ff6e24a commit 428f042

2 files changed

Lines changed: 56 additions & 39 deletions

File tree

‎src/extension.ts‎

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -75,24 +75,10 @@ function severityToNumber(sev: vscode.DiagnosticSeverity): SeverityNumber {
7575
}
7676
}
7777

78-
function parseMinSeverity(str: string): SeverityNumber {
79-
switch (str.toLowerCase()) {
80-
case "error": return SeverityNumber.Error;
81-
case "warning": return SeverityNumber.Warning;
82-
default: return SeverityNumber.Info;
83-
}
84-
}
85-
86-
function filterOutDiagnosticsBelowSeverityLevel(diagnosticCollection : vscode.DiagnosticCollection, severity : vscode.DiagnosticSeverity) {
87-
diagnosticCollection.forEach((uri : vscode.Uri, diagnostics : readonly vscode.Diagnostic[], collection: vscode.DiagnosticCollection) => {
88-
const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => {
89-
if (severityToNumber(diagnostic.severity) < severityToNumber(severity)) {
90-
return false;
91-
}
92-
return true;
93-
});
94-
collection.set(uri, filteredDiagnostics);
95-
});
78+
function setDiagnosticHiddenStatus(diagnostic : vscode.Diagnostic, hiddenStatus : boolean) {
79+
var metadata = diagnosticMetadataStore.get(diagnostic);
80+
const newMetaData = { ...metadata, hidden: hiddenStatus };
81+
diagnosticMetadataStore.set(diagnostic, newMetaData);
9682
}
9783

9884
function updateProgressIndicator(): void {
@@ -127,6 +113,35 @@ export async function activate(context: vscode.ExtensionContext) {
127113
// Create a diagnostic collection.
128114
const diagnosticCollection = vscode.languages.createDiagnosticCollection("Cppcheck");
129115
context.subscriptions.push(diagnosticCollection);
116+
117+
// Create a map for storing all diagnostics, including hidden / filtered diagnostics
118+
const uriDiagnosticsMap = new Map<vscode.Uri, vscode.Diagnostic[]>();
119+
120+
function filterDisplayedDiagnosticsBasedOnHiddenStatus() {
121+
uriDiagnosticsMap.forEach((diagnostics : vscode.Diagnostic[], uri : vscode.Uri) => {
122+
const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => {
123+
var metadata = diagnosticMetadataStore.get(diagnostic);
124+
if (metadata?.hidden) {
125+
return false;
126+
}
127+
return true;
128+
});
129+
diagnosticCollection.set(uri, filteredDiagnostics);
130+
});
131+
}
132+
133+
function hideDiagnosticsBasedOnSeverityLevel(severity : vscode.DiagnosticSeverity) {
134+
uriDiagnosticsMap.forEach((diagnostics : vscode.Diagnostic[]) => {
135+
diagnostics?.forEach((diagnostic : vscode.Diagnostic) => {
136+
if (severityToNumber(diagnostic.severity) < severityToNumber(severity)) {
137+
setDiagnosticHiddenStatus(diagnostic, true);
138+
} else {
139+
setDiagnosticHiddenStatus(diagnostic, false);
140+
}
141+
});
142+
});
143+
filterDisplayedDiagnosticsBasedOnHiddenStatus();
144+
}
130145

131146
// Set up code actions provider
132147
context.subscriptions.push(
@@ -189,18 +204,17 @@ export async function activate(context: vscode.ExtensionContext) {
189204
vscode.commands.registerCommand(
190205
"cppcheck-official.hideWarning",
191206
async (uri : vscode.Uri, diagnosticCode : string, range : vscode.Range) => {
192-
const diagnostics = diagnosticCollection.get(uri);
193-
const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => {
207+
const diagnostics = uriDiagnosticsMap.get(uri);
208+
diagnostics?.forEach((diagnostic : vscode.Diagnostic) => {
194209
var code = diagnostic.code;
195210
if (typeof(code) === "object" && typeof(code) !== null) {
196211
code = code.value;
197212
}
198213
if (code === diagnosticCode && diagnostic.range.isEqual(range)) {
199-
return false;
214+
setDiagnosticHiddenStatus(diagnostic, true);
200215
}
201-
return true;
202216
});
203-
diagnosticCollection.set(uri, filteredDiagnostics);
217+
filterDisplayedDiagnosticsBasedOnHiddenStatus();
204218
}
205219
)
206220
);
@@ -210,19 +224,18 @@ export async function activate(context: vscode.ExtensionContext) {
210224
vscode.commands.registerCommand(
211225
"cppcheck-official.hideWarningType",
212226
async (diagnosticCode : string) => {
213-
diagnosticCollection.forEach((uri : vscode.Uri, diagnostics : readonly vscode.Diagnostic[], collection : vscode.DiagnosticCollection) => {
214-
const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => {
227+
uriDiagnosticsMap.forEach((diagnostics : readonly vscode.Diagnostic[]) => {
228+
diagnostics?.forEach((diagnostic : vscode.Diagnostic) => {
215229
var code = diagnostic.code;
216230
if (typeof(code) === "object" && typeof(code) !== null) {
217231
code = code.value;
218232
}
219233
if (code === diagnosticCode) {
220-
return false;
234+
setDiagnosticHiddenStatus(diagnostic, true);
221235
}
222-
return true;
223236
});
224-
collection.set(uri, filteredDiagnostics);
225237
});
238+
filterDisplayedDiagnosticsBasedOnHiddenStatus();
226239
}
227240
)
228241
);
@@ -315,7 +328,7 @@ export async function activate(context: vscode.ExtensionContext) {
315328
);
316329

317330
// Clear diagnostics below severity level selected from the problems tab
318-
filterOutDiagnosticsBelowSeverityLevel(diagnosticCollection, parseSeverity(selection.value));
331+
hideDiagnosticsBasedOnSeverityLevel(parseSeverity(selection.value));
319332

320333
updateMinSeverityOption();
321334
}
@@ -382,7 +395,6 @@ export async function activate(context: vscode.ExtensionContext) {
382395

383396
const config = vscode.workspace.getConfiguration();
384397
const isEnabled = config.get<boolean>("cppcheck-official.enable", true);
385-
const minSevString = config.get<string>("cppcheck-official.minSeverity", "info");
386398
const userPath = config.get<string>("cppcheck-official.path")?.trim() || "";
387399
const commandPath = userPath ? resolvePath(userPath) : "cppcheck";
388400

@@ -425,9 +437,12 @@ export async function activate(context: vscode.ExtensionContext) {
425437
document,
426438
commandPath,
427439
processedArgs,
428-
minSevString,
429-
diagnosticCollection
440+
uriDiagnosticsMap,
430441
);
442+
443+
// Diagnostics from analysis are stored in DiagnosticCollectionAll, the displayed diagnostic collection
444+
// is diagnosticCollection, which is set by the filter function filterDisplayedDiagnosticsBasedOnHiddenStatus()
445+
filterDisplayedDiagnosticsBasedOnHiddenStatus();
431446
}
432447

433448
// Listen for file saves.
@@ -496,18 +511,19 @@ async function runCppcheckOnFileXML(
496511
document: vscode.TextDocument,
497512
commandPath: string,
498513
processedArgs: string,
499-
minSevString: string,
500-
diagnosticCollection: vscode.DiagnosticCollection
514+
uriDiagnosticsMap: Map<vscode.Uri, vscode.Diagnostic[]>,
501515
): Promise<void> {
502516
checksRunning = true;
503517
updateProgressIndicator();
504518

505519
// Clear existing diagnostics for this file
506-
diagnosticCollection.delete(document.uri);
520+
uriDiagnosticsMap.delete(document.uri);
507521

508522
// Replace backslashes (used in paths in Windows environment)
509523
const filePath = document.fileName.replaceAll('\\', '/');
510-
const minSevNum = parseMinSeverity(minSevString);
524+
525+
// We always call cppcheck with severity level info, and then filter warnings when displaying them
526+
const minSevNum = SeverityNumber.Info;
511527

512528
// Resolve paths for arguments where applicable
513529
const argsParsed = processedArgs.split(" ").map((arg) => {
@@ -638,7 +654,7 @@ async function runCppcheckOnFileXML(
638654
// Save line of code at main location if we can access it
639655
const mainLocLine = mainLocDocument?.lineAt(line)?.text ?? '';
640656

641-
diagnosticMetadataStore.set(diagnostic, {symbolName, mainLocLine});
657+
diagnosticMetadataStore.set(diagnostic, { symbolName, mainLocLine, hidden: false });
642658

643659
// Related Information
644660
const relatedInfos: vscode.DiagnosticRelatedInformation[] = [];
@@ -708,11 +724,11 @@ async function runCppcheckOnFileXML(
708724
for (const uri of Object.keys(diagnostics)) {
709725
var newDiagnostics = diagnostics[uri];
710726
// If file has existing diagnostics from analyzing other files we do not want to overwrite those
711-
const existingDiagnostics = diagnosticCollection.get(vscode.Uri.parse(uri));
727+
const existingDiagnostics = uriDiagnosticsMap.get(vscode.Uri.parse(uri));
712728
if (existingDiagnostics) {
713729
newDiagnostics = diagnosticsUnion(newDiagnostics, existingDiagnostics.flat());
714730
}
715-
diagnosticCollection.set(vscode.Uri.parse(uri), newDiagnostics);
731+
uriDiagnosticsMap.set(vscode.Uri.parse(uri), newDiagnostics);
716732
if (fileRelationMap[uri] === null ||fileRelationMap[uri] === undefined) {
717733
fileRelationMap[uri] = new Set;
718734
}

‎src/util/diagnostics.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as vscode from 'vscode';
33
interface DiagnosticMetadata {
44
symbolName?: string;
55
mainLocLine?: string;
6+
hidden: boolean;
67
}
78

89
export class DiagnosticMetadataStore {

0 commit comments

Comments
 (0)