Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions src/ui/codeActionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import * as vscode from 'vscode';

export class ProofCodeCodeActionProvider implements vscode.CodeActionProvider {
public static readonly providedCodeActionKinds = [vscode.CodeActionKind.QuickFix];

public provideCodeActions(
document: vscode.TextDocument,
_range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext,
_token: vscode.CancellationToken
): vscode.CodeAction[] {
const actions: vscode.CodeAction[] = [];

// Filter diagnostics generated by ProofCode
const proofCodeDiagnostics = context.diagnostics.filter(
(diag) => diag.source === 'ProofCode'
);

for (const diag of proofCodeDiagnostics) {
const lineIdx = diag.range.start.line;
const line = document.lineAt(lineIdx);
const lineText = line.text;
const indentMatch = lineText.match(/^\s*/);
const indent = indentMatch ? indentMatch[0] : '';

// 1. Quick Fix for PC-REL-006: Unhandled Async Operation
if (diag.code === 'PC-REL-006') {
const action = new vscode.CodeAction(
'πŸ›‘οΈ ProofCode: Wrap in try/catch block',
vscode.CodeActionKind.QuickFix
);
action.isPreferred = true;
action.diagnostics = [diag];

const edit = new vscode.WorkspaceEdit();
const wrapped = `${indent}try {\n${indent} ${lineText.trim()}\n${indent}} catch (error) {\n${indent} console.error('Async operation failed:', error);\n${indent}}`;
edit.replace(document.uri, line.range, wrapped);
action.edit = edit;
actions.push(action);
}

// 2. Quick Fix for PC-DATA-001: Unhandled Null/Undefined Database Result
if (diag.code === 'PC-DATA-001') {
// Match variable name from diagnostic message or code line
const varMatch = diag.message.match(/\(([^)]+)\)/);
const varName = varMatch ? varMatch[1] : 'record';

// Fix A: Add null guard
const guardAction = new vscode.CodeAction(
`πŸ›‘οΈ ProofCode: Add null guard check (if (!${varName}))`,
vscode.CodeActionKind.QuickFix
);
guardAction.isPreferred = true;
guardAction.diagnostics = [diag];

const guardEdit = new vscode.WorkspaceEdit();
const guardText = `${indent}if (!${varName}) throw new Error('${varName} not found');\n`;
guardEdit.insert(document.uri, new vscode.Position(lineIdx, 0), guardText);
guardAction.edit = guardEdit;
actions.push(guardAction);

// Fix B: Use optional chaining
const dotIndex = lineText.indexOf(`${varName}.`);
if (dotIndex !== -1) {
const optChainAction = new vscode.CodeAction(
`πŸ›‘οΈ ProofCode: Use optional chaining (${varName}?.${lineText.slice(dotIndex + varName.length + 1).split(/\W/)[0]})`,
vscode.CodeActionKind.QuickFix
);
optChainAction.diagnostics = [diag];

const optEdit = new vscode.WorkspaceEdit();
const dotRange = new vscode.Range(
lineIdx,
dotIndex + varName.length,
lineIdx,
dotIndex + varName.length + 1
);
optEdit.replace(document.uri, dotRange, '?.');
optChainAction.edit = optEdit;
actions.push(optChainAction);
}
}

// 3. Quick Fix for PC-AUTH-001: Missing Authorization Check in API Route
if (diag.code === 'PC-AUTH-001') {
const authAction = new vscode.CodeAction(
'πŸ›‘οΈ ProofCode: Insert session authentication guard',
vscode.CodeActionKind.QuickFix
);
authAction.isPreferred = true;
authAction.diagnostics = [diag];

const authEdit = new vscode.WorkspaceEdit();
const authSnippet = `${indent} const session = await auth();\n${indent} if (!session) return new Response('Unauthorized', { status: 401 });\n`;
authEdit.insert(document.uri, new vscode.Position(lineIdx + 1, 0), authSnippet);
authAction.edit = authEdit;
actions.push(authAction);
}

// 4. Quick Fix for PC-SEC-001: Potential SQL Injection
if (diag.code === 'PC-SEC-001') {
const sqlAction = new vscode.CodeAction(
'πŸ›‘οΈ ProofCode: Review query parameterization guidance',
vscode.CodeActionKind.QuickFix
);
sqlAction.diagnostics = [diag];
actions.push(sqlAction);
}
}

return actions;
}
}
Loading