Skip to content

Commit 9a2adb1

Browse files
committed
Add indexVersion and cross-file diagnostics
Introduce a monotonically-increasing indexVersion in Analyzer and bump it whenever the global symbol index mutates (e.g. updateAllIndexes, removeFromIndex). In the diagnostics handler, track the analyzer indexVersion and, when it changes, schedule a debounced cross-file revalidation (CROSS_FILE_DEBOUNCE_MS = 800ms) that re-runs diagnostics for all open workspace documents except the triggering URI. Non-workspace files receive cleared diagnostics. This ensures open files pick up cross-file symbol additions/removals without requiring manual edits.
1 parent 2c6b50b commit 9a2adb1

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

server/src/analysis/project/graph.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,14 @@ export class Analyzer {
310310
/** Flag to mark when sorted arrays need rebuild */
311311
private symbolIndexDirty = false;
312312

313+
/**
314+
* Monotonically increasing counter bumped whenever the global symbol
315+
* index is mutated (file re-parsed, file deleted, etc.). Consumers
316+
* can compare snapshots to detect cross-file index changes.
317+
*/
318+
private _indexVersion = 0;
319+
get indexVersion(): number { return this._indexVersion; }
320+
313321
// ================================================================
314322
// CLASS INDEX for fast class lookups
315323
// ================================================================
@@ -335,6 +343,7 @@ export class Analyzer {
335343

336344
/** Update all indexes from a file's AST */
337345
private updateAllIndexes(uri: string, ast: File): void {
346+
this._indexVersion++;
338347
// Remove old entries from this URI
339348
this.removeIndexEntriesForUri(uri);
340349

@@ -694,6 +703,7 @@ export class Analyzer {
694703
* Also removes global symbol index entries and the doc cache entry.
695704
*/
696705
removeFromIndex(uri: string): void {
706+
this._indexVersion++;
697707
const normalizedUri = normalizeUri(uri);
698708
this.removeIndexEntriesForUri(normalizedUri);
699709
// Remove from global symbol index

server/src/lsp/handlers/diagnostics.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@ export function registerDiagnostics(conn: Connection, docs: TextDocuments<TextDo
2727
const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
2828
const DEBOUNCE_MS = 300;
2929

30+
// Cross-file revalidation: when the global symbol index changes
31+
// (e.g. Copilot adds a function to file A), other open files that
32+
// reference those symbols need their diagnostics refreshed too.
33+
const CROSS_FILE_DEBOUNCE_MS = 800;
34+
let crossFileTimer: ReturnType<typeof setTimeout> | undefined;
35+
let lastKnownIndexVersion = analyser.indexVersion;
36+
37+
/** Schedule a revalidation of all open docs EXCEPT `excludeUri`. */
38+
const scheduleCrossFileRevalidation = (excludeUri: string) => {
39+
if (crossFileTimer) clearTimeout(crossFileTimer);
40+
crossFileTimer = setTimeout(() => {
41+
crossFileTimer = undefined;
42+
for (const doc of docs.all()) {
43+
if (doc.uri === excludeUri) continue;
44+
if (!analyser.isWorkspaceFile(doc.uri)) {
45+
conn.sendDiagnostics({ uri: doc.uri, diagnostics: [] });
46+
continue;
47+
}
48+
const diagnostics = analyser.runDiagnostics(doc);
49+
conn.sendDiagnostics({ uri: doc.uri, diagnostics });
50+
}
51+
}, CROSS_FILE_DEBOUNCE_MS);
52+
};
53+
3054
docs.onDidOpen(validate);
3155
docs.onDidSave((change) => {
3256
// On save: cancel any pending debounce and run immediately
@@ -60,6 +84,15 @@ export function registerDiagnostics(conn: Connection, docs: TextDocuments<TextDo
6084
conn.sendDiagnostics({ uri, diagnostics });
6185
}
6286
}, DEBOUNCE_MS));
87+
88+
// If the global symbol index changed (new class/function/enum added
89+
// or removed), schedule a cross-file revalidation so other open
90+
// documents pick up the change without the user needing to touch them.
91+
const currentVersion = analyser.indexVersion;
92+
if (currentVersion !== lastKnownIndexVersion) {
93+
lastKnownIndexVersion = currentVersion;
94+
scheduleCrossFileRevalidation(uri);
95+
}
6396
});
6497

6598
docs.onDidClose((change) => {

0 commit comments

Comments
 (0)