julia-vscode / SymbolServer.jl
1
########## Fake type-system
2

3

4
# Used to label all objects
5
struct VarRef
6 70
    parent::Union{VarRef,Nothing}
7
    name::Symbol
8
end
9 70
VarRef(m::Module) = VarRef((parentmodule(m) == Main || parentmodule(m) == m) ? nothing : VarRef(parentmodule(m)), nameof(m))
10

11
# These mirror Julia types (w/o the Fake prefix)
12
struct FakeTypeName
13 70
    name::VarRef
14
    parameters::Vector{Any}
15
end
16

17 20
function FakeTypeName(@nospecialize(x); justname=false)
18 70
    @static if !(Vararg isa Type)
19
        x isa typeof(Vararg) && return FakeTypeofVararg(x)
20
    end
21 70
    if x isa DataType
22 20
        xname = x.name
23 20
        xnamename = xname.name # necessary but unclear why.
24 70
        if justname
25 70
            FakeTypeName(VarRef(VarRef(x.name.module), x.name.name), [])
26
        else
27
            # FakeTypeName(VarRef(VarRef(x.name.module), x.name.name), _parameter.(x.parameters))
28 70
            ft = FakeTypeName(VarRef(VarRef(x.name.module), x.name.name), [])
29 70
            for p in x.parameters
30 70
                push!(ft.parameters, _parameter(p))
31
            end
32 70
            ft
33
        end
34 70
    elseif x isa Union
35 70
        FakeUnion(x)
36 70
    elseif x isa UnionAll
37 70
        FakeUnionAll(x)
38 70
    elseif x isa TypeVar
39 70
        FakeTypeVar(x)
40 70
    elseif x isa Core.TypeofBottom
41 70
        FakeTypeofBottom()
42
    else
43 0
        error((x, typeof(x)))
44
    end
45
end
46

47 70
struct FakeTypeofBottom end
48
struct FakeUnion
49 70
    a
50
    b
51
end
52 70
FakeUnion(u::Union) = FakeUnion(FakeTypeName(u.a, justname=true), FakeTypeName(u.b, justname=true))
53
struct FakeTypeVar
54 70
    name::Symbol
55
    lb
56
    ub
57
end
58 70
FakeTypeVar(tv::TypeVar) = FakeTypeVar(tv.name, FakeTypeName(tv.lb, justname=true), FakeTypeName(tv.ub, justname=true))
59
struct FakeUnionAll
60 70
    var::FakeTypeVar
61
    body::Any
62
end
63 70
FakeUnionAll(ua::UnionAll) = FakeUnionAll(FakeTypeVar(ua.var), FakeTypeName(ua.body, justname=true))
64

65 20
function _parameter(@nospecialize(p))
66 70
    if p isa Union{Int,Symbol,Bool,Char}
67 70
        p
68 70
    elseif !(p isa Type) && isbitstype(typeof(p))
69 70
        0
70 70
    elseif p isa Tuple
71 0
        _parameter.(p)
72
    else
73 70
        FakeTypeName(p, justname=true)
74
    end
75
end
76

77 70
Base.print(io::IO, vr::VarRef) = vr.parent === nothing ? print(io, vr.name) : print(io, vr.parent, ".", vr.name)
78 20
function Base.print(io::IO, tn::FakeTypeName)
79 70
    print(io, tn.name)
80 70
    if !isempty(tn.parameters)
81 60
        print(io, "{")
82 70
        for i = 1:length(tn.parameters)
83 70
            print(io, tn.parameters[i])
84 70
            i != length(tn.parameters) && print(io, ",")
85
        end
86 70
        print(io, "}")
87
    end
88
end
89 70
Base.print(io::IO, x::FakeUnionAll) = print(io, x.body, " where ", x.var)
90 0
function Base.print(io::IO, x::FakeUnion; inunion=false)
91 0
    !inunion && print(io,  "Union{")
92 0
    print(io, x.a, ",")
93 0
    if x.b isa FakeUnion
94 0
        print(io, x.b, inunion=true)
95
    else
96 0
        print(io, x.b, "}")
97
    end
98
end
99 20
function Base.print(io::IO, x::FakeTypeVar)
100 70
    if isfakebottom(x.lb)
101 70
        if isfakeany(x.ub)
102 70
            print(io, x.name)
103
        else
104 0
            print(io, x.name, "<:", x.ub)
105
        end
106 0
    elseif isfakeany(x.ub)
107 0
        print(io, x.lb, "<:", x.name)
108
    else
109 0
        print(io, x.lb, "<:", x.name, "<:", x.ub)
110
    end
111
end
112

113 0
isfakeany(t) = false
114 70
isfakeany(t::FakeTypeName) = isfakeany(t.name)
115 70
isfakeany(vr::VarRef) = vr.name === :Any && vr.parent isa VarRef && vr.parent.name === :Core && vr.parent.parent === nothing
116

117 0
isfakebottom(t) = false
118 20
isfakebottom(t::FakeTypeofBottom) = true
119

120 70
Base.:(==)(a::FakeTypeName, b::FakeTypeName) = a.name == b.name && a.parameters == b.parameters
121 70
Base.:(==)(a::VarRef, b::VarRef) = a.parent == b.parent && a.name == b.name
122 70
Base.:(==)(a::FakeTypeVar, b::FakeTypeVar) = a.lb == b.lb && a.name == b.name && a.ub == b.ub
123 70
Base.:(==)(a::FakeUnionAll, b::FakeUnionAll) = a.var == b.var && a.body == b.body
124 0
Base.:(==)(a::FakeUnion, b::FakeUnion) = a.a == b.a && a.b == b.b
125 70
Base.:(==)(a::FakeTypeofBottom, b::FakeTypeofBottom) = true
126

127
@static if !(Vararg isa Type)
128
    struct FakeTypeofVararg
129
        T
130
        N
131 0
        FakeTypeofVararg() = new()
132 0
        FakeTypeofVararg(T) = (new(T))
133 0
        FakeTypeofVararg(T, N) = new(T, N)
134
    end
135 0
    function FakeTypeofVararg(va::typeof(Vararg))
136 0
        if isdefined(va, :N)
137 0
            vaN = va.N isa TypeVar ? FakeTypeVar(va.N) : va.N
138 0
            FakeTypeofVararg(FakeTypeName(va.T; justname=true), vaN) # This should be FakeTypeName(va.N) but seems to crash inference.
139 0
        elseif isdefined(va, :T)
140 0
            FakeTypeofVararg(FakeTypeName(va.T; justname=true))
141
        else
142 0
            FakeTypeofVararg()
143
        end
144
    end
145 0
    function Base.print(io::IO, va::FakeTypeofVararg)
146 0
        print(io, "Vararg")
147 0
        if isdefined(va, :T)
148 0
            print(io, "{", va.T)
149 0
            if isdefined(va, :N)
150 0
                print(io, ",", va.N)
151
            end
152 0
            print(io, "}")
153
        end
154
    end
155 0
    function Base.:(==)(a::FakeTypeofVararg, b::FakeTypeofVararg)
156 0
        if isdefined(a, :T)
157 0
            if isdefined(b, :T) && a.T == b.T
158 0
                if isdefined(a, :N)
159 0
                    isdefined(b, :N) && a.N == b.N
160
                else
161 0
                    !isdefined(b, :N)
162
                end
163
            else
164 0
                false
165
            end
166
        else
167 0
            !isdefined(b, :T)
168
        end
169
    end
170
end

Read our documentation on viewing source code .

Loading