refactor: extract LSP diagnostic report formatter (#21964)
This commit is contained in:
@@ -540,6 +540,8 @@ export namespace LSP {
|
|||||||
export const outgoingCalls = async (input: LocInput) => runPromise((svc) => svc.outgoingCalls(input))
|
export const outgoingCalls = async (input: LocInput) => runPromise((svc) => svc.outgoingCalls(input))
|
||||||
|
|
||||||
export namespace Diagnostic {
|
export namespace Diagnostic {
|
||||||
|
const MAX_PER_FILE = 20
|
||||||
|
|
||||||
export function pretty(diagnostic: LSPClient.Diagnostic) {
|
export function pretty(diagnostic: LSPClient.Diagnostic) {
|
||||||
const severityMap = {
|
const severityMap = {
|
||||||
1: "ERROR",
|
1: "ERROR",
|
||||||
@@ -554,5 +556,14 @@ export namespace LSP {
|
|||||||
|
|
||||||
return `${severity} [${line}:${col}] ${diagnostic.message}`
|
return `${severity} [${line}:${col}] ${diagnostic.message}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function report(file: string, issues: LSPClient.Diagnostic[]) {
|
||||||
|
const errors = issues.filter((item) => item.severity === 1)
|
||||||
|
if (errors.length === 0) return ""
|
||||||
|
const limited = errors.slice(0, MAX_PER_FILE)
|
||||||
|
const more = errors.length - MAX_PER_FILE
|
||||||
|
const suffix = more > 0 ? `\n... and ${more} more` : ""
|
||||||
|
return `<diagnostics file="${file}">\n${limited.map(pretty).join("\n")}${suffix}\n</diagnostics>`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,20 +258,13 @@ export const ApplyPatchTool = Tool.defineEffect(
|
|||||||
})
|
})
|
||||||
let output = `Success. Updated the following files:\n${summaryLines.join("\n")}`
|
let output = `Success. Updated the following files:\n${summaryLines.join("\n")}`
|
||||||
|
|
||||||
// Report LSP errors for changed files
|
|
||||||
const MAX_DIAGNOSTICS_PER_FILE = 20
|
|
||||||
for (const change of fileChanges) {
|
for (const change of fileChanges) {
|
||||||
if (change.type === "delete") continue
|
if (change.type === "delete") continue
|
||||||
const target = change.movePath ?? change.filePath
|
const target = change.movePath ?? change.filePath
|
||||||
const normalized = AppFileSystem.normalizePath(target)
|
const block = LSP.Diagnostic.report(target, diagnostics[AppFileSystem.normalizePath(target)] ?? [])
|
||||||
const issues = diagnostics[normalized] ?? []
|
if (!block) continue
|
||||||
const errors = issues.filter((item) => item.severity === 1)
|
const rel = path.relative(Instance.worktree, target).replaceAll("\\", "/")
|
||||||
if (errors.length > 0) {
|
output += `\n\nLSP errors detected in ${rel}, please fix:\n${block}`
|
||||||
const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE)
|
|
||||||
const suffix =
|
|
||||||
errors.length > MAX_DIAGNOSTICS_PER_FILE ? `\n... and ${errors.length - MAX_DIAGNOSTICS_PER_FILE} more` : ""
|
|
||||||
output += `\n\nLSP errors detected in ${path.relative(Instance.worktree, target).replaceAll("\\", "/")}, please fix:\n<diagnostics file="${target}">\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n</diagnostics>`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import { Instance } from "../project/instance"
|
|||||||
import { Snapshot } from "@/snapshot"
|
import { Snapshot } from "@/snapshot"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
|
|
||||||
const MAX_DIAGNOSTICS_PER_FILE = 20
|
|
||||||
|
|
||||||
function normalizeLineEndings(text: string): string {
|
function normalizeLineEndings(text: string): string {
|
||||||
return text.replaceAll("\r\n", "\n")
|
return text.replaceAll("\r\n", "\n")
|
||||||
}
|
}
|
||||||
@@ -166,16 +164,8 @@ export const EditTool = Tool.defineEffect(
|
|||||||
yield* lsp.touchFile(filePath, true)
|
yield* lsp.touchFile(filePath, true)
|
||||||
const diagnostics = yield* lsp.diagnostics()
|
const diagnostics = yield* lsp.diagnostics()
|
||||||
const normalizedFilePath = Filesystem.normalizePath(filePath)
|
const normalizedFilePath = Filesystem.normalizePath(filePath)
|
||||||
const issues = diagnostics[normalizedFilePath] ?? []
|
const block = LSP.Diagnostic.report(filePath, diagnostics[normalizedFilePath] ?? [])
|
||||||
const errors = issues.filter((item) => item.severity === 1)
|
if (block) output += `\n\nLSP errors detected in this file, please fix:\n${block}`
|
||||||
if (errors.length > 0) {
|
|
||||||
const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE)
|
|
||||||
const suffix =
|
|
||||||
errors.length > MAX_DIAGNOSTICS_PER_FILE
|
|
||||||
? `\n... and ${errors.length - MAX_DIAGNOSTICS_PER_FILE} more`
|
|
||||||
: ""
|
|
||||||
output += `\n\nLSP errors detected in this file, please fix:\n<diagnostics file="${filePath}">\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n</diagnostics>`
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
metadata: {
|
metadata: {
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { Instance } from "../project/instance"
|
|||||||
import { trimDiff } from "./edit"
|
import { trimDiff } from "./edit"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
|
|
||||||
const MAX_DIAGNOSTICS_PER_FILE = 20
|
|
||||||
const MAX_PROJECT_DIAGNOSTICS_FILES = 5
|
const MAX_PROJECT_DIAGNOSTICS_FILES = 5
|
||||||
|
|
||||||
export const WriteTool = Tool.defineEffect(
|
export const WriteTool = Tool.defineEffect(
|
||||||
@@ -72,20 +71,16 @@ export const WriteTool = Tool.defineEffect(
|
|||||||
const normalizedFilepath = AppFileSystem.normalizePath(filepath)
|
const normalizedFilepath = AppFileSystem.normalizePath(filepath)
|
||||||
let projectDiagnosticsCount = 0
|
let projectDiagnosticsCount = 0
|
||||||
for (const [file, issues] of Object.entries(diagnostics)) {
|
for (const [file, issues] of Object.entries(diagnostics)) {
|
||||||
const errors = issues.filter((item) => item.severity === 1)
|
const current = file === normalizedFilepath
|
||||||
if (errors.length === 0) continue
|
if (!current && projectDiagnosticsCount >= MAX_PROJECT_DIAGNOSTICS_FILES) continue
|
||||||
const limited = errors.slice(0, MAX_DIAGNOSTICS_PER_FILE)
|
const block = LSP.Diagnostic.report(current ? filepath : file, issues)
|
||||||
const suffix =
|
if (!block) continue
|
||||||
errors.length > MAX_DIAGNOSTICS_PER_FILE
|
if (current) {
|
||||||
? `\n... and ${errors.length - MAX_DIAGNOSTICS_PER_FILE} more`
|
output += `\n\nLSP errors detected in this file, please fix:\n${block}`
|
||||||
: ""
|
|
||||||
if (file === normalizedFilepath) {
|
|
||||||
output += `\n\nLSP errors detected in this file, please fix:\n<diagnostics file="${filepath}">\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n</diagnostics>`
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (projectDiagnosticsCount >= MAX_PROJECT_DIAGNOSTICS_FILES) continue
|
|
||||||
projectDiagnosticsCount++
|
projectDiagnosticsCount++
|
||||||
output += `\n\nLSP errors detected in other files:\n<diagnostics file="${file}">\n${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}\n</diagnostics>`
|
output += `\n\nLSP errors detected in other files:\n${block}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user