Skip to content

Cache binding occurrences for faster global references/rename/highlight#486

Merged
aviatesk merged 3 commits intomasterfrom
avi/cache-binding-occurrences
Jan 16, 2026
Merged

Cache binding occurrences for faster global references/rename/highlight#486
aviatesk merged 3 commits intomasterfrom
avi/cache-binding-occurrences

Conversation

@aviatesk
Copy link
Owner

@aviatesk aviatesk commented Jan 16, 2026

Cache compute_binding_occurrences results per top-level expression
to avoid redundant lowering when searching the same file multiple times.

Changes

On-demand caching (18bddc7)

Add BindingOccurrencesCache keyed by top-level expression byte range. When textDocument/references or textDocument/rename searches a file, the binding occurrence analysis is cached and reused for subsequent requests within the same analysis unit.

Cache invalidation follows the same pattern as document_symbol_cache:

  • textDocument/didChange for synced files
  • workspace/didChangeWatchedFiles for unsynced files

Memory optimization (0f6874d)

Full JS.SyntaxTree and JL.BindingInfo objects hold references to large internal structures. Introduce lightweight types that store only what LSP operations need:

  • BindingInfoKey: (mod, name) tuple
  • CachedSyntaxTree: byte range and source location only
  • CachedBindingOccurrence: combines above with binding kind

document-highlight refactor (8a827a0)

Refactor global_document_highlights! to use find_global_binding_occurrences!, allowing document highlight to benefit from the cache.

Add `BindingOccurrencesCache` to cache `compute_binding_occurrences`
results per top-level expression, keyed by byte range.

This avoids redundant lowering and binding analysis when the same file
is searched multiple times during global references or rename operations.

Cache invalidation follows the same pattern as `document_symbol_cache`:
- `textDocument/didChange` for synced files
- `workspace/didChangeWatchedFiles` for unsynced files

Note: Invalidation when full-analysis updates module context is not yet
implemented (see TODO in types.jl).
Reduce cache memory usage from ~100MB to ~11MB by not storing full
`JS.SyntaxTree` and `JL.BindingInfo` objects, which hold references to
large internal structures (syntax graphs, lowering contexts).

Instead, introduce lightweight cache types that store only the essential
information needed for LSP operations:
- `BindingInfoKey`: stores only `(mod, name)` from `BindingInfo`
- `CachedSyntaxTree`: stores only byte range and source location
- `CachedBindingOccurrence`: combines the above with binding kind

`CachedSyntaxTree` implements the minimum `JS.SyntaxTree` API required
by `jsobj_to_range`, maintaining compatibility with existing code via
duck typing.
Refactor `global_document_highlights!` to use `find_global_binding_occurrences!`
instead of duplicating the binding occurrence computation logic. This
allows document highlight to benefit from the binding occurrences cache.

Also simplify function signatures by replacing the complex union type
`module_info::Union{Tuple{ServerState,URI},Module}` and optional
`location_info` keyword with required positional `state` and `uri`
arguments.
@aviatesk aviatesk force-pushed the avi/cache-binding-occurrences branch from 231c034 to 8a827a0 Compare January 16, 2026 14:29
@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

❌ Patch coverage is 88.67925% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.51%. Comparing base (d80176b) to head (8a827a0).
⚠️ Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
src/utils/binding.jl 89.28% 3 Missing ⚠️
src/did-change-watched-files.jl 0.00% 1 Missing ⚠️
src/document-highlight.jl 93.33% 1 Missing ⚠️
src/types.jl 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #486      +/-   ##
==========================================
+ Coverage   67.43%   67.51%   +0.08%     
==========================================
  Files          46       46              
  Lines        6519     6539      +20     
==========================================
+ Hits         4396     4415      +19     
- Misses       2123     2124       +1     
Flag Coverage Δ
JETLS.jl 67.51% <88.67%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aviatesk aviatesk merged commit 5b1a499 into master Jan 16, 2026
12 of 13 checks passed
@aviatesk aviatesk deleted the avi/cache-binding-occurrences branch January 16, 2026 15:23
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