Skip to content

Fix duplicate and crashing "find all references" results - #1791

Open
TwitchBronBron wants to merge 1 commit into
masterfrom
fix-duplicate-references
Open

Fix duplicate and crashing "find all references" results#1791
TwitchBronBron wants to merge 1 commit into
masterfrom
fix-duplicate-references

Conversation

@TwitchBronBron

Copy link
Copy Markdown
Member

Two bugs in ReferencesProvider, both user-visible in the VSCode references panel today.

Duplicate results. processedFiles was declared inside the scope loop, so a file reachable through multiple scopes got re-walked once per scope. The search is a case-insensitive text match over the file AST, so every re-walk emitted identical Locations, and no layer between the provider and the LSP client dedupes them — a source/ file included by 3 components showed each reference 3× in the panel. Hoisting the set walks each file once across the whole traversal.

Worth noting since it looks like it might over-dedupe: references reachable through only one scope are still found, because the set keys on file, not scope. A test covers exactly that case (alpha referenced from a file unique to scope A and another unique to scope B — both still returned).

Crash on positions with no token. getTokenAt returns undefined when the cursor is past the end of a line, so callSiteToken.text threw. The plugin runner swallowed the error and the user silently got no references.

Tests: 11 new cases in ReferencesProvider.spec.ts (both fixes, scope-specific references, case-insensitivity, params, XML, and the three provideReferences plugin events, which had no coverage) plus one at the LanguageServer.onReferences level asserting no duplicate Locations reach the client. Verified both fixes fail their tests when reverted. npm run test:nocover 3048 → 3059 passing, lint and tsc --noEmit clean.

🤖 Generated with Claude Code

`ReferencesProvider` declared its `processedFiles` set inside the scope
loop, so a file reachable through multiple scopes was walked once per
scope. Since the search is a case-insensitive text match against the
file's AST, each of those walks produced identical `Location`s, and
nothing between the provider and the LSP client dedupes them — a file
included by 3 components showed every reference 3 times in the
references panel. Hoisting the set keeps each file walked once across
the whole traversal; references only reachable through a single scope
are still found, because the set keys on file rather than scope.

`getTokenAt` returns undefined when there is no token at the position
(e.g. the cursor is past the end of a line), which made the following
`.text` access throw. The plugin runner swallowed it, so the user
silently got no references.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant