Refactoring teil 2 - TplCodeActionProvider aufgeteilt

This commit is contained in:
kuro 2026-10-11 04:36:23 +02:00
parent 07eb9f7366
commit 132cfacb70
5 changed files with 115 additions and 52 deletions

View File

@ -1,67 +1,43 @@
import * as vscode from 'vscode';
import { TplQuickFix } from './actions/TplQuickFix';
import { TabFix } from './actions/TabFix';
import { LogFix } from './actions/LogFix';
import { MetadataFix } from './actions/MetadataFix';
export class TplCodeActionProvider implements vscode.CodeActionProvider {
private fixes: Map<string, TplQuickFix> = new Map();
constructor() {
// Hier werden alle Quick Fixes registriert
const availableFixes: TplQuickFix[] = [
new TabFix(),
new LogFix(),
new MetadataFix()
];
for (const fix of availableFixes) {
this.fixes.set(fix.diagnosticCode, fix);
}
}
public provideCodeActions(
document: vscode.TextDocument,
range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext,
token: vscode.CancellationToken
): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
): vscode.CodeAction[] {
const actionList: vscode.CodeAction[] = [];
const actions: vscode.CodeAction[] = [];
for (const diag of context.diagnostics) {
// 1. Fix für fehlende Modul-Metadaten (Auf Modul-Ebene, 4 Spaces)
if (diag.code === 'missing_module_metadata') {
const action = new vscode.CodeAction('Fehlende Modul-Metadaten einfügen', vscode.CodeActionKind.QuickFix);
action.edit = new vscode.WorkspaceEdit();
const fehlendeFelder = diag.message.replace('Fehlende Pflicht-Metadaten (Modul-Ebene): ', '').split(', ');
let neuerText = '';
if (fehlendeFelder.includes('origin')) { neuerText += ` origin := 'Origin';\n`; }
if (fehlendeFelder.includes('author')) { neuerText += ` author := 'Dein Name';\n`; }
if (fehlendeFelder.includes('products')) { neuerText += ` products := 'Produktname';\n`; }
if (fehlendeFelder.includes('publishers')) { neuerText += ` publishers := 'Dein Unternehmen';\n`; }
if (fehlendeFelder.includes('tree_path')) { neuerText += ` tree_path := 'Company', 'Kategorie', 'Sub';\n`; }
action.edit.insert(document.uri, new vscode.Position(diag.range.start.line + 1, 0), neuerText);
action.diagnostics = [diag];
action.isPreferred = true;
actionList.push(action);
}
// 2. Fix für fehlendes Log-Statement im Body (8 Spaces Einrückung)
if (diag.code === 'missing_log_start') {
const action = new vscode.CodeAction('Log-Statement am Body-Anfang einfügen', vscode.CodeActionKind.QuickFix);
action.edit = new vscode.WorkspaceEdit();
const erwartetesLog = diag.source as string;
const neuerText = ` ${erwartetesLog}\n`;
action.edit.insert(document.uri, new vscode.Position(diag.range.start.line + 1, 0), neuerText);
action.diagnostics = [diag];
action.isPreferred = true;
actionList.push(action);
}
// 3. Fix für Tabs (Ersetzt \t durch 4 Spaces in der ganzen Zeile)
if (diag.code === 'invalid_tab') {
const action = new vscode.CodeAction('Tabs in dieser Zeile durch 4 Spaces ersetzen', vscode.CodeActionKind.QuickFix);
action.edit = new vscode.WorkspaceEdit();
const zeile = document.lineAt(diag.range.start.line);
const bereinigterText = zeile.text.replace(/\t/g, ' ');
action.edit.replace(document.uri, zeile.range, bereinigterText);
action.diagnostics = [diag];
action.isPreferred = true;
actionList.push(action);
// Prüfen, ob für die aktuellen Fehler (Diagnostics) ein Fix existiert
for (const diagnostic of context.diagnostics) {
const code = diagnostic.code;
if (typeof code === 'string' && this.fixes.has(code)) {
const fixLogic = this.fixes.get(code)!;
actions.push(...fixLogic.provideFix(document, diagnostic));
}
}
return actionList;
return actions;
}
}

View File

@ -0,0 +1,23 @@
import * as vscode from 'vscode';
import { TplQuickFix } from './TplQuickFix';
export class LogFix implements TplQuickFix {
public readonly diagnosticCode = 'missing_log_start';
public provideFix(document: vscode.TextDocument, diagnostic: vscode.Diagnostic): vscode.CodeAction[] {
const fix = new vscode.CodeAction("Fehlendes Log-Statement einfügen", vscode.CodeActionKind.QuickFix);
fix.edit = new vscode.WorkspaceEdit();
// Der Linter hat uns den exakten String in die 'source' gepackt
const expectedLog = diagnostic.source || 'log.debug("Start pattern");';
// Füge es eine Zeile unter dem 'body' Keyword ein, sauber eingerückt
const insertText = ` ${expectedLog}\n`;
fix.edit.insert(document.uri, new vscode.Position(diagnostic.range.start.line + 1, 0), insertText);
fix.diagnostics = [diagnostic];
fix.isPreferred = true;
return [fix];
}
}

View File

@ -0,0 +1,35 @@
import * as vscode from 'vscode';
import { TplQuickFix } from './TplQuickFix';
export class MetadataFix implements TplQuickFix {
public readonly diagnosticCode = 'missing_module_metadata';
public provideFix(document: vscode.TextDocument, diagnostic: vscode.Diagnostic): vscode.CodeAction[] {
const fix = new vscode.CodeAction("Fehlende Metadaten generieren", vscode.CodeActionKind.QuickFix);
fix.edit = new vscode.WorkspaceEdit();
// Einstellungen laden
const config = vscode.workspace.getConfiguration('tpl');
const author = config.get<string>('metadata.author', 'Kuro');
const origin = config.get<string>('metadata.origin', 'Custom');
const publisher = config.get<string>('metadata.publisher', 'IT-Operations');
const treePathBase = config.get<string>('metadata.treePathBase', 'Grafing');
// Herausfinden, welche Felder fehlen (steht im Diagnostic-Message-String)
const missingFieldsStr = diagnostic.message.replace('Fehlende Pflicht-Metadaten (Modul-Ebene): ', '');
const missingFields = missingFieldsStr.split(', ');
let insertText = '';
if (missingFields.includes('origin')) insertText += ` origin := '${origin}';\n`;
if (missingFields.includes('author')) insertText += ` author := '${author}';\n`;
if (missingFields.includes('products')) insertText += ` products := 'TODO_Product';\n`;
if (missingFields.includes('publishers')) insertText += ` publishers := '${publisher}';\n`;
if (missingFields.includes('tree_path')) insertText += ` tree_path := '${treePathBase}', 'TODO_Category', 'TODO_Subcategory';\n`;
// Direkt über der Zeile 'end metadata;' einfügen
fix.edit.insert(document.uri, new vscode.Position(diagnostic.range.start.line, 0), insertText);
fix.diagnostics = [diagnostic];
return [fix];
}
}

View File

@ -0,0 +1,20 @@
import * as vscode from 'vscode';
import { TplQuickFix } from './TplQuickFix';
export class TabFix implements TplQuickFix {
public readonly diagnosticCode = 'invalid_tab';
public provideFix(document: vscode.TextDocument, diagnostic: vscode.Diagnostic): vscode.CodeAction[] {
const fix = new vscode.CodeAction("Tabs in 4 Spaces umwandeln", vscode.CodeActionKind.QuickFix);
fix.edit = new vscode.WorkspaceEdit();
const line = document.lineAt(diagnostic.range.start.line);
const newText = line.text.replace(/\t/g, ' ');
fix.edit.replace(document.uri, line.range, newText);
fix.diagnostics = [diagnostic];
fix.isPreferred = true; // Setzt dies als Standard-Vorschlag
return [fix];
}
}

View File

@ -0,0 +1,9 @@
import * as vscode from 'vscode';
export interface TplQuickFix {
// Der Fehlercode aus dem Linter (z.B. 'invalid_tab')
readonly diagnosticCode: string;
// Die Methode, die den Fix generiert
provideFix(document: vscode.TextDocument, diagnostic: vscode.Diagnostic): vscode.CodeAction[];
}