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
function apply_to_everything(f, m=nothing, visited=Base.IdSet{Module}())
234 30
    if m isa Module
235 25
        push!(visited, m)
236 30
        for s in unsorted_names(m, all=true, imported=true)
237 30
            (!isdefined(m, s) || s == nameof(m)) && continue
238 30
            x = getfield(m, s)
239 25
            f(x)
240 30
            if x isa Module && !in(x, visited)
241 30
                apply_to_everything(f, x, visited)
242
            end
243
        end
244
    else
245 30
        for m in Base.loaded_modules_array()
246 30
            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)
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
function symbols(env::EnvStore, m::Union{Module,Nothing}=nothing, allnames::Base.IdSet{Symbol}=getallns(), visited=Base.IdSet{Module}())
361 30
    if m isa Module
362 30
        cache = _lookup(VarRef(m), env, true)
363 30
        cache === nothing && return
364 25
        push!(visited, m)
365 30
        internalnames, othernames = split_module_names(m, allnames)
366 30
        for s in internalnames
367 30
            !isdefined(m, s) && continue
368 30
            x = getfield(m, s)
369 30
            if Base.unwrap_unionall(x) isa DataType # Unions aren't handled here.
370 30
                if parentmodule((x)) === m
371 30
                    cache[s] = DataTypeStore(x, m, s in getnames(m))
372 30
                    cache_methods(x, s, env)
373 30
                elseif nameof(x) !== s
374
                    # This needs some finessing.
375 30
                    cache[s] = DataTypeStore(x, m, s in getnames(m))
376 30
                    cache_methods(x, s, env)
377
                else
378
                    # These are imported variables that are reexported.
379 30
                    cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
380
                end
381 30
            elseif x isa Function
382 30
                if parentmodule(x) === m || (x isa Core.IntrinsicFunction && m === Core.Intrinsics)
383 30
                    cache[s] = FunctionStore(x, m, s in getnames(m))
384 30
                    cache_methods(x, s, env)
385 30
                elseif !haskey(cache, s)
386
                    # This will be replaced at a later point by a FunctionStore if methods for `x` are defined within `m`.
387 30
                    if x isa Core.IntrinsicFunction
388 30
                        cache[s] = VarRef(VarRef(Core.Intrinsics), nameof(x))
389
                    else
390 30
                        cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
391
                    end
392
                else
393
                    # These are imported variables that are reexported.
394 30
                    if x isa Core.IntrinsicFunction
395 0
                        cache[s] = VarRef(VarRef(Core.Intrinsics), nameof(x))
396
                    else
397 30
                        cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
398
                    end
399
                end
400 30
            elseif x isa Module
401 30
                if x === m
402 30
                    cache[s] = VarRef(x)
403 30
                elseif parentmodule(x) === m
404 30
                    symbols(env, x, allnames, visited)
405
                else
406 30
                    cache[s] = VarRef(x)
407
                end
408
            else
409 30
                cache[s] = GenericStore(VarRef(VarRef(m), s), FakeTypeName(typeof(x)), _doc(x), s in getnames(m))
410
            end
411
        end
412 30
        for s in othernames
413 30
            x = getfield(m, s)
414 30
            if x isa Function
415 30
                if x isa Core.IntrinsicFunction
416 30
                    cache[s] = VarRef(VarRef(Core.Intrinsics), nameof(x))
417
                else
418 30
                    cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
419
                end
420 30
            elseif x isa DataType
421 30
                cache[s] = VarRef(VarRef(parentmodule(x)), nameof(x))
422 30
            elseif x isa Module
423 30
                cache[s] = VarRef(x)
424
            else
425
                # We'd like to have these as VarRef's but we don't know where they live.
426 30
                cache[s] = GenericStore(VarRef(VarRef(m), s), FakeTypeName(typeof(x)), _doc(x), s in getnames(m))
427
            end
428
        end
429
    else
430 30
        for m in Base.loaded_modules_array()
431 30
            in(m, visited) || symbols(env, m, allnames, visited)
432
        end
433
    end
434
end
435

436

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

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

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

452 25
    cache[:Base][Symbol("@.")] = cache[:Base][Symbol("@__dot__")]
453 25
    cache[:Core][:Main] = GenericStore(VarRef(nothing, :Main), FakeTypeName(Module), _doc(Main), true)
454
    # Add built-ins
455 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]
456 25
    cnames = unsorted_names(Core)
457 25
    for f in builtins
458 25
        if !haskey(cache[:Core], f)
459 25
            cache[:Core][f] = FunctionStore(getfield(Core, Symbol(f)), Core, Symbol(f) in cnames)
460
        end
461
    end
462 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)))
463 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)))
464 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)))
465 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)))
466 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)))
467 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)))
468 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)))
469 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)))
470 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)))
471 25
    push!(cache[:Core][:arrayref].methods, MethodStore(:arrayref, :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any), :c => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
472 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)))
473 25
    push!(cache[:Core][:arraysize].methods, MethodStore(:arraysize, :Core, "built-in", 0, [:a => FakeTypeName(Array), :i => FakeTypeName(Int)], Symbol[], FakeTypeName(Int)))
474 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)))
475 25
    push!(cache[:Core][:fieldtype].methods, MethodStore(:fieldtype, :Core, "built-in", 0, [:t => FakeTypeName(DataType), :field => FakeTypeName(Symbol)], Symbol[], FakeTypeName(Type{T} where T)))
476 25
    push!(cache[:Core][:getfield].methods, MethodStore(:setfield, :Core, "built-in", 0, [:object => FakeTypeName(Any), :item => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
477 25
    push!(cache[:Core][:ifelse].methods, MethodStore(:ifelse, :Core, "built-in", 0, [:condition => FakeTypeName(Bool), :x => FakeTypeName(Any), :y => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
478 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)))
479 25
    push!(cache[:Core][:isa].methods, MethodStore(:isa, :Core, "built-in", 0, [:a => FakeTypeName(Any), :T => FakeTypeName(Type{T} where T)], Symbol[], FakeTypeName(Bool)))
480 25
    push!(cache[:Core][:isdefined].methods, MethodStore(:getproperty, :Core, "built-in", 0, [:value => FakeTypeName(Any), :field => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
481 25
    push!(cache[:Core][:nfields].methods, MethodStore(:nfields, :Core, "built-in", 0, [:x => FakeTypeName(Any)], Symbol[], FakeTypeName(Int)))
482 25
    push!(cache[:Core][:setfield!].methods, MethodStore(:setfield!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
483 25
    push!(cache[:Core][:sizeof].methods, MethodStore(:sizeof, :Core, "built-in", 0, [:obj => FakeTypeName(Any)], Symbol[], FakeTypeName(Int)))
484 25
    push!(cache[:Core][:svec].methods, MethodStore(:svec, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
485 25
    push!(cache[:Core][:throw].methods, MethodStore(:throw, :Core, "built-in", 0, [:e => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
486 25
    push!(cache[:Core][:tuple].methods, MethodStore(:tuple, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)))
487 25
    push!(cache[:Core][:typeassert].methods, MethodStore(:typeassert, :Core, "built-in", 0, [:x => FakeTypeName(Any), :T => FakeTypeName(Type{T} where T)], Symbol[], FakeTypeName(Any)))
488 25
    push!(cache[:Core][:typeof].methods, MethodStore(:typeof, :Core, "built-in", 0, [:x => FakeTypeName(Any)], Symbol[], FakeTypeName(Type{T} where T)))
489

490 25
    push!(cache[:Core][:getproperty].methods, MethodStore(:getproperty, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol)], Symbol[], FakeTypeName(Any)))
491 25
    push!(cache[:Core][:setproperty!].methods, MethodStore(:setproperty!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
492 25
    push!(cache[:Core][:setproperty!].methods, MethodStore(:setproperty!, :Core, "built-in", 0, [:value => FakeTypeName(Any), :name => FakeTypeName(Symbol), :x => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
493 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)))
494 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)))
495 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)))
496 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)))
497 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)))
498 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)))
499 25
    push!(cache[:Core][:(===)].methods, MethodStore(:(===), :Core, "built-in", 0, [:a => FakeTypeName(Any), :b => FakeTypeName(Any)], Symbol[], FakeTypeName(Any)))
500 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)))
501

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

509 25
    cache[:Core][:ccall] = FunctionStore(VarRef(VarRef(Core), :ccall),
510
        MethodStore[
511
            MethodStore(:ccall, :Core, "built-in", 0, [:args => FakeTypeName(Vararg{Any,N} where N)], Symbol[], FakeTypeName(Any)) # General method - should be fixed
512
        ],
513
        "`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)`.",
514
        VarRef(VarRef(Core), :ccall),
515
        true)
516 25
    push!(cache[:Core].exportednames, :ccall)
517 25
    cache[:Core][Symbol("@__doc__")] = FunctionStore(VarRef(VarRef(Core), Symbol("@__doc__")), [], "", VarRef(VarRef(Core), Symbol("@__doc__")), true)
518 25
    cache_methods(getfield(Core, Symbol("@__doc__")), Symbol("@__doc__"), cache)
519
    # Accounts for the dd situation where Base.rand only has methods from Random which doesn't appear to be explicitly used.
520
    # append!(cache[:Base][:rand].methods, cache_methods(Base.rand, cache))
521 25
    for m in cache_methods(Base.rand, :rand, cache)
522 25
        push!(cache[:Base][:rand].methods, m[2])
523
    end
524

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

531

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

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

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

551
"""
552
    split_module_names(m::Module, allns)
553

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

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

580 30
get_all_modules() = let allms = Base.IdSet{Module}(); apply_to_everything(x -> if x isa Module push!(allms, x) end); allms end
581 30
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