From 9dcbf58f3a878a1b49b6fb05384c976329bf7e4a Mon Sep 17 00:00:00 2001 From: kuro Date: Sun, 18 Oct 2026 03:14:13 +0200 Subject: [PATCH] refactoring fixes --- src/core/rules/BlockRule.ts | 45 ++++++++++++------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/core/rules/BlockRule.ts b/src/core/rules/BlockRule.ts index f9d4be3..8143410 100644 --- a/src/core/rules/BlockRule.ts +++ b/src/core/rules/BlockRule.ts @@ -10,7 +10,7 @@ export class BlockRule implements LinterRule { else { ctx.addDiag(lineIdx, 0, rawLine.length, "Jede Datei muss mit 'tpl 1.x module ;' beginnen.", vscode.DiagnosticSeverity.Error); ctx.hasModuleDef = true; } } - // NEU: Wenn wir im Metadata-Block sind, ignorieren wir den Rest. Die MetadataRule übernimmt! + // Wenn wir im Metadata-Block sind, ignorieren wir den Rest. Die MetadataRule übernimmt! if (ctx.inModuleMetadata || (line.startsWith('metadata') && ctx.inBlock === 'none')) { return; } @@ -31,13 +31,20 @@ export class BlockRule implements LinterRule { this.checkEndBlocks(line, rawLine, lineIdx, ctx); } + public checkEnd(lines: string[], ctx: LinterContext): void { + for (const unclosedLine of ctx.openDefines) { + ctx.addDiag(unclosedLine, 0, lines[unclosedLine].length, "Block 'define' wurde nicht mit 'end define;' geschlossen!", vscode.DiagnosticSeverity.Error); + } + for (const block of ctx.openControlBlocks) { + ctx.addDiag(block.lineIdx, 0, lines[block.lineIdx].length, `Block '${block.type}' wurde nicht mit 'end${block.type};' geschlossen!`, vscode.DiagnosticSeverity.Error); + } + } + private handleControlBlocks(line: string, rawLine: string, lineIdx: number, ctx: LinterContext) { - // Block wird geöffnet if (/^if\b/.test(line)) { ctx.openControlBlocks.push({ type: 'if', lineIdx }); } else if (/^for\b/.test(line)) { ctx.openControlBlocks.push({ type: 'for', lineIdx }); } else if (/^while\b/.test(line)) { ctx.openControlBlocks.push({ type: 'while', lineIdx }); } - // Block wird geschlossen if (line.startsWith('end if')) { this.closeControlBlock('if', line, lineIdx, ctx); } else if (line.startsWith('end for')) { this.closeControlBlock('for', line, lineIdx, ctx); } else if (line.startsWith('end while')) { this.closeControlBlock('while', line, lineIdx, ctx); } @@ -49,33 +56,13 @@ export class BlockRule implements LinterRule { return; } - // Wir nehmen den zuletzt geöffneten Block vom Stapel const lastBlock = ctx.openControlBlocks.pop()!; - if (lastBlock.type !== expectedType) { - ctx.addDiag(lineIdx, 0, line.length, `Falsches Ende. Erwartet: 'end ${lastBlock.type};', gefunden: 'end ${expectedType};'.`, vscode.DiagnosticSeverity.Error); - // Damit Folgefehler vermieden werden, legen wir ihn zurück + ctx.addDiag(lineIdx, 0, line.length, `Falsches Ende. Erwartet: 'end ${lastBlock.type};', gefunden: 'end${expectedType};'.`, vscode.DiagnosticSeverity.Error); ctx.openControlBlocks.push(lastBlock); } } - private trackModuleMetadata(line: string, lineIdx: number, ctx: LinterContext) { - if (line.match(/^origin\b/)) { ctx.foundModuleMetadata.origin = true; } - if (line.match(/^author\b/)) { ctx.foundModuleMetadata.author = true; } - if (line.match(/^products\b/)) { ctx.foundModuleMetadata.products = true; } - if (line.match(/^publishers\b/)) { ctx.foundModuleMetadata.publishers = true; } - if (line.match(/^tree_path\b/)) { ctx.foundModuleMetadata.tree_path = true; } - - if (line.startsWith('end metadata')) { - ctx.inModuleMetadata = false; - const missing = Object.keys(ctx.foundModuleMetadata).filter(k => !(ctx.foundModuleMetadata as any)[k]); - if (missing.length > 0 && ctx.moduleMetadataBlockLine !== -1) { - const diag = ctx.addDiag(ctx.moduleMetadataBlockLine, 0, 8, `Fehlende Pflicht-Metadaten (Modul-Ebene): ${missing.join(', ')}`, vscode.DiagnosticSeverity.Error); - diag.code = 'missing_module_metadata'; - } - } - } - private handleBlockOpenings(line: string, rawLine: string, lineIdx: number, ctx: LinterContext) { if (line.startsWith('definitions ') || line.startsWith('definition ')) { if (ctx.inBlock !== 'none') { ctx.addDiag(lineIdx, 0, line.length, "Ein Definitions-Block muss auf oberster Ebene deklariert werden.", vscode.DiagnosticSeverity.Error); } @@ -110,7 +97,7 @@ export class BlockRule implements LinterRule { private checkPatternPhases(line: string, rawLine: string, lineIdx: number, ctx: LinterContext, lines: string[]) { const checkPhase = (phaseName: string, phaseEnum: PatternPhase) => { if (line.startsWith(phaseName)) { - if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end ${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } + if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } if (ctx.currentPatternPhase >= phaseEnum) { ctx.addDiag(lineIdx, 0, phaseName.length, `'${phaseName}' Block ist hier nicht erlaubt.`, vscode.DiagnosticSeverity.Error); } ctx.currentPatternPhase = phaseEnum; @@ -127,7 +114,7 @@ export class BlockRule implements LinterRule { checkPhase('removal', PatternPhase.Removal); if (line.startsWith('body')) { - if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end ${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } + if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } ctx.activePhaseName = "body"; ctx.activePhaseLine = lineIdx; @@ -158,7 +145,7 @@ export class BlockRule implements LinterRule { private checkEndBlocks(line: string, rawLine: string, lineIdx: number, ctx: LinterContext) { if (line.startsWith('end pattern') || line.startsWith('end syncmapping')) { - if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end ${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } + if (ctx.activePhaseName !== "") { ctx.addDiag(ctx.activePhaseLine, 0, ctx.activePhaseName.length, `Block '${ctx.activePhaseName}' wurde nicht mit 'end${ctx.activePhaseName};' geschlossen.`, vscode.DiagnosticSeverity.Error); } if (ctx.inBlock !== 'pattern') { ctx.addDiag(lineIdx, 0, 11, "'end pattern' gefunden, ohne offenen Pattern-Block.", vscode.DiagnosticSeverity.Error); } ctx.inBlock = 'none'; } @@ -174,8 +161,4 @@ export class BlockRule implements LinterRule { else { ctx.addDiag(lineIdx, 0, line.length, "'end define' gefunden, ohne offenes 'define'.", vscode.DiagnosticSeverity.Error); } } } - - public checkEnd(lines: string[], ctx: LinterContext): void { - // empty - } } \ No newline at end of file