Skip to content

Commit 524e346

Browse files
committed
feature/#88 warning suppression code actions
1 parent 2db9257 commit 524e346

3 files changed

Lines changed: 83 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
- **Warning notes**: Display notes for warnings when those are available
1717
- **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`.
1818

19-
- **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).
19+
- **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).
2020
![Image showing how to suppress warnings](./images/suppression.png)
2121
## Requirements
2222

src/extension.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as crypto from 'crypto';
66
import { documentationLinkMap, getPremiumCertLink } from './util/documentation';
77
import { runCommand } from './util/scripts';
88
import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path';
9-
import { diagnosticsUnion } from './util/diagnostics';
9+
import { CodeActionProvider, diagnosticsUnion } from './util/diagnostics';
1010

1111
// To keep track of document changes we save hashed versions of their content to this record
1212
let documentHashMemory : Record<string, string> = {};
@@ -95,6 +95,17 @@ function getDocumentSha1(document: vscode.TextDocument): string {
9595
// This method is called when your extension is activated.
9696
// Your extension is activated the very first time the command is executed.
9797
export async function activate(context: vscode.ExtensionContext) {
98+
context.subscriptions.push(
99+
vscode.languages.registerCodeActionsProvider(
100+
{ pattern: "**/*" },
101+
new CodeActionProvider(),
102+
{
103+
providedCodeActionKinds: [
104+
vscode.CodeActionKind.QuickFix
105+
]
106+
}
107+
)
108+
);
98109

99110
// Register a command to push user to workspace settings from walkthrough
100111
context.subscriptions.push(
@@ -108,6 +119,16 @@ export async function activate(context: vscode.ExtensionContext) {
108119
}
109120
)
110121
);
122+
123+
// Register a command for suppressing a warning type
124+
context.subscriptions.push(
125+
vscode.commands.registerCommand(
126+
"cppcheck-official.suppressWarningAll",
127+
(diagnostic: vscode.Diagnostic) => {
128+
console.log("Suppress", diagnostic);
129+
}
130+
)
131+
);
111132

112133
// ProgressIndicator status bar item to show when checks are running
113134
cppcheckProgressIndicator = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10);

src/util/diagnostics.ts

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

3+
export class CodeActionProvider implements vscode.CodeActionProvider {
4+
provideCodeActions(
5+
document: vscode.TextDocument,
6+
range: vscode.Range,
7+
context: vscode.CodeActionContext,
8+
token: vscode.CancellationToken
9+
): vscode.CodeAction[] {
10+
11+
const actions: vscode.CodeAction[] = [];
12+
13+
for (const diagnostic of context.diagnostics) {
14+
var diagnosticCode = diagnostic.code;
15+
if (typeof(diagnosticCode) === "object" && typeof(diagnosticCode) !== null) {
16+
diagnosticCode = diagnosticCode.value;
17+
}
18+
19+
// Set up one action for suppressing the specific warning on the line targeted by the diagnostic
20+
const suppressAction = new vscode.CodeAction(
21+
`Suppress warning for ${diagnosticCode} here`,
22+
vscode.CodeActionKind.QuickFix
23+
);
24+
25+
// Copy indentation from line affected by diagnostic
26+
const lineText = document.lineAt(diagnostic.range.start.line).text;
27+
const indent = lineText.match(/^\s*/)?.[0] ?? "";
28+
29+
// Insert suppression comment above affected line
30+
const suppressLineEdit = new vscode.WorkspaceEdit();
31+
suppressLineEdit.insert(
32+
document.uri,
33+
new vscode.Position(
34+
diagnostic.range.start.line,
35+
0,
36+
),
37+
`${indent}// cppcheck-suppress ${diagnosticCode}\n`
38+
);
39+
suppressAction.edit = suppressLineEdit;
40+
suppressAction.diagnostics = [diagnostic];
41+
actions.push(suppressAction);
42+
43+
// Set up one action for suppressing warning of a given type universally
44+
const suppressTypeAction = new vscode.CodeAction(
45+
`Suppress warning type ${diagnosticCode} universally`,
46+
vscode.CodeActionKind.QuickFix
47+
);
48+
49+
suppressTypeAction.command = {
50+
command: "cppcheck-official.suppressWarningAll",
51+
title: "Suppress warning here",
52+
arguments: [diagnostic]
53+
};
54+
55+
suppressTypeAction.diagnostics = [diagnostic];
56+
actions.push(suppressTypeAction);
57+
}
58+
59+
return actions;
60+
}
61+
}
62+
363
export function diagnosticsUnion(diagnosticsA : vscode.Diagnostic[], diagnosticB : vscode.Diagnostic[]) : vscode.Diagnostic[] {
464
const diagnosticsUnion = new Array<vscode.Diagnostic>;
565
// Add all elements from diagnosticsA to result array

0 commit comments

Comments
 (0)