From 132cfacb7029c9c39e1d163726c3cc4bf12f6ebe Mon Sep 17 00:00:00 2001 From: kuro Date: Sun, 11 Oct 2026 04:36:23 +0200 Subject: [PATCH] Refactoring teil 2 - TplCodeActionProvider aufgeteilt --- src/providers/TplCodeActionProvider.ts | 80 +++++++++----------------- src/providers/actions/LogFix.ts | 23 ++++++++ src/providers/actions/MetadataFix.ts | 35 +++++++++++ src/providers/actions/TabFix.ts | 20 +++++++ src/providers/actions/TplQuickFix.ts | 9 +++ 5 files changed, 115 insertions(+), 52 deletions(-) create mode 100644 src/providers/actions/LogFix.ts create mode 100644 src/providers/actions/MetadataFix.ts create mode 100644 src/providers/actions/TabFix.ts create mode 100644 src/providers/actions/TplQuickFix.ts diff --git a/src/providers/TplCodeActionProvider.ts b/src/providers/TplCodeActionProvider.ts index 63f1046..1f9319a 100644 --- a/src/providers/TplCodeActionProvider.ts +++ b/src/providers/TplCodeActionProvider.ts @@ -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 = 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; } } \ No newline at end of file diff --git a/src/providers/actions/LogFix.ts b/src/providers/actions/LogFix.ts new file mode 100644 index 0000000..cd15866 --- /dev/null +++ b/src/providers/actions/LogFix.ts @@ -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]; + } +} \ No newline at end of file diff --git a/src/providers/actions/MetadataFix.ts b/src/providers/actions/MetadataFix.ts new file mode 100644 index 0000000..c851e73 --- /dev/null +++ b/src/providers/actions/MetadataFix.ts @@ -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('metadata.author', 'Kuro'); + const origin = config.get('metadata.origin', 'Custom'); + const publisher = config.get('metadata.publisher', 'IT-Operations'); + const treePathBase = config.get('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]; + } +} \ No newline at end of file diff --git a/src/providers/actions/TabFix.ts b/src/providers/actions/TabFix.ts new file mode 100644 index 0000000..f6618b1 --- /dev/null +++ b/src/providers/actions/TabFix.ts @@ -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]; + } +} \ No newline at end of file diff --git a/src/providers/actions/TplQuickFix.ts b/src/providers/actions/TplQuickFix.ts new file mode 100644 index 0000000..88edac1 --- /dev/null +++ b/src/providers/actions/TplQuickFix.ts @@ -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[]; +} \ No newline at end of file