release: 2026-06-03#730
Merged
Merged
Conversation
Clarify why `FileInfo.syntax_tree0` exists and how it should be accessed. The field is an optional pruned `st0` cache for unsynced workspace files whose syntax trees are scanned repeatedly by diagnostics and global occurrence search. Mention `build_syntax_tree` as the access path because it returns a copy that can be safely passed through lowering, whose pipeline mutates syntax graph state. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Remove the unused raw-tree caching mode from `FileInfo`. The constructor now treats `cache_tree=true` as the single supported cached-tree path and always stores a pruned `st0`, matching the current unsynced-file use case and the field documentation. This keeps the default path cache-free while making the keyword type stricter and avoiding the misleading `nothing` / `false` distinction.
Closes #717
`FileInfo` now always stores a pruned `st0` snapshot. This moves the cost to file-info creation: the first read pays `build_tree` plus `JS.prune`, which is more expensive than rebuilding `st0` alone. `build_syntax_tree` returns a copy of that cache so lowering can mutate the tree without touching shared state. The synced-document path reuses the tree already built for testset discovery, and unsynced files no longer need a separate `cache_tree` switch. Performance measurement example: On this commit, `src/diagnostic.jl` is about 89KiB. Rebuilding `st0` for it takes about 11ms and allocates 12.1MiB across 153k objects. Building and pruning the initial cache takes about 22ms and 18.2MiB across 191k objects, while copying the cached pruned tree takes about 60us and 1.4MiB across 49 objects. That tradeoff is acceptable for synced documents because a normal edit is followed by several same-version requests, such as diagnostics, document links, document highlights, semantic tokens, and code actions. User interaction can then add hover, definition, document symbols, and occurrence queries. One caveat is that `JS.prune` preserves source locations but can collapse source-only provenance nodes. For example, short-form function definitions may lose the intermediate `K"function"` node and surface as `K"="` instead. `TypeAnnotation` handles this by falling back to method-like lowered nodes when dispatching type queries for that range. The same caveat appears in document symbols for `@nospecialize` arguments. After pruning, the provenance textref can survive in an st0-shaped macrocall, so document-symbol extraction accepts that shape alongside the st3 macrocall form. Co-authored-by: GPT-5 Codex <noreply@openai.com>
Add an optional per-`FileInfo` `InferredContextCache` and route synced LSP type-query paths through it. The cache is keyed by context module, world, and top-level range so stale analysis results are not reused. Only synchronized file snapshots allocate this cache. Unsynced `FileInfo` entries keep it as `nothing` to avoid retaining heavy inferred trees for workspace-wide paths. The memory measurements behind that choice are significant. A pruned `st0` cache for JETLS `src/` is about 29.74 MiB, with `src/diagnostic.jl` alone at 1.72 MiB. The inferred contexts are much heavier: about 10.41 MiB for `src/diagnostic.jl` and 5.89 MiB for `src/utils/ast.jl` after pruning and summary extraction. Measuring all of JETLS `src/` with file-appropriate context modules retains about 124.22 MiB for inferred-context cache entries, compared with 29.74 MiB for the pruned `st0` cache. That is a different cost profile from the `st0` cache, so the inferred cache stays scoped to synchronized documents. Cache misses build outside the cache lock, accepting duplicate inference during races so unrelated cache hits do not wait on lowering or inference. Full-analysis updates clear synced inferred-context caches so old analysis worlds can be released before the next type query rebuilds against the latest context. Tests cover cache hits, separate top-level entries, uncached rebuilds, cache clearing, and queryability through `get_type_for_range`. Co-authored-by: GPT-5 Codex <noreply@openai.com>
Remove the June 2026 legacy configuration aliases now that the announcement window has elapsed. Update the changelog entry to describe the aliases as removed instead of continuing the deprecation announcement.
…726) * analysis: Fix `unused-argument` false positive on nested `@generated` `compute_binding_occurrences` previously checked only whether the *top* of the lowerable subtree was a `@generated` macrocall (via `is_generated0(st0)`). That missed cases where the `@generated` function lives inside another construct -- e.g. as an inner constructor in a `struct` body -- producing a false `lowering/unused-argument` diagnostic and breaking find-references, document-highlight, and rename on the argument. The detection is now per-binding via `flattened_provenance`: for each `:argument` binding whose provenance includes a `@generated` ancestor, inert-node uses of the argument name within the same `@generated` macrocall range are recorded as `:use` occurrences. As a side effect, the `is_generated::Bool` parameter (and `st0` field destructuring at call sites) is dropped from `compute_binding_occurrences`, `_select_target_binding`, `local_document_highlights!`, `find_local_references!`, `find_local_binding_declarations`, and `local_binding_rename`, since the per-binding check on `st3` no longer needs a hint from the original parse tree. - Closes #722 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * analysis: Drop `SyntaxList` alloc in generated-arg detection `enclosing_generated_range` (formerly `innermost_generated_range`) no longer goes through `JS.flattened_provenance`, which would materialize a `SyntaxList` of the full macro-expansion chain just to find one entry. It now walks the chain step-by-step via `JS.macro_prov`, returning on the first `@generated` match -- no list allocation. Picking the innermost `@generated` is the semantically right choice here: - `@generated` cannot be a closure (Julia rejects nested `@generated function` at parse time with "Global method definition needs to be placed at the top level"), so the macro chain reaching any node we inspect contains at most one `@generated`; innermost and outermost coincide. - Even if nesting were possible, only the innermost `@generated`'s argument bindings have a static link to inert references in its body. An outer `@generated`'s parameters would appear as free identifiers in the inner body, with no static path back to the outer binding. Restores `compute_binding_occurrences` performance to master-level on JETLS source files measured with `experiments/jlbench.jl` (previously +7-10% from the per-binding provenance scan; now within noise). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * more tests --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Document the user-facing responsiveness improvements from reusing prepared syntax trees and prior type-aware analysis results.
* diagnostics: Clarify tail assignment diagnostics Address #723. In tail-position assignments, Julia returns the assignment expression, while the assigned binding itself may still never be read. For example, in: function f() x = 1 end the function returns the value of `x = 1`, not a later read of `x`. The old `Unused local binding x` wording did not explain that implicit-return distinction. JETLS now reports this message, wrapped here: Local binding `x` is not read; consider `return x` to return it explicitly For tail dead stores, JETLS similarly reports a message of the form, wrapped here: Value assigned to `x` is returned directly; consider `return x` to return the binding explicitly Classify returned assignment expressions and report this more specific message. Simple block-tail assignments also carry insertion metadata so the quick fix can add that explicit return. Co-Authored-By: Codex GPT-5 <noreply@openai.com> * address review comment, wording tweak --------- Co-authored-by: Codex GPT-5 <noreply@openai.com>
Avoid emitting empty `containerName` values for workspace symbols. The root cause is fixed in `document-symbol.jl` by preserving detail text for later bindings in multiline `let` and `for` headers. The `workspace_symbol_container_name` normalization is kept as a defensive guard against empty `containerName` values reaching workspace symbol responses. Co-authored-by: Codex GPT-5 <noreply@openai.com>
Prefer explicit return fixes before rename and deletion actions for tail unused local assignments. Suppress statement deletion when a value is returned implicitly, while keeping assignment deletion available. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Scope the pruned `st0` snapshot to synchronized documents and let unsynced `FileInfo` values rebuild syntax trees only on demand. Open documents still reuse copied cached trees, while workspace files no longer retain parsed syntax trees after global searches. Move workspace-wide diagnostics and global occurrence lookups toward summary caches instead: `PerFileDiagnosticsResult` now carries the cross-file summaries needed by diagnostics, and `BindingOccurrencesCache` stores a lazily built file-level global occurrence summary for warm definition, declaration, and reference searches. This keeps warm global searches at least comparable to the previous unsynced-`st0` cache path while reducing retained memory. In the JETLS self-analysis scenario measured during development, unsynced file cache size dropped by roughly 22 MiB, the occurrence cache grew by roughly 6 MiB, and the net major-cache footprint fell by about 16 MiB. End-to-end heap snapshots after `findReferences` showed the same order of improvement, from roughly 483 MiB down to 467 MiB. Co-authored-by: GPT-5 Codex <noreply@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR releases version
2026-06-03.Checklist
release / Test JETLS.jl with release environmentrelease / test_app / Test jetls serverelease / test_app / Test jetls checkrelease / test_app / Test jetls schemarelease / check_schemas / Check schemas are up to datePost-merge
releases/2026-06-03branch can be deleted after merging