From 029bfa7b4ed37a3318d67b44dfff75dc29205292 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Thu, 6 Aug 2026 16:17:41 +0200 Subject: [PATCH 1/2] fix/ only show code actions related to project file if project file is present --- src/extension.ts | 20 ++++++----- src/util/codeActions.ts | 75 ++++++++++++++++++++++------------------- src/util/files.ts | 16 +++++++++ 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 9ef0a46..9610144 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,7 +8,7 @@ import { runCommand } from './util/scripts'; import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path'; import { DiagnosticMetadataStore, diagnosticsUnion } from './util/diagnostics'; import { CodeActionProvider } from './util/codeActions'; -import { writeSuppressionToProjectFile } from './util/files'; +import { ProjectFileStore, writeSuppressionToProjectFile } from './util/files'; // To keep track of document changes we save hashed versions of their content to this record let documentHashMemory : Record = {}; @@ -16,13 +16,14 @@ let documentHashMemory : Record = {}; let fileRelationMap: Record> = {}; // Some diagnostics have symbol names associated with them, which we keep track of in diagnosticMetadataStore const diagnosticMetadataStore = new DiagnosticMetadataStore(); +// The ProjectFileStore is usd to keep track of the users project file through different context +const projectFileStore = new ProjectFileStore(); let previewAnalysisTimer: NodeJS.Timeout | undefined; let previewedDocument: vscode.TextDocument | undefined; let cppcheckProgressIndicator: vscode.StatusBarItem; let severityOption: vscode.StatusBarItem; let checksRunning = false; -let cppcheckProjectFileUri: vscode.Uri | undefined; enum SeverityNumber { Info = 0, @@ -131,7 +132,7 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.languages.registerCodeActionsProvider( { pattern: "**/*" }, - new CodeActionProvider(diagnosticMetadataStore), + new CodeActionProvider(diagnosticMetadataStore, projectFileStore), { providedCodeActionKinds: [ vscode.CodeActionKind.QuickFix @@ -158,14 +159,15 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand( "cppcheck-official.suppressWarningAll", async (diagnosticCode : string, file? : string, symbolName? : string) => { - if (cppcheckProjectFileUri) { - const success = await writeSuppressionToProjectFile(cppcheckProjectFileUri, diagnosticCode, file, symbolName); + const projectFileUri = projectFileStore.getUri(); + if (projectFileUri) { + const success = await writeSuppressionToProjectFile(projectFileUri, diagnosticCode, file, symbolName); if (success) { // Construct information message to display to the user const fileMessagePart = file ? ` for file ${file}` : ''; const symbolNameMessagePart = symbolName ? ` for symbol name ${symbolName}` : ''; const fileOrSymbolExtraMessage = file || symbolName ? '. Note: you have to re-analyze the file for the suppression to take effect.' : ''; - const completeInformationMessageText = `Suppression of ${diagnosticCode} added to project file ${cppcheckProjectFileUri.toString()}${fileMessagePart}${symbolNameMessagePart}${fileOrSymbolExtraMessage}`; + const completeInformationMessageText = `Suppression of ${diagnosticCode} added to project file ${projectFileStore.getUri()?.toString()}${fileMessagePart}${symbolNameMessagePart}${fileOrSymbolExtraMessage}`; vscode.window.showInformationMessage(completeInformationMessageText); // Only hide warnings if suppression is global, since hide command does not support file or symbol filter for now @@ -173,7 +175,7 @@ export async function activate(context: vscode.ExtensionContext) { await vscode.commands.executeCommand('cppcheck-official.hideWarningType', diagnosticCode); } } else { - vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${cppcheckProjectFileUri.toString()}`); + vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${projectFileStore.getUri()?.toString()}`); } } else { vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`); @@ -520,7 +522,7 @@ async function runCppcheckOnFileXML( }); let usingProjectFile = false; - cppcheckProjectFileUri = undefined; + projectFileStore.clear(); const args = [ '--enable=all', @@ -536,7 +538,7 @@ async function runCppcheckOnFileXML( var projectFilePath = processedArgs.split('--project=')[1].split(' ')[0]; var projectFileType = projectFilePath.split('.')[1]; if (projectFileType.toLowerCase() === 'cppcheck') { - cppcheckProjectFileUri = vscode.Uri.file(projectFilePath); + projectFileStore.setUri(vscode.Uri.file(projectFilePath)); } } else { args.push( diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index 0435e84..27a2e3c 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -1,8 +1,10 @@ import * as vscode from 'vscode'; import { DiagnosticMetadataStore } from './diagnostics'; +import { ProjectFileStore } from './files'; export class CodeActionProvider implements vscode.CodeActionProvider { constructor( - private readonly metadataStore: DiagnosticMetadataStore + private readonly metadataStore: DiagnosticMetadataStore, + private readonly projectFileStore: ProjectFileStore ) {} provideCodeActions( document: vscode.TextDocument, @@ -55,39 +57,6 @@ export class CodeActionProvider implements vscode.CodeActionProvider { suppressAction.diagnostics = [diagnostic]; actions.push(suppressAction); - // Set up an action for suppressing warning of a given type universally - const suppressTypeAction = new vscode.CodeAction( - `Suppress warning type ${diagnosticCode} universally (in project file)`, - vscode.CodeActionKind.QuickFix - ); - - suppressTypeAction.command = { - command: "cppcheck-official.suppressWarningAll", - title: "Suppress warning universally", - arguments: [diagnosticCode] - }; - - suppressTypeAction.diagnostics = [diagnostic]; - actions.push(suppressTypeAction); - - // Set up an action for suppressing warning based on file or symbol name - const symbol = this.metadataStore.get(diagnostic)?.symbolName; - const suppressAdvancedAction = new vscode.CodeAction( - symbol - ? `Suppress warning ${diagnosticCode} based on file and / or symbol` - :`Suppress warning ${diagnosticCode} based on file`, - vscode.CodeActionKind.QuickFix - ); - - suppressAdvancedAction.command = { - command: "cppcheck-official.suppressWarningAdvanced", - title: "Suppress warning advanced", - arguments: [diagnosticCode, document, diagnostic] - }; - - suppressAdvancedAction.diagnostics = [diagnostic]; - actions.push(suppressAdvancedAction); - // Set up an action for hiding a warning const hideAction = new vscode.CodeAction( `Hide this ${diagnosticCode} warning`, @@ -117,6 +86,44 @@ export class CodeActionProvider implements vscode.CodeActionProvider { hideTypeAction.diagnostics = [diagnostic]; actions.push(hideTypeAction); + + /* + * Actions only applicable if project file is used + */ + if (!!this.projectFileStore.getUri()) { + // Set up an action for suppressing warning of a given type universally + const suppressTypeAction = new vscode.CodeAction( + `Suppress warning type ${diagnosticCode} universally (in project file)`, + vscode.CodeActionKind.QuickFix + ); + + suppressTypeAction.command = { + command: "cppcheck-official.suppressWarningAll", + title: "Suppress warning universally", + arguments: [diagnosticCode] + }; + + suppressTypeAction.diagnostics = [diagnostic]; + actions.push(suppressTypeAction); + + // Set up an action for suppressing warning based on file or symbol name + const symbol = this.metadataStore.get(diagnostic)?.symbolName; + const suppressAdvancedAction = new vscode.CodeAction( + symbol + ? `Suppress warning ${diagnosticCode} based on file and / or symbol` + :`Suppress warning ${diagnosticCode} based on file`, + vscode.CodeActionKind.QuickFix + ); + + suppressAdvancedAction.command = { + command: "cppcheck-official.suppressWarningAdvanced", + title: "Suppress warning advanced", + arguments: [diagnosticCode, document, diagnostic] + }; + + suppressAdvancedAction.diagnostics = [diagnostic]; + actions.push(suppressAdvancedAction); + } } return actions; diff --git a/src/util/files.ts b/src/util/files.ts index 6d280c6..b8a16b2 100644 --- a/src/util/files.ts +++ b/src/util/files.ts @@ -1,5 +1,21 @@ import * as vscode from 'vscode'; +export class ProjectFileStore { + private projectFileUri : vscode.Uri | undefined; + + setUri(newProjectFileUri: vscode.Uri) { + this.projectFileUri = newProjectFileUri; + } + + getUri() { + return this.projectFileUri; + } + + clear() { + this.projectFileUri = undefined; + } +} + export async function writeSuppressionToProjectFile(projectFileUri : vscode.Uri, warningType : String, file? : String, symbolName? : String) : Promise { const fileType = projectFileUri.toString().split('.')[1]; if (fileType !== 'cppcheck') { From 6e95c3a0b09389cbd164dab71c6d8de9075b8e49 Mon Sep 17 00:00:00 2001 From: davidramnero Date: Fri, 7 Aug 2026 09:29:17 +0200 Subject: [PATCH 2/2] save project file regardless of type, have project file store check for type --- src/extension.ts | 10 +++------- src/util/codeActions.ts | 2 +- src/util/files.ts | 9 +++++++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 9610144..1a03e14 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -160,7 +160,7 @@ export async function activate(context: vscode.ExtensionContext) { "cppcheck-official.suppressWarningAll", async (diagnosticCode : string, file? : string, symbolName? : string) => { const projectFileUri = projectFileStore.getUri(); - if (projectFileUri) { + if (projectFileUri && projectFileStore.hasCppcheckProjectFile()) { const success = await writeSuppressionToProjectFile(projectFileUri, diagnosticCode, file, symbolName); if (success) { // Construct information message to display to the user @@ -178,7 +178,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${projectFileStore.getUri()?.toString()}`); } } else { - vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`); + throw new Error(`Cppcheck Official error: Command 'cppcheck-official.suppressWarningAll' for project file level suppression called without project file present!`); } } ) @@ -534,12 +534,8 @@ async function runCppcheckOnFileXML( 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') { - projectFileStore.setUri(vscode.Uri.file(projectFilePath)); - } + projectFileStore.setUri(vscode.Uri.file(projectFilePath)); } else { args.push( '--suppress=unusedFunction', diff --git a/src/util/codeActions.ts b/src/util/codeActions.ts index 27a2e3c..989f16f 100644 --- a/src/util/codeActions.ts +++ b/src/util/codeActions.ts @@ -90,7 +90,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider { /* * Actions only applicable if project file is used */ - if (!!this.projectFileStore.getUri()) { + if (this.projectFileStore.hasCppcheckProjectFile()) { // Set up an action for suppressing warning of a given type universally const suppressTypeAction = new vscode.CodeAction( `Suppress warning type ${diagnosticCode} universally (in project file)`, diff --git a/src/util/files.ts b/src/util/files.ts index b8a16b2..0af5a97 100644 --- a/src/util/files.ts +++ b/src/util/files.ts @@ -11,6 +11,15 @@ export class ProjectFileStore { return this.projectFileUri; } + hasCppcheckProjectFile() { + const uri = this.getUri(); + if (!uri) { + return false; + } + var projectFileType = uri.path.split('.')[1]; + return projectFileType.toLowerCase() === 'cppcheck'; + } + clear() { this.projectFileUri = undefined; }