@@ -58,24 +58,61 @@ function argument_types(sig)
5858 return parameters (sig)[2 : end ]
5959end
6060
61- name_of_type (x) = x
61+ module DummyThatHasOnlyDefaultImports end # for working out visibility
62+
63+ function name_of_module (m:: Module )
64+ if Base. is_root_module (m)
65+ return nameof (m)
66+ else
67+ return :($ (name_of_module (parentmodule (m))). $ (nameof (m)))
68+ end
69+ end
70+ function name_of_type (x:: Core.TypeName )
71+ # TODO : could let user pass this in, then we could be using what is inscope for them
72+ # but this is not important as we will give a correct (if overly verbose) output as is.
73+ from = DummyThatHasOnlyDefaultImports
74+ if Base. isvisible (x. name, x. module, from) # avoid qualifying things that are in scope
75+ return x. name
76+ else
77+ return :($ (name_of_module (x. module)). $ (x. name))
78+ end
79+ end
80+
81+ name_of_type (x:: Symbol ) = QuoteNode (x) # Literal type-param e.g. `Val{:foo}`
82+ function name_of_type (x:: T ) where T # Literal type-param e.g. `Val{1}`
83+ # If this error is thrown, there is an issue with out implementation
84+ isbits (x) || throw (DomainError ((x, T), " not a valid type-param" ))
85+ return x
86+ end
6287name_of_type (tv:: TypeVar ) = tv. name
6388function name_of_type (x:: DataType )
64- name_sym = Symbol (x. name)
65- if isempty (x. parameters)
66- return name_sym
89+ name = name_of_type (x. name)
90+ # because tuples are varadic in number of type parameters having no parameters does not
91+ # mean you should not write the `{}`, so we special case them here.
92+ if isempty (x. parameters) && x != Tuple{}
93+ return name
6794 else
68- parameter_names = name_of_type .( x. parameters)
69- return :($ (name_sym ){$ (parameter_names... )})
95+ parameter_names = map (name_of_type, x. parameters)
96+ return :($ (name ){$ (parameter_names... )})
7097 end
7198end
99+
100+
72101function name_of_type (x:: UnionAll )
73- name = name_of_type (x. body)
74- whereparam = where_parameters (x. var)
75- return :($ name where $ whereparam)
102+ # we do nested union all unwrapping so we can make the more compact:
103+ # `foo{T,A} where {T, A}`` rather than the longer: `(foo{T,A} where T) where A`
104+ where_params = []
105+ while x isa UnionAll
106+ push! (where_params, where_constraint (x. var))
107+ x = x. body
108+ end
109+
110+ name = name_of_type (x)
111+ return :($ name where {$ (where_params... )})
76112end
113+
77114function name_of_type (x:: Union )
78- parameter_names = name_of_type .( Base. uniontypes (x))
115+ parameter_names = map (name_of_type, Base. uniontypes (x))
79116 return :(Union{$ (parameter_names... )})
80117end
81118
@@ -95,7 +132,7 @@ function arguments(m::Method)
95132 end
96133end
97134
98- function where_parameters (x:: TypeVar )
135+ function where_constraint (x:: TypeVar )
99136 if x. lb === Union{} && x. ub === Any
100137 return x. name
101138 elseif x. lb === Union{}
@@ -112,7 +149,7 @@ where_parameters(sig) = nothing
112149function where_parameters (sig:: UnionAll )
113150 whereparams = []
114151 while sig isa UnionAll
115- push! (whereparams, where_parameters (sig. var))
152+ push! (whereparams, where_constraint (sig. var))
116153 sig = sig. body
117154 end
118155 return whereparams
@@ -125,7 +162,7 @@ function type_parameters(sig)
125162
126163 function_type = first (parameters (typeof_type)) # will be e.g. Foo{P}
127164 parameter_types = parameters (function_type)
128- return [ name_of_type (type) for type in parameter_types]
165+ return map (name_of_type, parameter_types)
129166end
130167
131168function kwargs (m:: Method )
0 commit comments