From 524e34652f66e38aae2a158d6147ca8f8cb3f9f2 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Wed, 22 Jul 2026 00:09:04 +0200 Subject: [PATCH 1/8] feature/#88 warning suppression code actions --- README.md | 2 +- src/extension.ts | 23 +++++++++++++++- src/util/diagnostics.ts | 60 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 854c6b8..69bd3b1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - **Warning notes**: Display notes for warnings when those are available - **Dynamic config**: The extension supports running a script to generate arguments to pass to cppcheck. This can be done by including the command in the argument field wrapped with \@(), e.g. `--suppress=memleak:src/file1.cpp @(bash path/to/script.sh)`. The script is expected to output the argument(s) wrapped with \@(). If the script e.g. creates a project file it should print out as `@(--project=path/to/projectfile.json)`. This output will be spliced into the argument string as such: `--suppress=memleak:src/file1.cpp --project=path/to/projectfile.json`. -- **Warning suppression**: Warnings of a specific type can be supressed with the --supress flag in the argument field in the extension settings. The extension also supports inline suppression for specific lines of code, simply write `// cppcheck-supress >warning id<` (see image below). +- **Warning suppression**: Warnings of a specific type can be supressed with the --suppress flag in the argument field in the extension settings. The extension also supports inline suppression for specific lines of code, simply write `// cppcheck-suppress >warning id<` (see image below). ![Image showing how to suppress warnings](./images/suppression.png) ## Requirements diff --git a/src/extension.ts b/src/extension.ts index ab87963..dd96b06 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,7 +6,7 @@ import * as crypto from 'crypto'; import { documentationLinkMap, getPremiumCertLink } from './util/documentation'; import { runCommand } from './util/scripts'; import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path'; -import { diagnosticsUnion } from './util/diagnostics'; +import { CodeActionProvider, diagnosticsUnion } from './util/diagnostics'; // To keep track of document changes we save hashed versions of their content to this record let documentHashMemory : Record = {}; @@ -95,6 +95,17 @@ function getDocumentSha1(document: vscode.TextDocument): string { // This method is called when your extension is activated. // Your extension is activated the very first time the command is executed. export async function activate(context: vscode.ExtensionContext) { + context.subscriptions.push( + vscode.languages.registerCodeActionsProvider( + { pattern: "**/*" }, + new CodeActionProvider(), + { + providedCodeActionKinds: [ + vscode.CodeActionKind.QuickFix + ] + } + ) + ); // Register a command to push user to workspace settings from walkthrough context.subscriptions.push( @@ -108,6 +119,16 @@ export async function activate(context: vscode.ExtensionContext) { } ) ); + + // Register a command for suppressing a warning type + context.subscriptions.push( + vscode.commands.registerCommand( + "cppcheck-official.suppressWarningAll", + (diagnostic: vscode.Diagnostic) => { + console.log("Suppress", diagnostic); + } + ) + ); // ProgressIndicator status bar item to show when checks are running cppcheckProgressIndicator = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); diff --git a/src/util/diagnostics.ts b/src/util/diagnostics.ts index 0054b1a..0b18666 100644 --- a/src/util/diagnostics.ts +++ b/src/util/diagnostics.ts @@ -1,5 +1,65 @@ import * as vscode from 'vscode'; +export class CodeActionProvider implements vscode.CodeActionProvider { + provideCodeActions( + document: vscode.TextDocument, + range: vscode.Range, + context: vscode.CodeActionContext, + token: vscode.CancellationToken + ): vscode.CodeAction[] { + + const actions: vscode.CodeAction[] = []; + + for (const diagnostic of context.diagnostics) { + var diagnosticCode = diagnostic.code; + if (typeof(diagnosticCode) === "object" && typeof(diagnosticCode) !== null) { + diagnosticCode = diagnosticCode.value; + } + + // Set up one action for suppressing the specific warning on the line targeted by the diagnostic + const suppressAction = new vscode.CodeAction( + `Suppress warning for ${diagnosticCode} here`, + vscode.CodeActionKind.QuickFix + ); + + // Copy indentation from line affected by diagnostic + const lineText = document.lineAt(diagnostic.range.start.line).text; + const indent = lineText.match(/^\s*/)?.[0] ?? ""; + + // Insert suppression comment above affected line + const suppressLineEdit = new vscode.WorkspaceEdit(); + suppressLineEdit.insert( + document.uri, + new vscode.Position( + diagnostic.range.start.line, + 0, + ), + `${indent}// cppcheck-suppress ${diagnosticCode}\n` + ); + suppressAction.edit = suppressLineEdit; + suppressAction.diagnostics = [diagnostic]; + actions.push(suppressAction); + + // Set up one action for suppressing warning of a given type universally + const suppressTypeAction = new vscode.CodeAction( + `Suppress warning type ${diagnosticCode} universally`, + vscode.CodeActionKind.QuickFix + ); + + suppressTypeAction.command = { + command: "cppcheck-official.suppressWarningAll", + title: "Suppress warning here", + arguments: [diagnostic] + }; + + suppressTypeAction.diagnostics = [diagnostic]; + actions.push(suppressTypeAction); + } + + return actions; + } +} + export function diagnosticsUnion(diagnosticsA : vscode.Diagnostic[], diagnosticB : vscode.Diagnostic[]) : vscode.Diagnostic[] { const diagnosticsUnion = new Array; // Add all elements from diagnosticsA to result array From 17e928c825ff0cce4fd8c7da104571b47566fb51 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Wed, 22 Jul 2026 00:15:16 +0200 Subject: [PATCH 2/8] extracted codeActionProvider class to sepparate util file --- src/extension.ts | 3 +- src/util/codeActions.ts | 61 +++++++++++++++++++++++++++++++++++++++++ src/util/diagnostics.ts | 60 ---------------------------------------- 3 files changed, 63 insertions(+), 61 deletions(-) create mode 100644 src/util/codeActions.ts diff --git a/src/extension.ts b/src/extension.ts index dd96b06..e92b696 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,7 +6,8 @@ import * as crypto from 'crypto'; import { documentationLinkMap, getPremiumCertLink } from './util/documentation'; import { runCommand } from './util/scripts'; import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path'; -import { CodeActionProvider, diagnosticsUnion } from './util/diagnostics'; +import { diagnosticsUnion } from './util/diagnostics'; +import { CodeActionProvider } from './util/codeActions'; // To keep track of document changes we save hashed versions of their content to this record let documentHashMemory : Record = {}; diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts new file mode 100644 index 0000000..d235567 --- /dev/null +++ b/src/util/codeActions.ts @@ -0,0 +1,61 @@ +import * as vscode from 'vscode'; + +export class CodeActionProvider implements vscode.CodeActionProvider { + provideCodeActions( + document: vscode.TextDocument, + range: vscode.Range, + context: vscode.CodeActionContext, + token: vscode.CancellationToken + ): vscode.CodeAction[] { + + const actions: vscode.CodeAction[] = []; + + for (const diagnostic of context.diagnostics) { + var diagnosticCode = diagnostic.code; + if (typeof(diagnosticCode) === "object" && typeof(diagnosticCode) !== null) { + diagnosticCode = diagnosticCode.value; + } + + // Set up one action for suppressing the specific warning on the line targeted by the diagnostic + const suppressAction = new vscode.CodeAction( + `Suppress warning for ${diagnosticCode} here`, + vscode.CodeActionKind.QuickFix + ); + + // Copy indentation from line affected by diagnostic + const lineText = document.lineAt(diagnostic.range.start.line).text; + const indent = lineText.match(/^\s*/)?.[0] ?? ""; + + // Insert suppression comment above affected line + const suppressLineEdit = new vscode.WorkspaceEdit(); + suppressLineEdit.insert( + document.uri, + new vscode.Position( + diagnostic.range.start.line, + 0, + ), + `${indent}// cppcheck-suppress ${diagnosticCode}\n` + ); + suppressAction.edit = suppressLineEdit; + suppressAction.diagnostics = [diagnostic]; + actions.push(suppressAction); + + // Set up one action for suppressing warning of a given type universally + const suppressTypeAction = new vscode.CodeAction( + `Suppress warning type ${diagnosticCode} universally`, + vscode.CodeActionKind.QuickFix + ); + + suppressTypeAction.command = { + command: "cppcheck-official.suppressWarningAll", + title: "Suppress warning here", + arguments: [diagnostic] + }; + + suppressTypeAction.diagnostics = [diagnostic]; + actions.push(suppressTypeAction); + } + + return actions; + } +} \ No newline at end of file diff --git a/src/util/diagnostics.ts b/src/util/diagnostics.ts index 0b18666..0054b1a 100644 --- a/src/util/diagnostics.ts +++ b/src/util/diagnostics.ts @@ -1,65 +1,5 @@ import * as vscode from 'vscode'; -export class CodeActionProvider implements vscode.CodeActionProvider { - provideCodeActions( - document: vscode.TextDocument, - range: vscode.Range, - context: vscode.CodeActionContext, - token: vscode.CancellationToken - ): vscode.CodeAction[] { - - const actions: vscode.CodeAction[] = []; - - for (const diagnostic of context.diagnostics) { - var diagnosticCode = diagnostic.code; - if (typeof(diagnosticCode) === "object" && typeof(diagnosticCode) !== null) { - diagnosticCode = diagnosticCode.value; - } - - // Set up one action for suppressing the specific warning on the line targeted by the diagnostic - const suppressAction = new vscode.CodeAction( - `Suppress warning for ${diagnosticCode} here`, - vscode.CodeActionKind.QuickFix - ); - - // Copy indentation from line affected by diagnostic - const lineText = document.lineAt(diagnostic.range.start.line).text; - const indent = lineText.match(/^\s*/)?.[0] ?? ""; - - // Insert suppression comment above affected line - const suppressLineEdit = new vscode.WorkspaceEdit(); - suppressLineEdit.insert( - document.uri, - new vscode.Position( - diagnostic.range.start.line, - 0, - ), - `${indent}// cppcheck-suppress ${diagnosticCode}\n` - ); - suppressAction.edit = suppressLineEdit; - suppressAction.diagnostics = [diagnostic]; - actions.push(suppressAction); - - // Set up one action for suppressing warning of a given type universally - const suppressTypeAction = new vscode.CodeAction( - `Suppress warning type ${diagnosticCode} universally`, - vscode.CodeActionKind.QuickFix - ); - - suppressTypeAction.command = { - command: "cppcheck-official.suppressWarningAll", - title: "Suppress warning here", - arguments: [diagnostic] - }; - - suppressTypeAction.diagnostics = [diagnostic]; - actions.push(suppressTypeAction); - } - - return actions; - } -} - export function diagnosticsUnion(diagnosticsA : vscode.Diagnostic[], diagnosticB : vscode.Diagnostic[]) : vscode.Diagnostic[] { const diagnosticsUnion = new Array; // Add all elements from diagnosticsA to result array From 8c9c0f30e9af793bc99a822dde8a97b0f5e674b1 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Wed, 22 Jul 2026 15:59:50 +0200 Subject: [PATCH 3/8] basic functionality for writing suppression lines to project file --- src/extension.ts | 20 +++++++++++++++-- src/util/files.ts | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/util/files.ts diff --git a/src/extension.ts b/src/extension.ts index e92b696..ee64a8e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,6 +8,7 @@ import { runCommand } from './util/scripts'; import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path'; import { diagnosticsUnion } from './util/diagnostics'; import { CodeActionProvider } from './util/codeActions'; +import { writeSuppressionToProjectFile } from './util/files'; // To keep track of document changes we save hashed versions of their content to this record let documentHashMemory : Record = {}; @@ -18,6 +19,7 @@ let previewAnalysisTimer: NodeJS.Timeout | undefined; let previewedDocument: vscode.TextDocument | undefined; let cppcheckProgressIndicator: vscode.StatusBarItem; let checksRunning = false; +let cppcheckProjectFileUri: vscode.Uri | undefined; enum SeverityNumber { Info = 0, @@ -96,6 +98,7 @@ function getDocumentSha1(document: vscode.TextDocument): string { // This method is called when your extension is activated. // Your extension is activated the very first time the command is executed. export async function activate(context: vscode.ExtensionContext) { + // Set up code actions provider context.subscriptions.push( vscode.languages.registerCodeActionsProvider( { pattern: "**/*" }, @@ -125,8 +128,12 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand( "cppcheck-official.suppressWarningAll", - (diagnostic: vscode.Diagnostic) => { - console.log("Suppress", diagnostic); + async (warningType : String) => { + if (cppcheckProjectFileUri) { + await writeSuppressionToProjectFile(cppcheckProjectFileUri, warningType); + } else { + vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`); + } } ) ); @@ -321,6 +328,8 @@ async function runCppcheckOnFileXML( }); let usingProjectFile = false; + cppcheckProjectFileUri = undefined; + const args = [ '--enable=all', '--inline-suppr', @@ -330,9 +339,16 @@ async function runCppcheckOnFileXML( '--suppress=missingIncludeSystem', ...argsParsed, ].filter(Boolean); + if (processedArgs.includes("--project")) { usingProjectFile = true; args.push(`--file-filter=${filePath}`); + // If project file is of type .cppcheck we keep track of it + var projectFilePath = processedArgs.split('--project=')[1].split(' ')[0]; + var projectFileType = projectFilePath.split('.')[1]; + if (projectFileType.toLowerCase() === 'cppcheck') { + cppcheckProjectFileUri = vscode.Uri.file(projectFilePath); + } } else { args.push(filePath); } diff --git a/src/util/files.ts b/src/util/files.ts new file mode 100644 index 0000000..6bd6b77 --- /dev/null +++ b/src/util/files.ts @@ -0,0 +1,55 @@ +import * as vscode from 'vscode'; + +export async function writeSuppressionToProjectFile(projectFileUri : vscode.Uri, warningType : String) { + const fileType = projectFileUri.toString().split('.')[1]; + if (fileType !== 'cppcheck') { + throw new Error(`Function writeSuppressionToProjectFile only supports writing to .cppcheck project files! Recieved file is of type .${fileType}`); + } + + // Open project file with vscode workspace API + const document = await vscode.workspace.openTextDocument(projectFileUri); + const text = document.getText(); + const edit = new vscode.WorkspaceEdit(); + var textToInsert = ''; + var positionToInsertAt = 0; + + // Search for suppressions section + const match = /]*>([\s\S]*?)<\/suppressions>/m.exec(text); + if (match !== null) { + // match !== null -> Suppressions section exists + const closeIndex = text.indexOf(""); + + // Determine indentation and construct the new suppression line + const line = document.lineAt(document.positionAt(closeIndex).line - 1); + const indentation = line.text.match(/^\s*/)?.[0] ?? " "; + const newSuppressionLine = `\n${indentation}\n`; + + // We splice in the new line just before the end of the suppressions block + textToInsert = newSuppressionLine; + positionToInsertAt = closeIndex; + } else { + // match === null -> Suppressions section does not exist + const closeIndex = text.indexOf(""); + + // Determine indentation and construct the new suppressions block + const line = document.lineAt(document.positionAt(closeIndex).line - 1); + const indentation = line.text.match(/^\s*/)?.[0] ?? " "; + const suppressionsBlock = + `\n${indentation} + ${indentation} + ${indentation}\n`; + + // Splice in the new suppressions block just before the end of the project-file + textToInsert = suppressionsBlock; + positionToInsertAt = closeIndex; + } + + // Write file + edit.insert( + document.uri, + document.positionAt(positionToInsertAt), + textToInsert + ); + + await vscode.workspace.applyEdit(edit); +} \ No newline at end of file From cee230704b5b1c89bae3f15f1d034943a36d1e7d Mon Sep 17 00:00:00 2001 From: davidramnero Date: Wed, 22 Jul 2026 17:17:19 +0200 Subject: [PATCH 4/8] wip testing --- src/extension.ts | 12 ++++++++---- src/util/codeActions.ts | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index ee64a8e..9001e3a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -339,8 +339,8 @@ async function runCppcheckOnFileXML( '--suppress=missingIncludeSystem', ...argsParsed, ].filter(Boolean); - - if (processedArgs.includes("--project")) { + + if (processedArgs.includes("--project=")) { usingProjectFile = true; args.push(`--file-filter=${filePath}`); // If project file is of type .cppcheck we keep track of it @@ -349,12 +349,15 @@ async function runCppcheckOnFileXML( if (projectFileType.toLowerCase() === 'cppcheck') { cppcheckProjectFileUri = vscode.Uri.file(projectFilePath); } + console.log('cppcheckProjectFileUri', cppcheckProjectFileUri); } else { args.push(filePath); } let proc; const cwd = findWorkspaceRoot(); + console.log('command', commandPath, args); + console.log('cwd', cwd); proc = cp.spawn(commandPath, args, { cwd, }); @@ -400,9 +403,10 @@ async function runCppcheckOnFileXML( if (!isCriticalError && usingProjectFile && !filePath.endsWith(mainLoc.file)) { continue; } - + console.log('open file', mainLoc.file); + console.log('locations', locations); const mainLocDocument = await vscode.workspace.openTextDocument(mainLoc.file); - + console.log('file opnened'); // Cppcheck line number is 1-indexed, while VS Code uses 0-indexing let line = Number(mainLoc.line) - 1; // Invalid line number usually means non-analysis output diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index d235567..e9beef6 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -48,8 +48,8 @@ export class CodeActionProvider implements vscode.CodeActionProvider { suppressTypeAction.command = { command: "cppcheck-official.suppressWarningAll", - title: "Suppress warning here", - arguments: [diagnostic] + title: "Suppress warning universally", + arguments: [diagnosticCode] }; suppressTypeAction.diagnostics = [diagnostic]; From 7a0372900866929a8e5d3c881da6e7e553b31b7e Mon Sep 17 00:00:00 2001 From: davidramnero Date: Fri, 24 Jul 2026 12:04:13 +0200 Subject: [PATCH 5/8] added hide warning code actions --- src/extension.ts | 46 +++++++++++++++++++++++++++++++++++------ src/util/codeActions.ts | 34 ++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 21bfcb1..0a56e13 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -97,7 +97,11 @@ function getDocumentSha1(document: vscode.TextDocument): string { // This method is called when your extension is activated. // Your extension is activated the very first time the command is executed. -export async function activate(context: vscode.ExtensionContext) { +export async function activate(context: vscode.ExtensionContext) { + // Create a diagnostic collection. + const diagnosticCollection = vscode.languages.createDiagnosticCollection("Cppcheck"); + context.subscriptions.push(diagnosticCollection); + // Set up code actions provider context.subscriptions.push( vscode.languages.registerCodeActionsProvider( @@ -130,7 +134,6 @@ export async function activate(context: vscode.ExtensionContext) { "cppcheck-official.suppressWarningAll", async (warningType : String) => { if (cppcheckProjectFileUri) { - console.log('writeSuppressionToProjectFile'); const success = await writeSuppressionToProjectFile(cppcheckProjectFileUri, warningType); if (success) { vscode.window.showInformationMessage(`Suppression of ${warningType} added to project file ${cppcheckProjectFileUri.toString()}`); @@ -144,14 +147,45 @@ export async function activate(context: vscode.ExtensionContext) { ) ); + // Register a command for hiding a warning + context.subscriptions.push( + vscode.commands.registerCommand( + "cppcheck-official.hideWarning", + async (uri : vscode.Uri, diagnosticCode : string, range : vscode.Range) => { + const diagnostics = diagnosticCollection.get(uri); + const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => { + if (diagnostic.code === diagnosticCode && diagnostic.range.isEqual(range)) { + return false; + } + return true; + }); + diagnosticCollection.set(uri, filteredDiagnostics); + } + ) + ); + + // Register a command for hiding all warnings of a given type + context.subscriptions.push( + vscode.commands.registerCommand( + "cppcheck-official.hideWarningType", + async (diagnosticCode : string) => { + diagnosticCollection.forEach((uri : vscode.Uri, diagnostics : readonly vscode.Diagnostic[], collection : vscode.DiagnosticCollection) => { + const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => { + if (diagnostic.code === diagnosticCode) { + return false; + } + return true; + }); + collection.set(uri, filteredDiagnostics); + }); + } + ) + ); + // ProgressIndicator status bar item to show when checks are running cppcheckProgressIndicator = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10); context.subscriptions.push(cppcheckProgressIndicator); - // Create a diagnostic collection. - const diagnosticCollection = vscode.languages.createDiagnosticCollection("Cppcheck"); - context.subscriptions.push(diagnosticCollection); - function clearDiagnosticForDoc(doc: vscode.TextDocument): void { // Any file who was warnings generated from (and only from) the closed doc have their diagnostics cleared // NOTE: This includes the closed doc - its diagnostics will only be cleared if its warnings only come from analysis of it itself diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index e9beef6..1c4cbb1 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -18,7 +18,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider { // Set up one action for suppressing the specific warning on the line targeted by the diagnostic const suppressAction = new vscode.CodeAction( - `Suppress warning for ${diagnosticCode} here`, + `Suppress this ${diagnosticCode} warning`, vscode.CodeActionKind.QuickFix ); @@ -40,7 +40,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider { suppressAction.diagnostics = [diagnostic]; actions.push(suppressAction); - // Set up one action for suppressing warning of a given type universally + // Set up an action for suppressing warning of a given type universally const suppressTypeAction = new vscode.CodeAction( `Suppress warning type ${diagnosticCode} universally`, vscode.CodeActionKind.QuickFix @@ -54,6 +54,36 @@ export class CodeActionProvider implements vscode.CodeActionProvider { suppressTypeAction.diagnostics = [diagnostic]; actions.push(suppressTypeAction); + + // Set up an action for hiding a warning + const hideAction = new vscode.CodeAction( + `Hide this ${diagnosticCode} warning`, + vscode.CodeActionKind.QuickFix + ); + + hideAction.command = { + command: "cppcheck-official.hideWarning", + title: "Hide warning", + arguments: [document.uri, diagnosticCode, diagnostic.range] + }; + + hideAction.diagnostics = [diagnostic]; + actions.push(hideAction); + + // Set up an action for hiding all warnings of a given type + const hideTypeAction = new vscode.CodeAction( + `Hide all ${diagnosticCode} warnings`, + vscode.CodeActionKind.QuickFix + ); + + hideTypeAction.command = { + command: "cppcheck-official.hideWarningType", + title: "Hide warning type", + arguments: [diagnosticCode] + }; + + hideTypeAction.diagnostics = [diagnostic]; + actions.push(hideTypeAction); } return actions; From 4ea99a262224cafebc8cf6737e1d85bb21f03e91 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Fri, 24 Jul 2026 12:06:17 +0200 Subject: [PATCH 6/8] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69bd3b1..0c2e6e8 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - **Warning notes**: Display notes for warnings when those are available - **Dynamic config**: The extension supports running a script to generate arguments to pass to cppcheck. This can be done by including the command in the argument field wrapped with \@(), e.g. `--suppress=memleak:src/file1.cpp @(bash path/to/script.sh)`. The script is expected to output the argument(s) wrapped with \@(). If the script e.g. creates a project file it should print out as `@(--project=path/to/projectfile.json)`. This output will be spliced into the argument string as such: `--suppress=memleak:src/file1.cpp --project=path/to/projectfile.json`. -- **Warning suppression**: Warnings of a specific type can be supressed with the --suppress flag in the argument field in the extension settings. The extension also supports inline suppression for specific lines of code, simply write `// cppcheck-suppress >warning id<` (see image below). +- **Warning suppression**: Warnings of a specific type can be supressed with the --suppress flag in the argument field in the extension settings. The extension also supports inline suppression for specific lines of code, simply write `// cppcheck-suppress >warning id<` (see image below). Suppressions can also be added through code actions, either as automatically generated inline suppressions or, if you are using a project file, as universal suppressions specified in your project file. ![Image showing how to suppress warnings](./images/suppression.png) ## Requirements From 4cb2c300f06a52fa2e5566ba036bd331cc105acc Mon Sep 17 00:00:00 2001 From: davidramnero Date: Fri, 24 Jul 2026 13:30:26 +0200 Subject: [PATCH 7/8] update code action description based on PR feedback --- src/util/codeActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index 1c4cbb1..7398035 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -18,7 +18,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider { // Set up one action for suppressing the specific warning on the line targeted by the diagnostic const suppressAction = new vscode.CodeAction( - `Suppress this ${diagnosticCode} warning`, + `Add comment that suppresses this ${diagnosticCode} warning`, vscode.CodeActionKind.QuickFix ); @@ -42,7 +42,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider { // Set up an action for suppressing warning of a given type universally const suppressTypeAction = new vscode.CodeAction( - `Suppress warning type ${diagnosticCode} universally`, + `Suppress warning type ${diagnosticCode} universally (in project file)`, vscode.CodeActionKind.QuickFix ); From 9173f07006076d578dc7c17aed52c10457a1b068 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Fri, 24 Jul 2026 14:16:28 +0200 Subject: [PATCH 8/8] also hide warnings when suppressions are added for them --- src/extension.ts | 21 +++++++++++++++------ src/util/codeActions.ts | 7 +++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 0a56e13..a83b74b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -132,13 +132,14 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand( "cppcheck-official.suppressWarningAll", - async (warningType : String) => { + async (diagnosticCode : string) => { if (cppcheckProjectFileUri) { - const success = await writeSuppressionToProjectFile(cppcheckProjectFileUri, warningType); + const success = await writeSuppressionToProjectFile(cppcheckProjectFileUri, diagnosticCode); if (success) { - vscode.window.showInformationMessage(`Suppression of ${warningType} added to project file ${cppcheckProjectFileUri.toString()}`); + vscode.window.showInformationMessage(`Suppression of ${diagnosticCode} added to project file ${cppcheckProjectFileUri.toString()}`); + await vscode.commands.executeCommand('cppcheck-official.hideWarningType', diagnosticCode); } else { - vscode.window.showErrorMessage(`Failed to add suppression of ${warningType} to project file ${cppcheckProjectFileUri.toString()}`); + vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${cppcheckProjectFileUri.toString()}`); } } else { vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`); @@ -154,7 +155,11 @@ export async function activate(context: vscode.ExtensionContext) { async (uri : vscode.Uri, diagnosticCode : string, range : vscode.Range) => { const diagnostics = diagnosticCollection.get(uri); const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => { - if (diagnostic.code === diagnosticCode && diagnostic.range.isEqual(range)) { + var code = diagnostic.code; + if (typeof(code) === "object" && typeof(code) !== null) { + code = code.value; + } + if (code === diagnosticCode && diagnostic.range.isEqual(range)) { return false; } return true; @@ -171,7 +176,11 @@ export async function activate(context: vscode.ExtensionContext) { async (diagnosticCode : string) => { diagnosticCollection.forEach((uri : vscode.Uri, diagnostics : readonly vscode.Diagnostic[], collection : vscode.DiagnosticCollection) => { const filteredDiagnostics = diagnostics?.filter((diagnostic : vscode.Diagnostic) => { - if (diagnostic.code === diagnosticCode) { + var code = diagnostic.code; + if (typeof(code) === "object" && typeof(code) !== null) { + code = code.value; + } + if (code === diagnosticCode) { return false; } return true; diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index 7398035..be6870b 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -37,6 +37,13 @@ export class CodeActionProvider implements vscode.CodeActionProvider { `${indent}// cppcheck-suppress ${diagnosticCode}\n` ); suppressAction.edit = suppressLineEdit; + + // For inline suppression we also hide the warning so user does not have to rerun analysis for it to disappear + suppressAction.command = { + command: "cppcheck-official.hideWarning", + title: "Hide warning", + arguments: [document.uri, diagnosticCode, diagnostic.range] + }; suppressAction.diagnostics = [diagnostic]; actions.push(suppressAction);