Skip to content

Commit ed97238

Browse files
authored
fix/ only show code actions related to project file if project file is present (#102)
* fix/ only show code actions related to project file if project file is present * save project file regardless of type, have project file store check for type
1 parent 7477cab commit ed97238

3 files changed

Lines changed: 78 additions & 48 deletions

File tree

‎src/extension.ts‎

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@ import { runCommand } from './util/scripts';
88
import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path';
99
import { DiagnosticMetadataStore, diagnosticsUnion } from './util/diagnostics';
1010
import { CodeActionProvider } from './util/codeActions';
11-
import { writeSuppressionToProjectFile } from './util/files';
11+
import { ProjectFileStore, writeSuppressionToProjectFile } from './util/files';
1212

1313
// To keep track of document changes we save hashed versions of their content to this record
1414
let documentHashMemory : Record<string, string> = {};
1515
// To keep track of warnings for files created from analysis of other files we save their relations to fileRelationMap
1616
let fileRelationMap: Record<string, Set<string>> = {};
1717
// Some diagnostics have symbol names associated with them, which we keep track of in diagnosticMetadataStore
1818
const diagnosticMetadataStore = new DiagnosticMetadataStore();
19+
// The ProjectFileStore is usd to keep track of the users project file through different context
20+
const projectFileStore = new ProjectFileStore();
1921

2022
let previewAnalysisTimer: NodeJS.Timeout | undefined;
2123
let previewedDocument: vscode.TextDocument | undefined;
2224
let cppcheckProgressIndicator: vscode.StatusBarItem;
2325
let severityOption: vscode.StatusBarItem;
2426
let checksRunning = false;
25-
let cppcheckProjectFileUri: vscode.Uri | undefined;
2627

2728
enum SeverityNumber {
2829
Info = 0,
@@ -131,7 +132,7 @@ export async function activate(context: vscode.ExtensionContext) {
131132
context.subscriptions.push(
132133
vscode.languages.registerCodeActionsProvider(
133134
{ pattern: "**/*" },
134-
new CodeActionProvider(diagnosticMetadataStore),
135+
new CodeActionProvider(diagnosticMetadataStore, projectFileStore),
135136
{
136137
providedCodeActionKinds: [
137138
vscode.CodeActionKind.QuickFix
@@ -158,25 +159,26 @@ export async function activate(context: vscode.ExtensionContext) {
158159
vscode.commands.registerCommand(
159160
"cppcheck-official.suppressWarningAll",
160161
async (diagnosticCode : string, file? : string, symbolName? : string) => {
161-
if (cppcheckProjectFileUri) {
162-
const success = await writeSuppressionToProjectFile(cppcheckProjectFileUri, diagnosticCode, file, symbolName);
162+
const projectFileUri = projectFileStore.getUri();
163+
if (projectFileUri && projectFileStore.hasCppcheckProjectFile()) {
164+
const success = await writeSuppressionToProjectFile(projectFileUri, diagnosticCode, file, symbolName);
163165
if (success) {
164166
// Construct information message to display to the user
165167
const fileMessagePart = file ? ` for file ${file}` : '';
166168
const symbolNameMessagePart = symbolName ? ` for symbol name ${symbolName}` : '';
167169
const fileOrSymbolExtraMessage = file || symbolName ? '. Note: you have to re-analyze the file for the suppression to take effect.' : '';
168-
const completeInformationMessageText = `Suppression of ${diagnosticCode} added to project file ${cppcheckProjectFileUri.toString()}${fileMessagePart}${symbolNameMessagePart}${fileOrSymbolExtraMessage}`;
170+
const completeInformationMessageText = `Suppression of ${diagnosticCode} added to project file ${projectFileStore.getUri()?.toString()}${fileMessagePart}${symbolNameMessagePart}${fileOrSymbolExtraMessage}`;
169171
vscode.window.showInformationMessage(completeInformationMessageText);
170172

171173
// Only hide warnings if suppression is global, since hide command does not support file or symbol filter for now
172174
if (!file && !symbolName) {
173175
await vscode.commands.executeCommand('cppcheck-official.hideWarningType', diagnosticCode);
174176
}
175177
} else {
176-
vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${cppcheckProjectFileUri.toString()}`);
178+
vscode.window.showErrorMessage(`Failed to add suppression of ${diagnosticCode} to project file ${projectFileStore.getUri()?.toString()}`);
177179
}
178180
} else {
179-
vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`);
181+
throw new Error(`Cppcheck Official error: Command 'cppcheck-official.suppressWarningAll' for project file level suppression called without project file present!`);
180182
}
181183
}
182184
)
@@ -520,7 +522,7 @@ async function runCppcheckOnFileXML(
520522
});
521523

522524
let usingProjectFile = false;
523-
cppcheckProjectFileUri = undefined;
525+
projectFileStore.clear();
524526

525527
const args = [
526528
'--enable=all',
@@ -532,12 +534,8 @@ async function runCppcheckOnFileXML(
532534
if (processedArgs.includes("--project=")) {
533535
usingProjectFile = true;
534536
args.push(`--file-filter=${filePath}`);
535-
// If project file is of type .cppcheck we keep track of it
536537
var projectFilePath = processedArgs.split('--project=')[1].split(' ')[0];
537-
var projectFileType = projectFilePath.split('.')[1];
538-
if (projectFileType.toLowerCase() === 'cppcheck') {
539-
cppcheckProjectFileUri = vscode.Uri.file(projectFilePath);
540-
}
538+
projectFileStore.setUri(vscode.Uri.file(projectFilePath));
541539
} else {
542540
args.push(
543541
'--suppress=unusedFunction',

‎src/util/codeActions.ts‎

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import * as vscode from 'vscode';
22
import { DiagnosticMetadataStore } from './diagnostics';
3+
import { ProjectFileStore } from './files';
34
export class CodeActionProvider implements vscode.CodeActionProvider {
45
constructor(
5-
private readonly metadataStore: DiagnosticMetadataStore
6+
private readonly metadataStore: DiagnosticMetadataStore,
7+
private readonly projectFileStore: ProjectFileStore
68
) {}
79
provideCodeActions(
810
document: vscode.TextDocument,
@@ -55,39 +57,6 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
5557
suppressAction.diagnostics = [diagnostic];
5658
actions.push(suppressAction);
5759

58-
// Set up an action for suppressing warning of a given type universally
59-
const suppressTypeAction = new vscode.CodeAction(
60-
`Suppress warning type ${diagnosticCode} universally (in project file)`,
61-
vscode.CodeActionKind.QuickFix
62-
);
63-
64-
suppressTypeAction.command = {
65-
command: "cppcheck-official.suppressWarningAll",
66-
title: "Suppress warning universally",
67-
arguments: [diagnosticCode]
68-
};
69-
70-
suppressTypeAction.diagnostics = [diagnostic];
71-
actions.push(suppressTypeAction);
72-
73-
// Set up an action for suppressing warning based on file or symbol name
74-
const symbol = this.metadataStore.get(diagnostic)?.symbolName;
75-
const suppressAdvancedAction = new vscode.CodeAction(
76-
symbol
77-
? `Suppress warning ${diagnosticCode} based on file and / or symbol`
78-
:`Suppress warning ${diagnosticCode} based on file`,
79-
vscode.CodeActionKind.QuickFix
80-
);
81-
82-
suppressAdvancedAction.command = {
83-
command: "cppcheck-official.suppressWarningAdvanced",
84-
title: "Suppress warning advanced",
85-
arguments: [diagnosticCode, document, diagnostic]
86-
};
87-
88-
suppressAdvancedAction.diagnostics = [diagnostic];
89-
actions.push(suppressAdvancedAction);
90-
9160
// Set up an action for hiding a warning
9261
const hideAction = new vscode.CodeAction(
9362
`Hide this ${diagnosticCode} warning`,
@@ -117,6 +86,44 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
11786

11887
hideTypeAction.diagnostics = [diagnostic];
11988
actions.push(hideTypeAction);
89+
90+
/*
91+
* Actions only applicable if project file is used
92+
*/
93+
if (this.projectFileStore.hasCppcheckProjectFile()) {
94+
// Set up an action for suppressing warning of a given type universally
95+
const suppressTypeAction = new vscode.CodeAction(
96+
`Suppress warning type ${diagnosticCode} universally (in project file)`,
97+
vscode.CodeActionKind.QuickFix
98+
);
99+
100+
suppressTypeAction.command = {
101+
command: "cppcheck-official.suppressWarningAll",
102+
title: "Suppress warning universally",
103+
arguments: [diagnosticCode]
104+
};
105+
106+
suppressTypeAction.diagnostics = [diagnostic];
107+
actions.push(suppressTypeAction);
108+
109+
// Set up an action for suppressing warning based on file or symbol name
110+
const symbol = this.metadataStore.get(diagnostic)?.symbolName;
111+
const suppressAdvancedAction = new vscode.CodeAction(
112+
symbol
113+
? `Suppress warning ${diagnosticCode} based on file and / or symbol`
114+
:`Suppress warning ${diagnosticCode} based on file`,
115+
vscode.CodeActionKind.QuickFix
116+
);
117+
118+
suppressAdvancedAction.command = {
119+
command: "cppcheck-official.suppressWarningAdvanced",
120+
title: "Suppress warning advanced",
121+
arguments: [diagnosticCode, document, diagnostic]
122+
};
123+
124+
suppressAdvancedAction.diagnostics = [diagnostic];
125+
actions.push(suppressAdvancedAction);
126+
}
120127
}
121128

122129
return actions;

‎src/util/files.ts‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
import * as vscode from 'vscode';
22

3+
export class ProjectFileStore {
4+
private projectFileUri : vscode.Uri | undefined;
5+
6+
setUri(newProjectFileUri: vscode.Uri) {
7+
this.projectFileUri = newProjectFileUri;
8+
}
9+
10+
getUri() {
11+
return this.projectFileUri;
12+
}
13+
14+
hasCppcheckProjectFile() {
15+
const uri = this.getUri();
16+
if (!uri) {
17+
return false;
18+
}
19+
var projectFileType = uri.path.split('.')[1];
20+
return projectFileType.toLowerCase() === 'cppcheck';
21+
}
22+
23+
clear() {
24+
this.projectFileUri = undefined;
25+
}
26+
}
27+
328
export async function writeSuppressionToProjectFile(projectFileUri : vscode.Uri, warningType : String, file? : String, symbolName? : String) : Promise<boolean> {
429
const fileType = projectFileUri.toString().split('.')[1];
530
if (fileType !== 'cppcheck') {

0 commit comments

Comments
 (0)