Skip to content

Commit 6f9526e

Browse files
committed
chore(lsp): apply AI review suggestions
1 parent 7aada92 commit 6f9526e

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

packages/lsp/src/client.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export async function createLSPClient(input: {
6262

6363
const diagnostics = new Map<string, Diagnostic[]>()
6464
const files: Record<string, number> = {}
65+
const diagnosticPulls: Record<string, number> = {}
6566
let diagnosticsListeners: Array<{
6667
path: string
6768
resolve: () => void
@@ -96,13 +97,22 @@ export async function createLSPClient(input: {
9697
// Pull diagnostics for a single file (LSP textDocument/diagnostic). Used for
9798
// servers that advertise a diagnostic provider instead of pushing them
9899
// (e.g. typescript-go / tsgo). Failures are swallowed — absent diagnostics
99-
// must never break opening a file.
100+
// must never break opening a file. `pullID` uniquely identifies this request;
101+
// the response is discarded if a newer open/change/close superseded it, so an
102+
// out-of-order reply can't overwrite fresher diagnostics with stale ones.
100103
const pullDiagnostics = async (filePath: string): Promise<void> => {
101104
if (!supportsPullDiagnostics) { return }
105+
const pullID = (diagnosticPulls[filePath] ?? 0) + 1
106+
diagnosticPulls[filePath] = pullID
102107
try {
103-
const report = (await connection.sendRequest('textDocument/diagnostic', {
104-
textDocument: { uri: pathToFileURL(filePath).href },
105-
})) as { kind?: string, items?: Diagnostic[] } | null
108+
const report = (await withTimeout(
109+
connection.sendRequest('textDocument/diagnostic', {
110+
textDocument: { uri: pathToFileURL(filePath).href },
111+
}),
112+
DIAGNOSTICS_WAIT_TIMEOUT_MS,
113+
)) as { kind?: string, items?: Diagnostic[] } | null
114+
// Drop a response superseded by a newer pull or close.
115+
if (diagnosticPulls[filePath] !== pullID) { return }
106116
// A "full" report carries items; an "unchanged" report means keep the
107117
// previously reported set, so leave the map as-is.
108118
if (report?.kind === 'full' && Array.isArray(report.items)) {
@@ -240,6 +250,7 @@ export async function createLSPClient(input: {
240250
},
241251
})
242252
delete files[filePath]
253+
diagnosticPulls[filePath] = (diagnosticPulls[filePath] ?? 0) + 1
243254
diagnostics.delete(normalizePath(filePath))
244255
},
245256
},

packages/lsp/src/server/typescript.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export const TypescriptServer: LSPServerInfo = {
100100
const proc = spawn(native.command, ['--lsp', '--stdio'], {
101101
cwd: root,
102102
env: { ...process.env, BUN_BE_BUN: '1' },
103+
shell: process.platform === 'win32',
103104
})
104105
attachLSPProcessHandlers(proc, 'typescript')
105106
return { process: proc }

0 commit comments

Comments
 (0)