Skip to content

Commit 8c9c0f3

Browse files
committed
basic functionality for writing suppression lines to project file
1 parent 17e928c commit 8c9c0f3

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

src/extension.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { runCommand } from './util/scripts';
88
import { looksLikePath, resolvePath, findWorkspaceRoot } from './util/path';
99
import { diagnosticsUnion } from './util/diagnostics';
1010
import { CodeActionProvider } from './util/codeActions';
11+
import { writeSuppressionToProjectFile } from './util/files';
1112

1213
// To keep track of document changes we save hashed versions of their content to this record
1314
let documentHashMemory : Record<string, string> = {};
@@ -18,6 +19,7 @@ let previewAnalysisTimer: NodeJS.Timeout | undefined;
1819
let previewedDocument: vscode.TextDocument | undefined;
1920
let cppcheckProgressIndicator: vscode.StatusBarItem;
2021
let checksRunning = false;
22+
let cppcheckProjectFileUri: vscode.Uri | undefined;
2123

2224
enum SeverityNumber {
2325
Info = 0,
@@ -96,6 +98,7 @@ function getDocumentSha1(document: vscode.TextDocument): string {
9698
// This method is called when your extension is activated.
9799
// Your extension is activated the very first time the command is executed.
98100
export async function activate(context: vscode.ExtensionContext) {
101+
// Set up code actions provider
99102
context.subscriptions.push(
100103
vscode.languages.registerCodeActionsProvider(
101104
{ pattern: "**/*" },
@@ -125,8 +128,12 @@ export async function activate(context: vscode.ExtensionContext) {
125128
context.subscriptions.push(
126129
vscode.commands.registerCommand(
127130
"cppcheck-official.suppressWarningAll",
128-
(diagnostic: vscode.Diagnostic) => {
129-
console.log("Suppress", diagnostic);
131+
async (warningType : String) => {
132+
if (cppcheckProjectFileUri) {
133+
await writeSuppressionToProjectFile(cppcheckProjectFileUri, warningType);
134+
} else {
135+
vscode.window.showInformationMessage(`Adding suppression is currently only supported for .cppcheck project files`);
136+
}
130137
}
131138
)
132139
);
@@ -321,6 +328,8 @@ async function runCppcheckOnFileXML(
321328
});
322329

323330
let usingProjectFile = false;
331+
cppcheckProjectFileUri = undefined;
332+
324333
const args = [
325334
'--enable=all',
326335
'--inline-suppr',
@@ -330,9 +339,16 @@ async function runCppcheckOnFileXML(
330339
'--suppress=missingIncludeSystem',
331340
...argsParsed,
332341
].filter(Boolean);
342+
333343
if (processedArgs.includes("--project")) {
334344
usingProjectFile = true;
335345
args.push(`--file-filter=${filePath}`);
346+
// If project file is of type .cppcheck we keep track of it
347+
var projectFilePath = processedArgs.split('--project=')[1].split(' ')[0];
348+
var projectFileType = projectFilePath.split('.')[1];
349+
if (projectFileType.toLowerCase() === 'cppcheck') {
350+
cppcheckProjectFileUri = vscode.Uri.file(projectFilePath);
351+
}
336352
} else {
337353
args.push(filePath);
338354
}

src/util/files.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as vscode from 'vscode';
2+
3+
export async function writeSuppressionToProjectFile(projectFileUri : vscode.Uri, warningType : String) {
4+
const fileType = projectFileUri.toString().split('.')[1];
5+
if (fileType !== 'cppcheck') {
6+
throw new Error(`Function writeSuppressionToProjectFile only supports writing to .cppcheck project files! Recieved file is of type .${fileType}`);
7+
}
8+
9+
// Open project file with vscode workspace API
10+
const document = await vscode.workspace.openTextDocument(projectFileUri);
11+
const text = document.getText();
12+
const edit = new vscode.WorkspaceEdit();
13+
var textToInsert = '';
14+
var positionToInsertAt = 0;
15+
16+
// Search for suppressions section
17+
const match = /<suppressions\b[^>]*>([\s\S]*?)<\/suppressions>/m.exec(text);
18+
if (match !== null) {
19+
// match !== null -> Suppressions section exists
20+
const closeIndex = text.indexOf("</suppressions>");
21+
22+
// Determine indentation and construct the new suppression line
23+
const line = document.lineAt(document.positionAt(closeIndex).line - 1);
24+
const indentation = line.text.match(/^\s*/)?.[0] ?? " ";
25+
const newSuppressionLine = `\n${indentation}<suppression id="${warningType}"/>\n`;
26+
27+
// We splice in the new line just before the end of the suppressions block
28+
textToInsert = newSuppressionLine;
29+
positionToInsertAt = closeIndex;
30+
} else {
31+
// match === null -> Suppressions section does not exist
32+
const closeIndex = text.indexOf("</project>");
33+
34+
// Determine indentation and construct the new suppressions block
35+
const line = document.lineAt(document.positionAt(closeIndex).line - 1);
36+
const indentation = line.text.match(/^\s*/)?.[0] ?? " ";
37+
const suppressionsBlock =
38+
`\n${indentation}<suppressions>
39+
${indentation} <suppression id="${warningType}"/>
40+
${indentation}</suppressions>\n`;
41+
42+
// Splice in the new suppressions block just before the end of the project-file
43+
textToInsert = suppressionsBlock;
44+
positionToInsertAt = closeIndex;
45+
}
46+
47+
// Write file
48+
edit.insert(
49+
document.uri,
50+
document.positionAt(positionToInsertAt),
51+
textToInsert
52+
);
53+
54+
await vscode.workspace.applyEdit(edit);
55+
}

0 commit comments

Comments
 (0)