import * as vscode from "vscode" import * as path from "path" import deepEqual from "fast-deep-equal" export function getNewDiagnostics( oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][], newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] ): [vscode.Uri, vscode.Diagnostic[]][] { const newProblems: [vscode.Uri, vscode.Diagnostic[]][] = [] const oldMap = new Map(oldDiagnostics) for (const [uri, newDiags] of newDiagnostics) { const oldDiags = oldMap.get(uri) || [] const newProblemsForUri = newDiags.filter((newDiag) => !oldDiags.some((oldDiag) => deepEqual(oldDiag, newDiag))) if (newProblemsForUri.length > 0) { newProblems.push([uri, newProblemsForUri]) } } return newProblems } // Usage: // const oldDiagnostics = // ... your old diagnostics array // const newDiagnostics = // ... your new diagnostics array // const newProblems = getNewDiagnostics(oldDiagnostics, newDiagnostics); // Example usage with mocks: // // // Mock old diagnostics // const oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [ // [vscode.Uri.file("/path/to/file1.ts"), [ // new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error) // ]], // [vscode.Uri.file("/path/to/file2.ts"), [ // new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning) // ]] // ]; // // // Mock new diagnostics // const newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [ // [vscode.Uri.file("/path/to/file1.ts"), [ // new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error), // new vscode.Diagnostic(new vscode.Range(2, 2, 2, 12), "New error in file1", vscode.DiagnosticSeverity.Error) // ]], // [vscode.Uri.file("/path/to/file2.ts"), [ // new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning) // ]], // [vscode.Uri.file("/path/to/file3.ts"), [ // new vscode.Diagnostic(new vscode.Range(1, 1, 1, 11), "New error in file3", vscode.DiagnosticSeverity.Error) // ]] // ]; // // const newProblems = getNewProblems(oldDiagnostics, newDiagnostics); // // console.log("New problems:"); // for (const [uri, diagnostics] of newProblems) { // console.log(`File: ${uri.fsPath}`); // for (const diagnostic of diagnostics) { // console.log(`- ${diagnostic.message} (${diagnostic.range.start.line}:${diagnostic.range.start.character})`); // } // } // // // Expected output: // // New problems: // // File: /path/to/file1.ts // // - New error in file1 (2:2) // // File: /path/to/file3.ts // // - New error in file3 (1:1) // will return empty string if no problems with the given severity are found export function diagnosticsToProblemsString( diagnostics: [vscode.Uri, vscode.Diagnostic[]][], severities: vscode.DiagnosticSeverity[], cwd: string ): string { let result = "" for (const [uri, fileDiagnostics] of diagnostics) { const problems = fileDiagnostics.filter((d) => severities.includes(d.severity)) if (problems.length > 0) { result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}` for (const diagnostic of problems) { let label: string switch (diagnostic.severity) { case vscode.DiagnosticSeverity.Error: label = "Error" break case vscode.DiagnosticSeverity.Warning: label = "Warning" break case vscode.DiagnosticSeverity.Information: label = "Information" break case vscode.DiagnosticSeverity.Hint: label = "Hint" break default: label = "Diagnostic" } const line = diagnostic.range.start.line + 1 // VSCode lines are 0-indexed const source = diagnostic.source ? `${diagnostic.source} ` : "" result += `\n- [${source}${label}] Line ${line}: ${diagnostic.message}` } } } return result.trim() }