linter fixes, fixes after refactoring and error fixing after i made MetadataRule seperate from BlockRule
This commit is contained in:
parent
9dcbf58f3a
commit
387f3793df
|
|
@ -0,0 +1 @@
|
|||
npm run lint -- --fix
|
||||
|
|
@ -8,7 +8,7 @@ import { IndentationRule } from './rules/IndentationRule'; // 1. Hier importiere
|
|||
// ... (deine eventuellen anderen Hilfs-Imports wie trackStrings) ...
|
||||
|
||||
export function validateTplDocument(document: vscode.TextDocument, collection: vscode.DiagnosticCollection) {
|
||||
if (document.languageId !== 'tpl') return;
|
||||
if (document.languageId !== 'tpl') {return;}
|
||||
|
||||
const text = document.getText();
|
||||
const lines = text.split('\n');
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ export class IndentationRule implements LinterRule {
|
|||
|
||||
public checkLine(line: string, rawLine: string, lineIdx: number, ctx: LinterContext, lines: string[]): void {
|
||||
// Leere Zeilen oder Zeilen, die nur aus Leerzeichen/Tabs bestehen, ignorieren
|
||||
if (rawLine.trim().length === 0) return;
|
||||
if (rawLine.trim().length === 0) {return;}
|
||||
|
||||
// Wenn Tabs drin sind, meckert die SyntaxRule bereits. Das ignorieren wir hier.
|
||||
if (rawLine.includes('\t')) return;
|
||||
if (rawLine.includes('\t')) {return;}
|
||||
|
||||
const leadingSpacesMatch = rawLine.match(/^ +/);
|
||||
const spaceCount = leadingSpacesMatch ? leadingSpacesMatch[0].length : 0;
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ export class MetadataRule implements LinterRule {
|
|||
const config = vscode.workspace.getConfiguration('tpl');
|
||||
|
||||
// Felder erfassen
|
||||
if (line.match(/^origin\b/)) ctx.foundModuleMetadata.add('origin');
|
||||
if (line.match(/^author\b/)) ctx.foundModuleMetadata.add('author');
|
||||
if (line.match(/^products\b/)) ctx.foundModuleMetadata.add('products');
|
||||
if (line.match(/^publishers\b/)) ctx.foundModuleMetadata.add('publishers');
|
||||
if (line.match(/^origin\b/)) {ctx.foundModuleMetadata.add('origin');}
|
||||
if (line.match(/^author\b/)) {ctx.foundModuleMetadata.add('author');}
|
||||
if (line.match(/^products\b/)) {ctx.foundModuleMetadata.add('products');}
|
||||
if (line.match(/^publishers\b/)) {ctx.foundModuleMetadata.add('publishers');}
|
||||
|
||||
// Tree-Path Sonderprüfung
|
||||
if (line.match(/^tree_path\b/)) {
|
||||
|
|
@ -60,11 +60,11 @@ export class MetadataRule implements LinterRule {
|
|||
|
||||
private checkRequiredFields(ctx: LinterContext, config: vscode.WorkspaceConfiguration) {
|
||||
const requiredFields: string[] = [];
|
||||
if (config.get<boolean>('metadata.require.origin', true)) requiredFields.push('origin');
|
||||
if (config.get<boolean>('metadata.require.author', true)) requiredFields.push('author');
|
||||
if (config.get<boolean>('metadata.require.products', true)) requiredFields.push('products');
|
||||
if (config.get<boolean>('metadata.require.publishers', true)) requiredFields.push('publishers');
|
||||
if (config.get<boolean>('metadata.require.treePath', true)) requiredFields.push('tree_path');
|
||||
if (config.get<boolean>('metadata.require.origin', true)) {requiredFields.push('origin');}
|
||||
if (config.get<boolean>('metadata.require.author', true)) {requiredFields.push('author');}
|
||||
if (config.get<boolean>('metadata.require.products', true)) {requiredFields.push('products');}
|
||||
if (config.get<boolean>('metadata.require.publishers', true)) {requiredFields.push('publishers');}
|
||||
if (config.get<boolean>('metadata.require.treePath', true)) {requiredFields.push('tree_path');}
|
||||
|
||||
const missing = requiredFields.filter(f => !ctx.foundModuleMetadata.has(f));
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export class SyntaxRule implements LinterRule {
|
|||
const commentIdx = cleanLine.indexOf('//');
|
||||
let codePart = commentIdx !== -1 ? cleanLine.substring(0, commentIdx).trim() : cleanLine.trim();
|
||||
|
||||
if (codePart.length === 0) return;
|
||||
if (codePart.length === 0) {return;}
|
||||
|
||||
let isStructuralKeyword = /^(tpl|pattern|syncmapping|table|definitions?|define|enumeration|configuration|metadata|overview|constants|triggers|mapping|removal|body|end|on|tags|origin|author|products|publishers|tree_path|import|from)\b/.test(codePart);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { tplBuiltIns } from '../data/TplBuiltIns';
|
|||
export class TplHoverProvider implements vscode.HoverProvider {
|
||||
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> {
|
||||
const range = document.getWordRangeAtPosition(position, /[a-zA-Z0-9_.]+/);
|
||||
if (!range) return null;
|
||||
if (!range) {return null;}
|
||||
|
||||
const word = document.getText(range);
|
||||
const text = document.getText();
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ export class MetadataFix implements TplQuickFix {
|
|||
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`;
|
||||
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`;}
|
||||
|
||||
fix.edit.insert(document.uri, new vscode.Position(diagnostic.range.start.line + 1, 0), insertText);
|
||||
fix.diagnostics = [diagnostic];
|
||||
|
|
|
|||
|
|
@ -3,18 +3,15 @@ import { CompletionStrategy } from './CompletionStrategy';
|
|||
|
||||
export class SnippetCompletion implements CompletionStrategy {
|
||||
public async provideCompletions(document: vscode.TextDocument, position: vscode.Position, linePrefix: string): Promise<vscode.CompletionItem[] | undefined> {
|
||||
// Bei Modul-Aufrufen (Punkt) keine Snippets feuern
|
||||
if (linePrefix.match(/\.[a-zA-Z0-9_]*$/)) { return undefined; }
|
||||
|
||||
const items: vscode.CompletionItem[] = [];
|
||||
|
||||
// 1. Kontext herausfinden (Sind wir in einem Pattern oder Syncmapping?)
|
||||
const textBeforeCursor = document.getText(new vscode.Range(new vscode.Position(0, 0), position));
|
||||
const inPattern = textBeforeCursor.lastIndexOf('pattern ') > textBeforeCursor.lastIndexOf('end pattern;');
|
||||
const inSyncmapping = textBeforeCursor.lastIndexOf('syncmapping ') > textBeforeCursor.lastIndexOf('end syncmapping;');
|
||||
const inBlock = inPattern || inSyncmapping;
|
||||
|
||||
// 2. Settings laden
|
||||
const config = vscode.workspace.getConfiguration('tpl');
|
||||
const author = config.get<string>('metadata.author', 'Kuro');
|
||||
const origin = config.get<string>('metadata.origin', 'Custom');
|
||||
|
|
@ -35,47 +32,38 @@ export class SnippetCompletion implements CompletionStrategy {
|
|||
treePathStr += `'\${${snippetTabIdx}:Level_${i+1}}'`;
|
||||
snippetTabIdx++;
|
||||
}
|
||||
if (i < minLevels - 1) treePathStr += ', ';
|
||||
if (i < minLevels - 1) {treePathStr += ', ';}
|
||||
}
|
||||
|
||||
// Dynamischer Metadata-String
|
||||
// Dynamischer Modul-Metadata-Block
|
||||
let metadataBlock = 'metadata\n';
|
||||
if (config.get<boolean>('metadata.require.origin', true)) metadataBlock += ` origin := '${origin}';\n`;
|
||||
if (config.get<boolean>('metadata.require.treePath', true)) metadataBlock += ` tree_path := ${treePathStr};\n`;
|
||||
if (config.get<boolean>('metadata.require.products', true)) metadataBlock += ` products := '\${${snippetTabIdx++}:Product}';\n`;
|
||||
if (config.get<boolean>('metadata.require.publishers', true)) metadataBlock += ` publishers := '${publisher}';\n`;
|
||||
if (config.get<boolean>('metadata.require.author', true)) metadataBlock += ` author := '${author}';\n`;
|
||||
if (config.get<boolean>('metadata.require.origin', true)) {metadataBlock += ` origin := '${origin}';\n`;}
|
||||
if (config.get<boolean>('metadata.require.treePath', true)) {metadataBlock += ` tree_path := ${treePathStr};\n`;}
|
||||
if (config.get<boolean>('metadata.require.products', true)) {metadataBlock += ` products := '\${${snippetTabIdx++}:Product}';\n`;}
|
||||
if (config.get<boolean>('metadata.require.publishers', true)) {metadataBlock += ` publishers := '${publisher}';\n`;}
|
||||
if (config.get<boolean>('metadata.require.author', true)) {metadataBlock += ` author := '${author}';\n`;}
|
||||
metadataBlock += 'end metadata;';
|
||||
|
||||
// ==========================================
|
||||
// SNIPPETS FÜR DIE MODUL-EBENE (Außerhalb)
|
||||
// ==========================================
|
||||
if (!inBlock) {
|
||||
const skeleton = new vscode.CompletionItem('tpl_skeleton', vscode.CompletionItemKind.Snippet);
|
||||
skeleton.detail = "Generiert ein frisches TPL Modul";
|
||||
skeleton.insertText = new vscode.SnippetString(
|
||||
`tpl 1.\${1:${version}} module \${2:MyModule};\n\n` +
|
||||
`metadata\n` +
|
||||
` origin := '${origin}';\n` +
|
||||
` tree_path := '${treePathBase}', '\${3:Category}', '\${4:Subcategory}';\n` +
|
||||
` products := '\${5:Product}';\n` +
|
||||
` publishers := '${publisher}';\n` +
|
||||
` author := '${author}';\n` +
|
||||
`end metadata;\n\n` +
|
||||
`pattern \${6:MyPattern} 1.0\n` +
|
||||
` """\n \${7:Beschreibung des Patterns}\n """\n` +
|
||||
`tpl 1.\${${snippetTabIdx++}:${version}} module \${${snippetTabIdx++}:MyModule};\n\n` +
|
||||
`${metadataBlock}\n\n` +
|
||||
`pattern \${${snippetTabIdx++}:MyPattern} 1.0\n` +
|
||||
` """\n \${${snippetTabIdx++}:Beschreibung des Patterns}\n """\n` +
|
||||
` metadata\n` +
|
||||
` publishers := '${publisher}';\n` +
|
||||
` tags := '\${8:Tags}';\n` +
|
||||
` tags := '\${${snippetTabIdx++}:Tags}';\n` +
|
||||
` end metadata;\n\n` +
|
||||
` overview\n` +
|
||||
` tags \${9:Tags};\n` +
|
||||
` tags \${${snippetTabIdx++}:Tags};\n` +
|
||||
` end overview;\n\n` +
|
||||
` constants\n` +
|
||||
` \${10:const_name} := '\${11:value}';\n` +
|
||||
` \${${snippetTabIdx++}:const_name} := '\${${snippetTabIdx++}:value}';\n` +
|
||||
` end constants;\n\n` +
|
||||
` triggers\n` +
|
||||
` on process := SoftwareInstance created, confirmed where type = '\${12:Type}';\n` +
|
||||
` on process := SoftwareInstance created, confirmed where type = '\${${snippetTabIdx++}:Type}';\n` +
|
||||
` end triggers;\n\n` +
|
||||
` body\n` +
|
||||
` log.debug("Start pattern %pattern_name%");\n` +
|
||||
|
|
@ -87,21 +75,10 @@ export class SnippetCompletion implements CompletionStrategy {
|
|||
|
||||
const modMeta = new vscode.CompletionItem('metadata', vscode.CompletionItemKind.Snippet);
|
||||
modMeta.detail = "Modul-Metadaten Block (Pflichtfelder)";
|
||||
modMeta.insertText = new vscode.SnippetString(
|
||||
`metadata\n` +
|
||||
` origin := '${origin}';\n` +
|
||||
` tree_path := '${treePathBase}', '\${1:Category}', '\${2:Subcategory}';\n` +
|
||||
` products := '\${3:Product}';\n` +
|
||||
` publishers := '${publisher}';\n` +
|
||||
` author := '${author}';\n` +
|
||||
`end metadata;\n$0`
|
||||
);
|
||||
modMeta.insertText = new vscode.SnippetString(`${metadataBlock}\n$0`);
|
||||
items.push(modMeta);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// SNIPPETS FÜR DIE PATTERN-EBENE (Innerhalb)
|
||||
// ==========================================
|
||||
if (inBlock) {
|
||||
const patMeta = new vscode.CompletionItem('metadata', vscode.CompletionItemKind.Snippet);
|
||||
patMeta.detail = "Pattern-Metadaten Block";
|
||||
|
|
@ -114,9 +91,6 @@ export class SnippetCompletion implements CompletionStrategy {
|
|||
items.push(patMeta);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// ALLGEMEINE SNIPPETS (Überall gültig)
|
||||
// ==========================================
|
||||
const ifSnippet = new vscode.CompletionItem('if', vscode.CompletionItemKind.Snippet);
|
||||
ifSnippet.insertText = new vscode.SnippetString(`if \${1:condition} then\n $0\nend if;`);
|
||||
items.push(ifSnippet);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ function createMockDoc(text: string): any {
|
|||
}
|
||||
|
||||
suite('Completion Provider Test Suite', () => {
|
||||
test('SnippetCompletion: Kontext-Check (Kein if außerhalb des Bodys)', () => {
|
||||
test('SnippetCompletion: Kontext-Check (Kein if außerhalb des Bodys)', async () => {
|
||||
const strategy = new SnippetCompletion();
|
||||
|
||||
// Simuliert, dass wir im "metadata" Block tippen
|
||||
|
|
@ -22,14 +22,14 @@ suite('Completion Provider Test Suite', () => {
|
|||
const mockDoc = createMockDoc(docText);
|
||||
const position = new vscode.Position(2, 4); // Zeile 2, Cursor am Ende
|
||||
|
||||
const result = strategy.provideCompletions(mockDoc, position, ' ');
|
||||
const result = await strategy.provideCompletions(mockDoc, position, ' ');
|
||||
|
||||
assert.ok(result !== undefined);
|
||||
const hasIf = result.some(item => item.label === 'if');
|
||||
const hasIf = result!.some(item => item.label === 'if');
|
||||
assert.strictEqual(hasIf, false, "Darf kein 'if' im metadata Block vorschlagen");
|
||||
});
|
||||
|
||||
test('SnippetCompletion: Vorschläge im Body korrekt', () => {
|
||||
test('SnippetCompletion: Vorschläge im Body korrekt', async () => {
|
||||
const strategy = new SnippetCompletion();
|
||||
|
||||
// Simuliert, dass wir im "body" tippen
|
||||
|
|
@ -37,10 +37,10 @@ suite('Completion Provider Test Suite', () => {
|
|||
const mockDoc = createMockDoc(docText);
|
||||
const position = new vscode.Position(2, 4);
|
||||
|
||||
const result = strategy.provideCompletions(mockDoc, position, ' ');
|
||||
const result = await strategy.provideCompletions(mockDoc, position, ' ');
|
||||
|
||||
assert.ok(result !== undefined);
|
||||
const hasIf = result.some(item => item.label === 'if');
|
||||
const hasIf = result!.some(item => item.label === 'if');
|
||||
assert.strictEqual(hasIf, true, "Muss 'if' im Body vorschlagen");
|
||||
});
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ suite('Completion Provider Test Suite', () => {
|
|||
const result = await strategy.provideCompletions(mockDoc, position, 'do');
|
||||
|
||||
assert.ok(result !== undefined);
|
||||
const funcItem = result.find(item => item.label === 'my_tools.doWork');
|
||||
const funcItem = result!.find(item => item.label === 'my_tools.doWork');
|
||||
assert.ok(funcItem !== undefined, "Muss die Methode inkl. Namespace extrahieren");
|
||||
|
||||
// Prüft, ob das generierte Snippet das Auto-Semikolon und den $0 Cursor hat
|
||||
|
|
|
|||
Loading…
Reference in New Issue