Skip to content

Commit 6458516

Browse files
committed
Merge branch 'master' into releases/2025-11-30
2 parents 8276103 + 4fc0d87 commit 6458516

File tree

6 files changed

+72
-70
lines changed

6 files changed

+72
-70
lines changed

CHANGELOG.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1818

1919
### Added
2020

21-
- JETLS now automatically runs `Pkg.instantiate()` for packages that have not
22-
been instantiated yet (e.g., freshly cloned repositories). This allows
23-
full analysis to work immediately upon opening such packages. Note that this
24-
will automatically create a `Manifest.toml` file when the package has not been
25-
instantiated yet. This behavior is controlled by the `full_analysis.auto_instantiate`
21+
- JETLS now automatically runs `Pkg.resolve()` and `Pkg.instantiate()` for
22+
packages that have not been instantiated yet (e.g., freshly cloned repositories).
23+
This allows full analysis to work immediately upon opening such packages.
24+
When no manifest file exists, JETLS first creates a
25+
[versioned manifest](https://pkgdocs.julialang.org/v1/toml-files/#Different-Manifests-for-Different-Julia-versions)
26+
(e.g., `Manifest-v1.12.toml`).
27+
This behavior is controlled by the `full_analysis.auto_instantiate`
2628
configuration option (default: `true`). Set it to `false` to disable.
2729
- When `full_analysis.auto_instantiate` is disabled, JETLS now checks if the
2830
environment is instantiated and warns the user if not.
@@ -36,6 +38,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
3638
opened simultaneously. Added global lock to `activate_do` to serialize
3739
environment switching operations. This fixes spurious "Failed to identify
3840
package environment" warnings.
41+
- Fixed document highlight and rename not working for function parameters
42+
annotated with `@nospecialize` or `@specialize`.
3943

4044
### Internal
4145

docs/src/configuration.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ debounce = 2.0 # Wait 2 seconds after save before analyzing
6565
- **Type**: boolean
6666
- **Default**: `true`
6767

68-
When enabled, JETLS automatically runs `Pkg.instantiate()` for packages that have
69-
not been instantiated yet (e.g., freshly cloned repositories). This allows full
70-
analysis to work immediately upon opening such packages. Note that this will
71-
automatically create a `Manifest.toml` file when the package has not been
72-
instantiated yet.
68+
When enabled, JETLS automatically runs `Pkg.resolve()` and `Pkg.instantiate()` for
69+
packages that have not been instantiated yet (e.g., freshly cloned repositories).
70+
This allows full analysis to work immediately upon opening such packages.
71+
When no manifest file exists, JETLS first creates a
72+
[versioned manifest](https://pkgdocs.julialang.org/v1/toml-files/#Different-Manifests-for-Different-Julia-versions)
73+
(e.g., `Manifest-v1.12.toml`).
7374

7475
```toml
7576
[full_analysis]

src/analysis/full-analysis.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,14 @@ end
676676
function ensure_instantiated!(server::Server, env_path::String)
677677
if get_config(server.state.config_manager, :full_analysis, :auto_instantiate)
678678
try
679+
manifest_name = "Manifest-v$(VERSION.major).$(VERSION.minor).toml"
680+
manifest_path = joinpath(dirname(env_path), manifest_name)
681+
if !isfile(manifest_path)
682+
JETLS_DEV_MODE && @info "Touching versioned manifest file" env_path
683+
touch(manifest_path)
684+
end
685+
JETLS_DEV_MODE && @info "Resolving package environment" env_path
686+
Pkg.resolve()
679687
JETLS_DEV_MODE && @info "Instantiating package environment" env_path
680688
Pkg.instantiate()
681689
catch e

src/utils/ast.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,30 @@ function without_kinds(st::JL.SyntaxTree, kinds::Tuple{Vararg{JS.Kind}})
3131
_without_kinds(st, kinds)[1])::JL.SyntaxTree
3232
end
3333

34+
function is_nospecialize_or_specialize_macrocall(st::JL.SyntaxTree)
35+
JS.kind(st) === JS.K"macrocall" || return false
36+
JS.numchildren(st) >= 1 || return false
37+
macro_name_node = st[1]
38+
JS.kind(macro_name_node) === JS.K"macro_name" || return false
39+
JS.numchildren(macro_name_node) >= 1 || return false
40+
macro_name = macro_name_node[1]
41+
JS.kind(macro_name) === JS.K"Identifier" || return false
42+
hasproperty(macro_name, :name_val) || return false
43+
return macro_name.name_val == "nospecialize" || macro_name.name_val == "specialize"
44+
end
45+
3446
function _remove_macrocalls(st::JL.SyntaxTree)
3547
if JS.kind(st) === JS.K"macrocall"
48+
if is_nospecialize_or_specialize_macrocall(st)
49+
# Special case `@nospecialize`/`@specialize`:
50+
# These macros are sometimes used in method definition argument lists, but
51+
# if we apply the `_remove_macrocalls` transformation directly, it would
52+
# result in a `:block` expression being inserted into the argument list,
53+
# preventing generation of a correct lowered tree.
54+
# Furthermore, JuliaLowering.jl provides new macro style definitions for
55+
# these macros, so there's no need to remove them in the first place.
56+
return st, false
57+
end
3658
new_children = JL.SyntaxList(JL.syntax_graph(st))
3759
for i = 2:JS.numchildren(st)
3860
push!(new_children, _remove_macrocalls(st[i])[1])

test/test_document_highlight.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,33 @@ end
119119
end
120120
end
121121

122+
@testset "highlight with @nospecialize" begin
123+
code = """
124+
function func(@nospecialize(│xxx│), yyy)
125+
zzz = │xxx│, yyy
126+
zzz, yyy
127+
end
128+
"""
129+
clean_code, positions = JETLS.get_text_and_positions(code)
130+
@test length(positions) == 4
131+
fi = JETLS.FileInfo(#=version=#0, clean_code, @__FILE__)
132+
@test issorted(positions; by = x -> JETLS.xy_to_offset(fi, x))
133+
for pos in positions
134+
highlights = JETLS.document_highlights(fi, pos)
135+
@test length(highlights) == 2
136+
@test any(highlights) do highlight
137+
highlight.range.start == positions[1] &&
138+
highlight.range.var"end" == positions[2] &&
139+
highlight.kind == DocumentHighlightKind.Write
140+
end
141+
@test any(highlights) do highlight
142+
highlight.range.start == positions[3] &&
143+
highlight.range.var"end" == positions[4] &&
144+
highlight.kind == DocumentHighlightKind.Read
145+
end
146+
end
147+
end
148+
122149
let code = """
123150
let │xxx│, │yyy│ = :yyy
124151
│xxx│ = :xxx

test/test_lookup_analysis_entry.jl

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)