@@ -175,6 +175,45 @@ function parsedocs(mod::Module)
175
175
end
176
176
end
177
177
178
+ """
179
+ $(:SIGNATURES )
180
+
181
+ Decides whether a length of method is too big to be visually appealing.
182
+ """
183
+ method_length_over_limit (len:: Int ) = len > 60
184
+
185
+ function printmethod_format (buffer:: IOBuffer , binding:: String , args:: Vector{String} , kws:: Vector{String} ; return_type = " " )
186
+
187
+ sep_delim = " "
188
+ paren_delim = " "
189
+ indent = " "
190
+
191
+ if method_length_over_limit (
192
+ length (binding) +
193
+ 1 +
194
+ sum (length .(args)) +
195
+ sum (length .(kws)) +
196
+ 2 * max (0 , length (args)- 1 ) +
197
+ 2 * length (kws) +
198
+ 1 +
199
+ length (return_type))
200
+
201
+ sep_delim = " \n "
202
+ paren_delim = " \n "
203
+ indent = " "
204
+ end
205
+
206
+ print (buffer, binding)
207
+ print (buffer, " ($paren_delim " )
208
+ join (buffer, Ref (indent).* args, " ,$sep_delim " )
209
+ if ! isempty (kws)
210
+ print (buffer, " ;$sep_delim " )
211
+ join (buffer, Ref (indent).* kws, " ,$sep_delim " )
212
+ end
213
+ print (buffer, " $paren_delim )" )
214
+ print (buffer, return_type)
215
+ return buffer
216
+ end
178
217
179
218
"""
180
219
$(:SIGNATURES )
@@ -194,19 +233,10 @@ f(x; a = 1, b...) = x
194
233
sig = printmethod(Docs.Binding(Main, :f), f, first(methods(f)))
195
234
```
196
235
"""
197
- function printmethod (buffer:: IOBuffer , binding:: Docs.Binding , func, method:: Method )
198
- # TODO : print qualified?
199
- print (buffer, binding. var)
200
- print (buffer, " (" )
201
- join (buffer, arguments (method), " , " )
202
- local kws = keywords (func, method)
203
- if ! isempty (kws)
204
- print (buffer, " ; " )
205
- join (buffer, kws, " , " )
206
- end
207
- print (buffer, " )" )
208
- return buffer
209
- end
236
+ printmethod (buffer:: IOBuffer , binding:: Docs.Binding , func, method:: Method ) =
237
+ printmethod_format (buffer, string (binding. var),
238
+ string .(arguments (method)),
239
+ string .(keywords (func, method)))
210
240
211
241
"""
212
242
$(:SIGNATURES )
@@ -274,18 +304,16 @@ sig = printmethod(Docs.Binding(Main, :f), f, first(methods(f)))
274
304
"""
275
305
function printmethod (buffer:: IOBuffer , binding:: Docs.Binding , func, method:: Method , typesig)
276
306
# TODO : print qualified?
277
- print (buffer, binding. var)
278
- print (buffer, " (" )
279
- local args = arguments (method)
280
- local where_syntax = []
307
+ local args = string .(arguments (method))
308
+ local kws = string .(keywords (func, method))
281
309
282
310
# find inner tuple type
283
- function f (t)
311
+ function find_inner_tuple_type (t)
284
312
# t is always either a UnionAll which represents a generic type or a Tuple where each parameter is the argument
285
313
if t isa DataType && t <: Tuple
286
314
t
287
315
elseif t isa UnionAll
288
- f (t. body)
316
+ find_inner_tuple_type (t. body)
289
317
else
290
318
error (" Expected `typeof($t )` to be `Tuple` or `UnionAll` but found `$typeof (t)`" )
291
319
end
@@ -309,45 +337,35 @@ function printmethod(buffer::IOBuffer, binding::Docs.Binding, func, method::Meth
309
337
typ
310
338
end
311
339
312
- for (i, sym) in enumerate (args)
313
- if typesig isa UnionAll
314
- # e.g. Tuple{Vector{T}} where T<:Number
315
- # or Tuple{String, T, T} where T<:Number
316
- # or Tuple{Type{T}, String, Union{Nothing, Function}} where T<:Number
317
- t = [x for x in f (typesig). types]
318
- t = [get_typesig (x, x) for x in t][i]
319
- else
320
- # e.g. Tuple{Vector{Int}}
321
- t = typesig. types[i]
322
- end
340
+ # if `typesig` is an UnionAll, it may be
341
+ # e.g. Tuple{Vector{T}} where T<:Number
342
+ # or Tuple{String, T, T} where T<:Number
343
+ # or Tuple{Type{T}, String, Union{Nothing, Function}} where T<:Number
344
+ # in the other case, it's usually something like Tuple{Vector{Int}}.
345
+ argtypes = typesig isa UnionAll ?
346
+ [get_typesig (t, t) for t in find_inner_tuple_type (typesig). types] :
347
+ collect (typesig. types)
348
+
349
+ args = map (args, argtypes) do arg,t
350
+ type = " "
351
+ suffix = " "
323
352
if isvarargtype (t)
324
- elt = vararg_eltype (t)
325
- if elt === Any
326
- print (buffer, " $sym ..." )
327
- else
328
- print (buffer, " $sym ::$elt ..." )
329
- end
330
- elseif t === Any
331
- print (buffer, sym)
332
- else
333
- print (buffer, " $sym ::$t " )
353
+ t = vararg_eltype (t)
354
+ suffix = " ..."
334
355
end
335
-
336
- if i != length (args)
337
- print (buffer, " , " )
356
+ if t!= = Any
357
+ type = " ::$t "
338
358
end
359
+
360
+ " $arg$type$suffix "
339
361
end
340
- local kws = keywords (func, method)
341
- if ! isempty (kws)
342
- print (buffer, " ; " )
343
- join (buffer, kws, " , " )
344
- end
345
- print (buffer, " )" )
362
+
346
363
rt = Base. return_types (func, typesig)
347
- if length (rt) >= 1 && rt[1 ] != = Nothing && rt[1 ] != = Union{}
348
- print (buffer, " -> $(rt[1 ]) " )
349
- end
350
- buffer
364
+
365
+ return printmethod_format (buffer, string (binding. var), args, string .(kws);
366
+ return_type =
367
+ length (rt) >= 1 && rt[1 ] != = Nothing && rt[1 ] != = Union{} ?
368
+ " -> $(rt[1 ]) " : " " )
351
369
end
352
370
353
371
printmethod (b, f, m) = String (take! (printmethod (IOBuffer (), b, f, m)))
@@ -402,7 +420,7 @@ function keywords(func, m::Method)
402
420
# table is a MethodTable object. For some reason, the :kwsorter field is not always
403
421
# defined. An undefined kwsorter seems to imply that there are no methods in the
404
422
# MethodTable with keyword arguments.
405
- if isdefined (table, :kwsorter )
423
+ if ! (Base . fieldindex (Core . MethodTable, :kwsorter , false ) > 0 ) || isdefined (table, :kwsorter )
406
424
# Fetching method keywords stolen from base/replutil.jl:572-576 (commit 3b45cdc9aab0):
407
425
kwargs = VERSION < v " 1.4.0-DEV.215" ? Base. kwarg_decl (m, typeof (table. kwsorter)) : Base. kwarg_decl (m)
408
426
if isa (kwargs, Vector) && length (kwargs) > 0
@@ -432,12 +450,21 @@ args = arguments(first(methods(f)))
432
450
```
433
451
"""
434
452
function arguments (m:: Method )
435
- local template = get_method_source (m)
436
- if isdefined (template, :slotnames )
437
- local args = map (template. slotnames[1 : nargs (m)]) do arg
453
+ local argnames = nothing
454
+ if isdefined (m, :generator )
455
+ # Generated function.
456
+ argnames = m. generator. argnames
457
+ else
458
+ local template = get_method_source (m)
459
+ if isdefined (template, :slotnames )
460
+ argnames = template. slotnames
461
+ end
462
+ end
463
+ if argnames != = nothing
464
+ local args = map (argnames[1 : nargs (m)]) do arg
438
465
arg === Symbol (" #unused#" ) ? " _" : arg
439
466
end
440
- return filter (arg -> arg != = Symbol (" #self#" ), args)
467
+ return filter (arg -> arg != = Symbol (" #self#" ) && arg != = Symbol ( " #ctor-self# " ) , args)
441
468
end
442
469
return Symbol[]
443
470
end
0 commit comments