@@ -58,24 +58,61 @@ function argument_types(sig)
58
58
return parameters (sig)[2 : end ]
59
59
end
60
60
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
62
87
name_of_type (tv:: TypeVar ) = tv. name
63
88
function 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
67
94
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... )})
70
97
end
71
98
end
99
+
100
+
72
101
function 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... )})
76
112
end
113
+
77
114
function name_of_type (x:: Union )
78
- parameter_names = name_of_type .( Base. uniontypes (x))
115
+ parameter_names = map (name_of_type, Base. uniontypes (x))
79
116
return :(Union{$ (parameter_names... )})
80
117
end
81
118
@@ -95,7 +132,7 @@ function arguments(m::Method)
95
132
end
96
133
end
97
134
98
- function where_parameters (x:: TypeVar )
135
+ function where_constraint (x:: TypeVar )
99
136
if x. lb === Union{} && x. ub === Any
100
137
return x. name
101
138
elseif x. lb === Union{}
@@ -112,7 +149,7 @@ where_parameters(sig) = nothing
112
149
function where_parameters (sig:: UnionAll )
113
150
whereparams = []
114
151
while sig isa UnionAll
115
- push! (whereparams, where_parameters (sig. var))
152
+ push! (whereparams, where_constraint (sig. var))
116
153
sig = sig. body
117
154
end
118
155
return whereparams
@@ -125,7 +162,7 @@ function type_parameters(sig)
125
162
126
163
function_type = first (parameters (typeof_type)) # will be e.g. Foo{P}
127
164
parameter_types = parameters (function_type)
128
- return [ name_of_type (type) for type in parameter_types]
165
+ return map (name_of_type, parameter_types)
129
166
end
130
167
131
168
function kwargs (m:: Method )
0 commit comments