Skip to content

Commit 1f71596

Browse files
authored
Merge pull request #301 from julia-vscode/sp/misc-fixes
fix: adjust jl_module_names ccall
2 parents 9f41f77 + 6e18942 commit 1f71596

File tree

4 files changed

+72
-18
lines changed

4 files changed

+72
-18
lines changed

src/faketypes.jl

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ function _parameter(@nospecialize(p))
7676
end
7777
end
7878

79-
Base.print(io::IO, vr::VarRef) = vr.parent === nothing ? print(io, vr.name) : print(io, vr.parent, ".", vr.name)
80-
function Base.print(io::IO, tn::FakeTypeName)
79+
Base.show(io::IO, vr::VarRef) = vr.parent === nothing ? print(io, vr.name) : print(io, vr.parent, ".", vr.name)
80+
function Base.show(io::IO, tn::FakeTypeName)
8181
print(io, tn.name)
8282
if !isempty(tn.parameters)
8383
print(io, "{")
@@ -88,17 +88,17 @@ function Base.print(io::IO, tn::FakeTypeName)
8888
print(io, "}")
8989
end
9090
end
91-
Base.print(io::IO, x::FakeUnionAll) = print(io, x.body, " where ", x.var)
92-
function Base.print(io::IO, x::FakeUnion; inunion=false)
93-
!inunion && print(io, "Union{")
91+
Base.show(io::IO, x::FakeUnionAll) = print(io, x.body, " where ", x.var)
92+
function Base.show(io::IO, x::FakeUnion; inunion=false)
93+
!inunion && print(io, "Union{")
9494
print(io, x.a, ",")
9595
if x.b isa FakeUnion
96-
print(io, x.b, inunion=true)
96+
Base.show(io, x.b; inunion=true)
9797
else
9898
print(io, x.b, "}")
9999
end
100100
end
101-
function Base.print(io::IO, x::FakeTypeVar)
101+
function Base.show(io::IO, x::FakeTypeVar)
102102
if isfakebottom(x.lb)
103103
if isfakeany(x.ub)
104104
print(io, x.name)
@@ -126,6 +126,13 @@ Base.:(==)(a::FakeUnionAll, b::FakeUnionAll) = a.var == b.var && a.body == b.bod
126126
Base.:(==)(a::FakeUnion, b::FakeUnion) = a.a == b.a && a.b == b.b
127127
Base.:(==)(a::FakeTypeofBottom, b::FakeTypeofBottom) = true
128128

129+
Base.hash(a::FakeTypeName, h::UInt) = hash(a.name, hash(a.parameters, hash(:FakeTypeName, h)))
130+
Base.hash(a::VarRef, h::UInt) = hash(a.name, hash(a.parent, hash(:VarRef, h)))
131+
Base.hash(a::FakeTypeVar, h::UInt) = hash(a.name, hash(a.lb, hash(a.ub, hash(:FakeTypeVar, h))))
132+
Base.hash(a::FakeUnionAll, h::UInt) = hash(a.var, hash(a.body, hash(:FakeUnionAll, h)))
133+
Base.hash(a::FakeUnion, h::UInt) = hash(a.a, hash(a.b, hash(:FakeUnion, h)))
134+
Base.hash(::FakeTypeofBottom, h::UInt) = hash(:FakeTypeofBottom, h)
135+
129136
@static if !(Vararg isa Type)
130137
struct FakeTypeofVararg
131138
T

src/symbols.jl

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Base.getindex(m::ModuleStore, k) = m.vals[k]
2121
Base.setindex!(m::ModuleStore, v, k) = (m.vals[k] = v)
2222
Base.haskey(m::ModuleStore, k) = haskey(m.vals, k)
2323

24+
Base.show(io::IO, ms::ModuleStore) = print(io, "ModuleStore($(ms.name)) with $(length(ms.vals)) entries")
25+
2426
const EnvStore = Dict{Symbol,ModuleStore}
2527

2628
struct Package
@@ -41,6 +43,14 @@ struct MethodStore
4143
rt::Any
4244
end
4345

46+
function Base.show(io::IO, ms::MethodStore)
47+
print(io, ms.mod, ".", ms.name, "(")
48+
for (a,b) in ms.sig
49+
print(io, a, "::", b)
50+
end
51+
print(io, ") at ", ms.file, ":", ms.line, )
52+
end
53+
4454
struct DataTypeStore <: SymStore
4555
name::FakeTypeName
4656
super::FakeTypeName
@@ -77,6 +87,10 @@ function DataTypeStore(@nospecialize(t), symbol, parent_mod, exported)
7787
DataTypeStore(FakeTypeName(ur_t), FakeTypeName(ur_t.super), parameters, types, isconcretetype(ur_t) && fieldcount(ur_t) > 0 ? collect(fieldnames(ur_t)) : Symbol[], MethodStore[], _doc(Base.Docs.Binding(parent_mod, symbol)), exported)
7888
end
7989

90+
function Base.show(io::IO, dts::DataTypeStore)
91+
print(io, dts.name, " <: ", dts.super, " with $(length(dts.methods)) methods")
92+
end
93+
8094
struct FunctionStore <: SymStore
8195
name::VarRef
8296
methods::Vector{MethodStore}
@@ -93,6 +107,10 @@ function FunctionStore(@nospecialize(f), symbol, parent_mod, exported)
93107
end
94108
end
95109

110+
function Base.show(io::IO, fs::FunctionStore)
111+
print(io, fs.name, " with $(length(fs.methods)) methods")
112+
end
113+
96114
struct GenericStore <: SymStore
97115
name::VarRef
98116
typ::Any
@@ -246,7 +264,9 @@ function cache_methods(@nospecialize(f), name, env, get_return_type)
246264
elseif !(modstore[name] isa DataTypeStore || modstore[name] isa FunctionStore)
247265
modstore[name] = FunctionStore(VarRef(mvr, name), MethodStore[m[2]], "", func_vr, false)
248266
else
249-
push!(modstore[name].methods, m[2])
267+
if !(m[2] in modstore[name].methods)
268+
push!(modstore[name].methods, m[2])
269+
end
250270
end
251271
end
252272
return ms
@@ -273,7 +293,7 @@ end
273293
function apply_to_everything(f, m = nothing, visited = Base.IdSet{Module}())
274294
if m isa Module
275295
push!(visited, m)
276-
for s in unsorted_names(m, all = true, imported = true)
296+
for s in unsorted_names(m, all = true, imported = true, usings = true)
277297
(!isdefined(m, s) || s == nameof(m)) && continue
278298
x = getfield(m, s)
279299
f(x)
@@ -294,7 +314,7 @@ function oneverything(f, m = nothing, visited = Base.IdSet{Module}())
294314
if m isa Module
295315
push!(visited, m)
296316
state = nothing
297-
for s in unsorted_names(m, all = true, imported = true)
317+
for s in unsorted_names(m, all = true, imported = true, usings = true)
298318
!isdefined(m, s) && continue
299319
x = getfield(m, s)
300320
state = f(m, s, x, state)
@@ -363,7 +383,7 @@ istoplevelmodule(m) = parentmodule(m) === m || parentmodule(m) === Main
363383
function getmoduletree(m::Module, amn, visited = Base.IdSet{Module}())
364384
push!(visited, m)
365385
cache = ModuleStore(m)
366-
for s in unsorted_names(m, all = true, imported = true)
386+
for s in unsorted_names(m, all = true, imported = true, usings = true)
367387
!isdefined(m, s) && continue
368388
x = getfield(m, s)
369389
if x isa Module
@@ -401,7 +421,7 @@ end
401421
all_names(m) = all_names(m, x -> isdefined(m, x))
402422
function all_names(m, pred, symbols = Set(Symbol[]), seen = Set(Module[]))
403423
push!(seen, m)
404-
ns = unsorted_names(m; all = true, imported = false)
424+
ns = unsorted_names(m; all = true, imported = false, usings = false)
405425
for n in ns
406426
isdefined(m, n) || continue
407427
Base.isdeprecated(m, n) && continue
@@ -416,6 +436,11 @@ function all_names(m, pred, symbols = Set(Symbol[]), seen = Set(Module[]))
416436
symbols
417437
end
418438

439+
# On 1.12, names() includes bindings from Core in Base even not requested,
440+
# so we filter those out below. This could also be a version check, but doing it
441+
# this way should be more robust
442+
const CORE_BASE_NAMES_CONFUSION = :Bool in names(Base)
443+
419444
function symbols(env::EnvStore, m::Union{Module,Nothing} = nothing, allnames::Base.IdSet{Symbol} = getallns(), visited = Base.IdSet{Module}(); get_return_type = false)
420445
if m isa Module
421446
cache = _lookup(VarRef(m), env, true)
@@ -425,8 +450,13 @@ function symbols(env::EnvStore, m::Union{Module,Nothing} = nothing, allnames::Ba
425450
for s in ns
426451
!isdefined(m, s) && continue
427452
x = getfield(m, s)
453+
454+
if CORE_BASE_NAMES_CONFUSION && m === Base && isdefined(Core, s) && getfield(Core, s) === x
455+
continue
456+
end
457+
428458
if Base.unwrap_unionall(x) isa DataType # Unions aren't handled here.
429-
if parentmodule((x)) === m
459+
if parentmodule(x) === m
430460
cache[s] = DataTypeStore(x, s, m, s in getnames(m))
431461
cache_methods(x, s, env, get_return_type)
432462
elseif nameof(x) !== s

src/utils.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,13 @@ extends_methods(f::FunctionStore) = f.name != f.extends
341341
get_top_module(vr::VarRef) = vr.parent === nothing ? vr.name : get_top_module(vr.parent)
342342

343343
# Sorting is the main performance of calling `names`
344-
unsorted_names(m::Module; all::Bool=false, imported::Bool=false) =
345-
ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint), m, all, imported)
344+
@static if VERSION < v"1.12-"
345+
unsorted_names(m::Module; all::Bool=false, imported::Bool=false, usings=false) =
346+
ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint), m, all, imported)
347+
else
348+
unsorted_names(m::Module; all::Bool=false, imported::Bool=false, usings=false) =
349+
ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, all, imported, usings)
350+
end
346351

347352
## recursive_copy
348353
#

test/runtests.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ using Base: UUID
44
using Test
55

66
allns = SymbolServer.getallns()
7-
function missingsymbols(m::Module, cache::SymbolServer.ModuleStore, env)
7+
function missingsymbols(m::Module, cache::SymbolServer.ModuleStore, env; excludecore = false)
88
notfound = Symbol[]
99
notfoundhidden = Symbol[]
1010
for n in names(m, all=true)
1111
if isdefined(m, n) && !haskey(cache.vals, n)
12+
if excludecore && isdefined(Core, n)
13+
continue
14+
end
1215
push!(notfound, n)
1316
end
1417
end
@@ -67,8 +70,17 @@ end
6770
SymbolServer.symbols(env)
6871
r = missingsymbols(Core, env[:Core], env)
6972
@test length.(r) == (0, 0)
70-
r = missingsymbols(Base, env[:Base], env)
71-
@test length.(r) == (0, 0)
73+
74+
if VERSION >= v"1.12-"
75+
# on 1.12, names() includes bindings from Core in Base even not requested,
76+
# so we filter those out here
77+
r = missingsymbols(Base, env[:Base], env; excludecore = true)
78+
@test length.(r) == (0, 0)
79+
else
80+
r = missingsymbols(Base, env[:Base], env)
81+
@test length.(r) == (0, 0)
82+
end
83+
7284
@testset "VarRef loops" begin
7385
check_varrefs(env)
7486
end

0 commit comments

Comments
 (0)