const vscode = require('vscode'); const path = require('path'); // Import the linter from the main project const TestLinter = require('../../../src/linter'); class PlayWrongDiagnosticProvider { constructor() { this.linter = new TestLinter(); this.diagnosticCollection = vscode.languages.createDiagnosticCollection('playwrong'); } provideDiagnostics(document) { if (document.languageId !== 'playwrong') { return; } const text = document.getText(); const lintResult = this.linter.lint(text, document.fileName); const diagnostics = []; // Convert errors to diagnostics lintResult.errors.forEach(error => { const line = Math.max(0, error.line - 1); // Convert to 0-based const range = new vscode.Range(line, 0, line, Number.MAX_VALUE); const diagnostic = new vscode.Diagnostic( range, error.message, vscode.DiagnosticSeverity.Error ); diagnostic.source = 'PlayWrong Linter'; diagnostics.push(diagnostic); }); // Convert warnings to diagnostics lintResult.warnings.forEach(warning => { const line = Math.max(0, warning.line - 1); // Convert to 0-based const range = new vscode.Range(line, 0, line, Number.MAX_VALUE); const diagnostic = new vscode.Diagnostic( range, warning.message, vscode.DiagnosticSeverity.Warning ); diagnostic.source = 'PlayWrong Linter'; diagnostics.push(diagnostic); }); // Convert info to diagnostics (as information) lintResult.info.forEach(info => { const line = Math.max(0, info.line - 1); // Convert to 0-based const range = new vscode.Range(line, 0, line, Number.MAX_VALUE); const diagnostic = new vscode.Diagnostic( range, info.message, vscode.DiagnosticSeverity.Information ); diagnostic.source = 'PlayWrong Linter'; diagnostics.push(diagnostic); }); this.diagnosticCollection.set(document.uri, diagnostics); } clear() { this.diagnosticCollection.clear(); } dispose() { this.diagnosticCollection.dispose(); } } class PlayWrongExtension { constructor() { this.diagnosticProvider = new PlayWrongDiagnosticProvider(); } activate(context) { console.log('PlayWrong extension is now active!'); // Register diagnostic provider const activeEditor = vscode.window.activeTextEditor; if (activeEditor) { this.diagnosticProvider.provideDiagnostics(activeEditor.document); } // Listen for document changes const onDidChangeTextDocument = vscode.workspace.onDidChangeTextDocument(event => { if (event.document.languageId === 'playwrong') { this.diagnosticProvider.provideDiagnostics(event.document); } }); // Listen for document open const onDidOpenTextDocument = vscode.workspace.onDidOpenTextDocument(document => { if (document.languageId === 'playwrong') { this.diagnosticProvider.provideDiagnostics(document); } }); // Listen for active editor changes const onDidChangeActiveTextEditor = vscode.window.onDidChangeActiveTextEditor(editor => { if (editor && editor.document.languageId === 'playwrong') { this.diagnosticProvider.provideDiagnostics(editor.document); } }); // Register commands const lintCommand = vscode.commands.registerCommand('playwrong.lint', () => { const editor = vscode.window.activeTextEditor; if (!editor || editor.document.languageId !== 'playwrong') { vscode.window.showWarningMessage('Please open a PlayWrong test file (.test) to lint.'); return; } this.runLintCommand(editor.document, false); }); const lintStrictCommand = vscode.commands.registerCommand('playwrong.lintStrict', () => { const editor = vscode.window.activeTextEditor; if (!editor || editor.document.languageId !== 'playwrong') { vscode.window.showWarningMessage('Please open a PlayWrong test file (.test) to lint.'); return; } this.runLintCommand(editor.document, true); }); // Add disposables to context context.subscriptions.push( this.diagnosticProvider, onDidChangeTextDocument, onDidOpenTextDocument, onDidChangeActiveTextEditor, lintCommand, lintStrictCommand ); // Initial lint for already open documents vscode.workspace.textDocuments.forEach(document => { if (document.languageId === 'playwrong') { this.diagnosticProvider.provideDiagnostics(document); } }); } runLintCommand(document, strict) { const text = document.getText(); const lintResult = this.diagnosticProvider.linter.lint(text, document.fileName); let message = ''; let hasIssues = false; if (lintResult.errors.length > 0) { message += `❌ ${lintResult.errors.length} error(s)`; hasIssues = true; } if (lintResult.warnings.length > 0) { if (message) message += ', '; message += `⚠️ ${lintResult.warnings.length} warning(s)`; if (strict) hasIssues = true; } if (lintResult.info.length > 0) { if (message) message += ', '; message += `💡 ${lintResult.info.length} info`; } if (!message) { message = '✅ No issues found'; } const fileName = path.basename(document.fileName); const fullMessage = `${fileName}: ${message}`; if (hasIssues) { if (lintResult.errors.length > 0) { vscode.window.showErrorMessage(fullMessage); } else { vscode.window.showWarningMessage(fullMessage); } } else { vscode.window.showInformationMessage(fullMessage); } // Update diagnostics this.diagnosticProvider.provideDiagnostics(document); } deactivate() { this.diagnosticProvider.clear(); } } let extension; function activate(context) { extension = new PlayWrongExtension(); extension.activate(context); } function deactivate() { if (extension) { extension.deactivate(); } } module.exports = { activate, deactivate };