1
using LibGit2, InteractiveUtils
2

3
mutable struct Server
4 30
    storedir::String
5
    context::Pkg.Types.Context
6
    depot::Dict
7
end
8

9
abstract type SymStore end
10
struct ModuleStore <: SymStore
11 30
    name::VarRef
12
    vals::Dict{Symbol,Any}
13
    doc::String
14
    exported::Bool
15
    exportednames::Vector{Symbol}
16
    used_modules::Vector{Symbol}
17
end
18

19 30
ModuleStore(m) = ModuleStore(VarRef(m), Dict{Symbol,Any}(), "", true, unsorted_names(m), Symbol[])
20 30
Base.getindex(m::ModuleStore, k) = m.vals[k]
21 30
Base.setindex!(m::ModuleStore, v, k) = (m.vals[k] = v)
22 30
Base.haskey(m::ModuleStore, k) = haskey(m.vals, k)
23

24
const EnvStore = Dict{Symbol,ModuleStore}
25

26
struct Package
27 30
    name::String
28
    val::ModuleStore
29
    ver::Any
30
    uuid::Base.UUID
31
    sha
32
end
33 0
Package(name::String, val::ModuleStore, ver, uuid::String, sha) = Package(name, val, ver, Base.UUID(uuid), sha)
34

35
struct MethodStore
36 30
    name::Symbol
37
    mod::Symbol
38
    file::String
39
    line::Int32
40
    sig::Vector{Pair{Any,Any}}
41
    kws::Vector{Symbol}
42
    rt::Any
43
end
44

45
struct DataTypeStore <: SymStore
46 30
    name::FakeTypeName
47
    super::FakeTypeName
48
    parameters::Vector{Any}
49
    types::Vector{Any}
50
    fieldnames::Vector{Any}
51
    methods::Vector{MethodStore}
52
    doc::String
53
    exported::Bool
54
end
55

56
function DataTypeStore(@nospecialize(t), parent_mod, exported)
57 30
    ur_t = Base.unwrap_unionall(t)
58 30
    parameters = if isdefined(ur_t, :parameters)
59 30
        map(ur_t.parameters) do p
60 10
            _parameter(p)
61
        end
62
    else
63 30
        []
64
    end
65 30
    types = if isdefined(ur_t, :types)
66 30
        map(ur_t.types) do p
67 10
            FakeTypeName(p)
68
        end
69
    else
70 30
        []
71
    end
72 30
    DataTypeStore(FakeTypeName(ur_t), FakeTypeName(ur_t.super), parameters, types, ur_t.isconcretetype && fieldcount(ur_t) > 0 ? collect(fieldnames(ur_t)) : Symbol[], MethodStore[], _doc(t), exported)
73
end
74

75
struct FunctionStore <: SymStore
76 30
    name::VarRef
77
    methods::Vector{MethodStore}
78
    doc::String
79
    extends::VarRef
80
    exported::Bool
81
end
82

83
function FunctionStore(@nospecialize(f), parent_mod, exported)
84 30
    if f isa Core.IntrinsicFunction
85 30
        FunctionStore(VarRef(VarRef(Core.Intrinsics), nameof(f)), MethodStore[], _doc(f), VarRef(VarRef(parentmodule(f)), nameof(f)), exported)
86
    else
87 30
        FunctionStore(VarRef(VarRef(parent_mod), nameof(f)), MethodStore[], _doc(f), VarRef(VarRef(parentmodule(f)), nameof(f)), exported)
88
    end
89
end
90

91
struct GenericStore <: SymStore
92 30
    name::VarRef
93
    typ::Any
94
    doc::String
95
    exported::Bool
96
end
97

98
# adapted from https://github.com/timholy/CodeTracking.jl/blob/afc73a957f5034cc7f02e084a91283c47882f92b/src/utils.jl#L87-L122
99

100
"""
101
    path = maybe_fix_path(path)
102

103
Return a normalized, absolute path for a source file `path`.
104
"""
105
function maybe_fix_path(file)
106 30
    if !isabspath(file)
107
        # This may be a Base or Core method
108 30
        newfile = Base.find_source_file(file)
109 30
        if isa(newfile, AbstractString)
110 30
            file = normpath(newfile)
111
        end
112
    end
113 30
    return maybe_fixup_stdlib_path(file)
114
end
115

116 30
safe_isfile(x) = try isfile(x); catch; false end
117
const BUILDBOT_STDLIB_PATH = dirname(abspath(joinpath(String((@which versioninfo()).file), "..", "..", "..")))
118 30
replace_buildbot_stdlibpath(str::String) = replace(str, BUILDBOT_STDLIB_PATH => Sys.STDLIB)
119
"""
120
    path = maybe_fixup_stdlib_path(path::String)
121

122
Return `path` corrected for julia issue [#26314](https://github.com/JuliaLang/julia/issues/26314) if applicable.
123
Otherwise, return the input `path` unchanged.
124

125
Due to the issue mentioned above, location info for methods defined one of Julia's standard libraries
126
are, for non source Julia builds, given as absolute paths on the worker that built the `julia` executable.
127
This function corrects such a path to instead refer to the local path on the users drive.
128
"""
129
function maybe_fixup_stdlib_path(path)
130 30
    if !safe_isfile(path)
131 30
        maybe_stdlib_path = replace_buildbot_stdlibpath(path)
132 30
        safe_isfile(maybe_stdlib_path) && return maybe_stdlib_path
133
    end
134 30
    return path
135
end
136

137
const _global_method_cache = IdDict{Any,Vector{Any}}()
138
function methodinfo(@nospecialize(f); types = Tuple, world = typemax(UInt))
139 30
    key = (f, types, world)
140 30
    cached = get(_global_method_cache, key, nothing)
141 30
    if cached === nothing
142 25
        cached = Base._methods(f, types, -1, world)
143 30
        _global_method_cache[key] = cached
144
    end
145 30
    return cached
146
end
147

148 0
function methodlist(@nospecialize(f))
149 0
    ms = methodinfo(f)
150 0
    Method[x[3]::Method for x in ms]
151
end
152

153
function cache_methods(@nospecialize(f), name, env)
154 30
    if isa(f, Core.Builtin)
155 30
        return MethodStore[]
156
    end
157 20
    types = Tuple
158 5
    world = typemax(UInt)
159 25
    ms = Tuple{Module,MethodStore}[]
160 30
    methods0 = try
161 30
        methodinfo(f; types = types, world = world)
162
    catch err
163 30
        return ms
164
    end
165 25
    ind_of_method_w_kws = Int[] # stores the index of methods with kws.
166 5
    i = 1
167 30
    for m in methods0
168 30
        file = maybe_fix_path(String(m[3].file))
169 30
        MS = MethodStore(m[3].name, nameof(m[3].module), file, m[3].line, [], Symbol[], FakeTypeName(Any))
170
        # Get signature
171 30
        sig = Base.unwrap_unionall(m[1])
172 30
        argnames = getargnames(m[3])
173 30
        for i = 2:m[3].nargs
174 30
            push!(MS.sig, argnames[i] => FakeTypeName(sig.parameters[i]))
175
        end
176 30
        kws = getkws(m[3])
177 30
        if !isempty(kws)
178 25
            push!(ind_of_method_w_kws, i)
179
        end
180 30
        for kw in kws
181 30
            push!(MS.kws, kw)
182
        end
183 30
        push!(ms, (m[3].module, MS))
184 30
        i += 1
185
    end
186
    # Go back and add kws to methods defined in the same place as others with kws.
187 30
    for i in ind_of_method_w_kws
188 30
        for j = 1:length(ms) # only need to go up to `i`?
189 30
            if ms[j][2].file == ms[i][2].file && ms[j][2].line == ms[i][2].line && isempty(ms[j][2].kws)
190 30
                for kw in ms[i][2].kws
191 30
                    push!(ms[j][2].kws, kw)
192
                end
193
            end
194
        end
195
    end
196

197 30
    func_vr = VarRef(VarRef(parentmodule(f)), name)
198 30
    for i = 1:length(ms)
199 30
        mvr = VarRef(ms[i][1])
200 30
        modstore = _lookup(mvr, env)
201 30
        if modstore !== nothing
202 30
            if !haskey(modstore, name)
203 30
                modstore[name] = FunctionStore(VarRef(mvr, name), MethodStore[ms[i][2]], "", func_vr, false)
204 30
            elseif !(modstore[name] isa DataTypeStore || modstore[name] isa FunctionStore)
205 30
                modstore[name] = FunctionStore(VarRef(mvr, name), MethodStore[ms[i][2]], "", func_vr, false)
206
            else
207 30
                push!(modstore[name].methods, ms[i][2])
208
            end
209
        else
210 30
        end
211
    end
212 30
    return ms
213
end
214

215 30
getargnames(m::Method) = Base.method_argnames(m)
216
@static if length(first(methods(Base.kwarg_decl)).sig.parameters) == 2
217
    getkws = Base.kwarg_decl
218
else
219 0
    function getkws(m::Method)
220 20
        sig = Base.unwrap_unionall(m.sig)
221 20
        length(sig.parameters) == 0 && return []
222 20
        sig.parameters[1] isa Union && return []
223 20
        !isdefined(Base.unwrap_unionall(sig.parameters[1]), :name) && return []
224 20
        fname = Base.unwrap_unionall(sig.parameters[1]).name
225 20
        if isdefined(fname.mt, :kwsorter)
226 20
            Base.kwarg_decl(m, typeof(fname.mt.kwsorter))
227
        else
228 20
            []
229
        end
230
    end
231
end
232

233 0
function apply_to_everything(f, m = nothing, visited = Base.IdSet{Module}())
234 0
    if m isa Module
235 0
        push!(visited, m)
236 0
        for s in unsorted_names(m, all = true, imported = true)
237 0
            (!isdefined(m, s) || s == nameof(m)) && continue
238 0
            x = getfield(m, s)
239 0
            f(x)
240 0
            if x isa Module && !in(x, visited)
241 0
                apply_to_everything(f, x, visited)
242
            end
243
        end
244
    else
245 0
        for m in Base.loaded_modules_array()
246 0
            in(m, visited) || apply_to_everything(f, m, visited)
247
        end
248
    end
249
end
250

251

252

253
function oneverything(f, m = nothing, visited = Base.IdSet{Module}())
254 30
    if m isa Module
255 25
        push!(visited, m)
256 30
        state = nothing
257 30
        for s in unsorted_names(m, all = true, imported = true)
258 30
            !isdefined(m, s) && continue
259 30
            x = getfield(m, s)
260 30
            state = f(m, s, x, state)
261 30
            if x isa Module && !in(x, visited)
262 30
                oneverything(f, x, visited)
263
            end
264
        end
265
    else
266 30
        for m in Base.loaded_modules_array()
267 30
            in(m, visited) || oneverything(f, m, visited)
268
        end
269
    end
270
end
271

272
const _global_symbol_cache_by_mod = IdDict{Module,Base.IdSet{Symbol}}()
273
function build_namecache(m, s, @nospecialize(x), state::Union{Base.IdSet{Symbol},Nothing} = nothing)
274 30
    if state === nothing
275 30
        state = get(_global_symbol_cache_by_mod, m, nothing)
276 30
        if state === nothing
277 30
            state = _global_symbol_cache_by_mod[m] = Base.IdSet{Symbol}()
278
        end
279
    end
280 30
    push!(state, s)
281
end
282

283
function getnames(m::Module)
284 30
    cache = get(_global_symbol_cache_by_mod, m, nothing)
285 30
    if cache === nothing
286 30
        oneverything(build_namecache, m)
287 30
        cache = _global_symbol_cache_by_mod[m]
288
    end
289 30
    return cache
290
end
291

292
function allmodulenames()
293 25
    symbols = Base.IdSet{Symbol}()
294 30
    oneverything((m, s, x, state) -> (x isa Module && push!(symbols, s); return state))
295 5
    return symbols
296
end
297

298 0
function allthingswithmethods()
299 0
    symbols = Base.IdSet{Any}()
300 0
    oneverything(function (m, s, x, state)
301 0
        if !Base.isvarargtype(x) && !isempty(methodlist(x))
302 0
            push!(symbols, x)
303
        end
304 0
        return state
305
    end)
306 0
    return symbols
307
end
308

309 0
function allmethods()
310 0
    ms = Method[]
311 0
    oneverything(function (m, s, x, state)
312 0
        if !Base.isvarargtype(x) && !isempty(methodlist(x))
313 0
            append!(ms, methodlist(x))
314
        end
315 0
        return state
316
    end)
317 0
    return ms
318
end
319

320 30
usedby(outer, inner) = outer !== inner && isdefined(outer, nameof(inner)) && getproperty(outer, nameof(inner)) === inner && all(isdefined(outer, name) || !isdefined(inner, name) for name in unsorted_names(inner))
321 30
istoplevelmodule(m) = parentmodule(m) === m || parentmodule(m) === Main
322

323
function getmoduletree(m::Module, amn, visited = Base.IdSet{Module}())
324 30
    push!(visited, m)
325 25
    cache = ModuleStore(m)
326 30
    for s in unsorted_names(m, all = true, imported = true)
327 30
        !isdefined(m, s) && continue
328 30
        x = getfield(m, s)
329 30
        if x isa Module
330 30
            if istoplevelmodule(x)
331 30
                cache[s] = VarRef(x)
332 30
            elseif m === parentmodule(x)
333 30
                cache[s] = getmoduletree(x, amn, visited)
334
            else
335 30
                cache[s] = VarRef(x)
336
            end
337
        end
338
    end
339 30
    for n in amn
340 30
        if n !== nameof(m) && isdefined(m, n)
341 30
            x = getfield(m, n)
342 30
            if x isa Module
343 30
                if !haskey(cache, n)
344 30
                    cache[n] = VarRef(x)
345
                end
346 30
                if x !== Main && usedby(m, x)
347 30
                    push!(cache.used_modules, n)
348
                end
349
            end
350
        end
351
    end
352 30
    cache
353
end
354

355
function getenvtree(names = nothing)
356 30
    amn = allmodulenames()
357 30
    EnvStore(nameof(m) => getmoduletree(m, amn) for m in Base.loaded_modules_array() if names === nothing || nameof(m) in names)
358
end
359

360
# faster and more correct split_module_names
361 30
all_names(m) = all_names(m, x -> isdefined(m, x))
362
function all_names(m, pred, symbols = Set(Symbol[]), seen = Set(Module[]))
363 30
    push!(seen, m)
364 25
    ns = unsorted_names(m; all = true, imported = false)
365 30
    for n in ns
366 30
        isdefined(m, n) || continue
367 30
        Base.isdeprecated(m, n) && continue
368 30
        val = getfield(m, n)
369 30
        if val isa Module && !(val in seen)
370 30
            all_names(val, pred, symbols, seen)
371
        end
372 30
        if pred(n)
373 30
            push!(symbols, n)
374
        end
375
    end
376 30
    symbols
377
end
378

379
function symbols(env::EnvStore, m::Union{Module,Nothing} = nothing, allnames::Base.IdSet{Symbol} = getallns(), visited = Base.IdSet{Module}())
380 30
    if m isa Module
381 30
        cache = _lookup(VarRef(m), env, true)
382 30
        cache === nothing && return
383 25
        push!(visited, m)
384 25
        ns = all_names(m)
385 30
        for s in ns
386 30
            !isdefined(m, s) && continue
387 30
            x = getfield(m, s)
388 30
            if Base.unwrap_unionall(x) isa DataType # Unions aren't handled here.
389 30
                if parentmodule((x)) === m
390 30
                    cache[s] = DataTypeStore(x, m, s in getnames(m))
391 30
                    cache_methods(x, s, env)
392 30
                elseif nameof(x) !== s
393
                    # This needs some finessing.
394 30
                    cache[s] = DataTypeStore(x, m, s in getnames(m))
395 30
                    cache_methods(x, s, env)
396
                else
397
                    # These are imported variables that are reexported.
398 30
                    cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
399
                end
400 30
            elseif x isa Function
401 30
                if parentmodule(x) === m || (x isa Core.IntrinsicFunction && m === Core.Intrinsics)
402 30
                    cache[s] = FunctionStore(x, m, s in getnames(m))
403 30
                    cache_methods(x, s, env)
404 30
                elseif !haskey(cache, s)
405
                    # This will be replaced at a later point by a FunctionStore if methods for `x` are defined within `m`.
406 30
                    if x isa Core.IntrinsicFunction
407 30
                        cache[s] = VarRef(VarRef(Core.Intrinsics), nameof(x))
408
                    else
409 30
                        cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
410
                    end
411
                else
412
                    # These are imported variables that are reexported.
413 30
                    if x isa Core.IntrinsicFunction
414 0
                        cache[s] = VarRef(VarRef(Core.Intrinsics), nameof(x))
415
                    else
416 30
                        cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
417
                    end
418
                end
419 30
            elseif x isa Module
420 30
                if x === m
421 30
                    cache[s] = VarRef(x)
422 30
                elseif parentmodule(x) === m
423 30
                    symbols(env, x, allnames, visited)
424
                else
425 30
                    cache[s] = VarRef(x)
426
                end
427
            else
428 30
                cache[s] = GenericStore(VarRef(VarRef(m), s), FakeTypeName(typeof(x)), _doc(x), s in getnames(m))
429
            end
430
        end
431
    else
432 30
        for m in Base.loaded_modules_array()
433 30
            in(m, visited) || symbols(env, m, allnames, visited)
434
        end
435
    end
436
end
437

438

439
function load_core()
440 25
    c = Pkg.Types.Context()
441 25
    cache = getenvtree([:Core,:Base])
442 25
    symbols(cache)
443 25
    cache[:Main] = ModuleStore(VarRef(nothing, :Main), Dict(), "", true, [], [])
444

445
    # This is wrong. As per the docs the Base.include each module should have it's own
446
    # version.
447 25
    push!(cache[:Base].exportednames, :include)
448

449
    # Add special cases for built-ins
450 25
    let f = cache[:Base][:include]
451 25
        cache[:Base][:include] = FunctionStore(f.name, cache[:Base][:MainInclude][:include].methods, f.doc, f.extends, true)
452
    end
453

454 25
    cache[:Base][Symbol("@.")] = cache[:Base][Symbol("@__dot__")]
455 25
    cache[:Core][:Main] = GenericStore(VarRef(nothing, :Main), FakeTypeName(Module), _doc(Main), true)
456
    # Add built-ins
457 25
    builtins = Symbol[nameof(getfield(Core, n).instance) for n in unsorted_names(Core, all = true) if isdefined(Core, n) && getfield(Core, n) isa DataType && isdefined(getfield(Core, n), :instance) && getfield(Core, n).instance isa Core.Builtin]
458 25
    cnames = unsorted_names(Core)
459 25
    for f in builtins
460 25
        if !haskey(cache[:Core], f)
461 25
            cache[:Core][f] = FunctionStore(getfield(Core, Symbol(f)), Core, Symbol(f) in cnames)
462
        end
463
    end
464 25
    haskey(cache[:Core], :_typevar) && push!(cache[:Core][:_typevar].methods, MethodStore(:_typevar, :Core, "built-in", 0, [:n => FakeTypeName(Symbol), :lb => FakeTypeName(Any), :ub => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
465 25
    push!(cache[:Core][:_apply].methods, MethodStore(:_apply, :Core, "built-in", 0, [:f => FakeTypeName(Function), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
466 25
    haskey(cache[:Core].vals, :_apply_iterate) && push!(cache[:Core][:_apply_iterate].methods, MethodStore(:_apply_iterate, :Core, "built-in", 0, [:f => FakeTypeName(Function), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
467 25
    push!(cache[:Core][:_apply_latest].methods, MethodStore(:_apply_latest, :Core, "built-in", 0, [:f => FakeTypeName(Function), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
468 25
    push!(cache[:Core][:_apply_pure].methods, MethodStore(:_apply_pure, :Core, "built-in", 0, [:f => FakeTypeName(Function), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
469 25
    push!(cache[:Core][:_expr].methods, MethodStore(:_expr, :Core, "built-in", 0, [:head => FakeTypeName(Symbol), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Expr)))
470 25
    haskey(cache[:Core].vals, :_typevar) && push!(cache[:Core][:_typevar].methods, MethodStore(:_typevar, :Core, "built-in", 0, [:name => FakeTypeName(Symbol), :lb => FakeTypeName(Any), :ub => FakeTypeName(Any)], Symbol[], FakeTypeName(TypeVar)))
471 25
    push!(cache[:Core][:applicable].methods, MethodStore(:applicable, :Core, "built-in", 0, [:f => FakeTypeName(Function), :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Bool)))
472 25
    push!(cache[:Core][:apply_type].methods, MethodStore(:apply_type, :Core, "built-in", 0, [:T => FakeTypeName(UnionAll), :types => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(UnionAll)))
473 25
    push!(cache[:Core][:arrayref].methods, MethodStore(:arrayref, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any), :c => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
474 25
    push!(cache[:Core][:arrayset].methods, MethodStore(:arrayset, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any), :c => FakeTypeName(Any), :d => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
475 25
    push!(cache[:Core][:arraysize].methods, MethodStore(:arraysize, :Core, "built-in", 0, [:a => FakeTypeName(Array), :i => FakeTypeName(Int)], Symbol[], FakeTypeName(Int)))
476 25
    haskey(cache[:Core], :const_arrayref) && push!(cache[:Core][:const_arrayref].methods, MethodStore(:const_arrayref, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
477 25
    push!(cache[:Core][:fieldtype].methods, MethodStore(:fieldtype, :Core, "built-in", 0, [:t => FakeTypeName(DataType), :field => FakeTypeName(Symbol)], Symbol[], FakeTypeName(Type{T} where T)))
478 25
    push!(cache[:Core][:getfield].methods, MethodStore(:setfield, :Core, "built-in", 0, [:object => FakeTypeName(Any), :item => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
479 25
    push!(cache[:Core][:ifelse].methods, MethodStore(:ifelse, :Core, "built-in", 0, [:condition => FakeTypeName(Bool), :x => FakeTypeName(Any), :y => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
480 25
    push!(cache[:Core][:invoke].methods, MethodStore(:invoke, :Core, "built-in", 0, [:f => FakeTypeName(Function), :x => FakeTypeName(Any), :argtypes => FakeTypeName(Type{T} where T) , :args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
481 25
    push!(cache[:Core][:isa].methods, MethodStore(:isa, :Core, "built-in", 0, [:a => FakeTypeName(Any), :T => FakeTypeName(Type{T} where T)], Symbol[], FakeTypeName(Bool)))
482 25
    push!(cache[:Core][:isdefined].methods, MethodStore(:getproperty, :Core, "built-in", 0, [:value => FakeTypeName(Any), :field => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
483 25
    push!(cache[:Core][:nfields].methods, MethodStore(:nfields, :Core, "built-in", 0, [:x => FakeTypeName(Any)], Symbol[], FakeTypeName(Int)))
484 25
    push!(cache[:Core][:setfield!].methods, MethodStore(:setfield!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
485 25
    push!(cache[:Core][:sizeof].methods, MethodStore(:sizeof, :Core, "built-in", 0, [:obj => FakeTypeName(Any)], Symbol[], FakeTypeName(Int)))
486 25
    push!(cache[:Core][:svec].methods, MethodStore(:svec, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
487 25
    push!(cache[:Core][:throw].methods, MethodStore(:throw, :Core, "built-in", 0, [:e => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
488 25
    push!(cache[:Core][:tuple].methods, MethodStore(:tuple, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
489 25
    push!(cache[:Core][:typeassert].methods, MethodStore(:typeassert, :Core, "built-in", 0, [:x => FakeTypeName(Any), :T => FakeTypeName(Type{T} where T)], Symbol[], FakeTypeName(Any)))
490 25
    push!(cache[:Core][:typeof].methods, MethodStore(:typeof, :Core, "built-in", 0, [:x => FakeTypeName(Any)], Symbol[], FakeTypeName(Type{T} where T)))
491

492 25
    push!(cache[:Core][:getproperty].methods, MethodStore(:getproperty, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol)], Symbol[], FakeTypeName(Any)))
493 25
    push!(cache[:Core][:setproperty!].methods, MethodStore(:setproperty!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
494 25
    push!(cache[:Core][:setproperty!].methods, MethodStore(:setproperty!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
495 25
    haskey(cache[:Core], :_abstracttype) && push!(cache[:Core][:_abstracttype].methods, MethodStore(:_abstracttype, :Core, "built-in", 0, [:m => FakeTypeName(Module), :x => FakeTypeName(Symbol), :p => FakeTypeName(Core.SimpleVector)], Symbol[], FakeTypeName(Any)))
496 25
    haskey(cache[:Core], :_primitivetype) && push!(cache[:Core][:_primitivetype].methods, MethodStore(:_primitivetype, :Core, "built-in", 0, [:m => FakeTypeName(Module), :x => FakeTypeName(Symbol), :p => FakeTypeName(Core.SimpleVector), :n => FakeTypeName(Core.Int)], Symbol[], FakeTypeName(Any)))
497 25
    haskey(cache[:Core], :_equiv_typedef) && push!(cache[:Core][:_equiv_typedef].methods, MethodStore(:_equiv_typedef, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
498 25
    haskey(cache[:Core], :_setsuper!) && push!(cache[:Core][:_setsuper!].methods, MethodStore(:_setsuper!, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
499 25
    haskey(cache[:Core], :_structtype) && push!(cache[:Core][:_structtype].methods, MethodStore(:_structtype, :Core, "built-in", 0, [:m => FakeTypeName(Module), :x => FakeTypeName(Symbol), :p => FakeTypeName(Core.SimpleVector), :fields => FakeTypeName(Core.SimpleVector), :mut => FakeTypeName(Bool), :z => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
500 25
    haskey(cache[:Core], :_typebody) && push!(cache[:Core][:_typebody!].methods, MethodStore(:_typebody!, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
501 25
    push!(cache[:Core][:(===)].methods, MethodStore(:(===), :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
502 25
    push!(cache[:Core][:(<:)].methods, MethodStore(:(<:), :Core, "built-in", 0, [:a => FakeTypeName(Type{T} where T), :b => FakeTypeName(Type{T} where T)], Symbol[], FakeTypeName(Any)))
503

504 25
    for bi in builtins
505 25
        if haskey(cache[:Core], bi) && isempty(cache[:Core][bi].methods)
506
            # Add at least one arbitrary method for anything left over
507 25
            push!(cache[:Core][bi].methods, MethodStore(bi, :none, "built-in", 0, [:x => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
508
        end
509
    end
510

511 25
    cache[:Core][:ccall] = FunctionStore(VarRef(VarRef(Core), :ccall),
512
        MethodStore[
513
            MethodStore(:ccall, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)) # General method - should be fixed
514
        ],
515
        "`ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)`\n`ccall(function_name, returntype, (argtype1, ...), argvalue1, ...)`\n`ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)`\n\nCall a function in a C-exported shared library, specified by the tuple (`function_name`, `library`), where each component is either a string or symbol. Instead of specifying a library, one\ncan also use a `function_name` symbol or string, which is resolved in the current process. Alternatively, `ccall` may also be used to call a function pointer `function_pointer`, such as one\nreturned by `dlsym`.\n\nNote that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.\n\nEach `argvalue` to the `ccall` will be converted to the corresponding `argtype`, by automatic insertion of calls to `unsafe_convert(argtype, cconvert(argtype, argvalue))`. (See also the documentation for `unsafe_convert` and `cconvert` for further details.) In most cases, this simply results in a call to `convert(argtype, argvalue)`.",
516
        VarRef(VarRef(Core), :ccall),
517
        true)
518 25
    push!(cache[:Core].exportednames, :ccall)
519 25
    cache[:Core][Symbol("@__doc__")] = FunctionStore(VarRef(VarRef(Core), Symbol("@__doc__")), [], "", VarRef(VarRef(Core), Symbol("@__doc__")), true)
520 25
    cache_methods(getfield(Core, Symbol("@__doc__")), Symbol("@__doc__"), cache)
521
    # Accounts for the dd situation where Base.rand only has methods from Random which doesn't appear to be explicitly used.
522
    # append!(cache[:Base][:rand].methods, cache_methods(Base.rand, cache))
523 25
    for m in cache_methods(Base.rand, :rand, cache)
524 25
        push!(cache[:Base][:rand].methods, m[2])
525
    end
526

527
    # Intrinsics
528 25
    cache[:Core][:add_int] = VarRef(VarRef(VarRef(nothing, :Core), :Intrinsics), :add_int)
529 25
    cache[:Core][:sle_int] = VarRef(VarRef(VarRef(nothing, :Core), :Intrinsics), :sle_int)
530 25
    return cache
531
end
532

533

534 0
function collect_extended_methods(depot::EnvStore, extendeds = Dict{VarRef,Vector{VarRef}}())
535 0
    for m in depot
536 0
        collect_extended_methods(m[2], extendeds, m[2].name)
537
    end
538 0
    extendeds
539
end
540

541 0
function collect_extended_methods(mod::ModuleStore, extendeds, mname)
542 0
    for (n, v) in mod.vals
543 0
        if (v isa FunctionStore) && v.extends != v.name
544 0
            haskey(extendeds, v.extends) ? push!(extendeds[v.extends], mname) : (extendeds[v.extends] = VarRef[v.extends.parent, mname])
545 0
        elseif v isa ModuleStore
546 0
            collect_extended_methods(v, extendeds, v.name)
547
        end
548
    end
549
end
550

551 30
getallns() = let allns = Base.IdSet{Symbol}(); SymbolServer.oneverything((m, s, x, state) -> push!(allns, s)); allns end
552

553
"""
554
    split_module_names(m::Module, allns)
555

556
Return two lists of names accessible from calling getfield(m, somename)`. The first
557
contains those symbols returned by `Base.names(m, all = true)`. The second contains
558
all others, including imported symbols and those introduced by the `using` of modules.
559
"""
560 0
function split_module_names(m::Module, allns)
561 0
    internal_names = getnames(m)
562 0
    availablenames = Set{Symbol}([s for s in allns if isdefined(m, s)])
563
    # usinged_names = Set{Symbol}()
564

565 0
    for n in availablenames
566 0
        if (n in internal_names)
567 0
            pop!(availablenames, n)
568
        end
569
    end
570 0
    allms = get_all_modules()
571 0
    for u in get_used_modules(m, allms)
572 0
        for n in unsorted_names(u)
573 0
            if n in availablenames
574 0
                pop!(availablenames, n)
575
                # push!(usinged_names, pop!(availablenames, n))
576
            end
577
        end
578
    end
579 0
    internal_names, availablenames
580
end
581

582 0
get_all_modules() = let allms = Base.IdSet{Module}(); apply_to_everything(x -> if x isa Module push!(allms, x) end); allms end
583 0
get_used_modules(M, allms = get_all_modules()) = [m for m in allms if usedby(M, m)]

Read our documentation on viewing source code .

Loading