@@ -52,13 +52,14 @@ will cause that specific method to be documented, as opposed to the whole functi
52
52
docs are concatenated together in the order they were defined to provide docs for the
53
53
function.
54
54
"""
55
- :(Base . DocBootstrap . @doc )
55
+ :(Core . @doc )
56
56
57
57
include (" bindings.jl" )
58
58
59
59
import Base. Markdown: @doc_str , MD
60
60
import Base. Meta: quot, isexpr
61
61
import Base: Callable
62
+ import Core. Inference. CoreDocs: lazy_iterpolate
62
63
63
64
export doc
64
65
@@ -99,7 +100,7 @@ function argtype(expr::Expr)
99
100
isexpr (expr, :(... )) && return :(Vararg{$ (argtype (expr. args[1 ]))})
100
101
argtype (expr. args[1 ])
101
102
end
102
- argtype (:: Symbol ) = :Any
103
+ argtype (other ) = :Any
103
104
104
105
function typevars (expr:: Expr )
105
106
isexpr (expr, :curly ) && return [tvar (x) for x in expr. args[2 : end ]]
@@ -126,13 +127,9 @@ The `.data` fields stores several values related to the docstring, such as: path
126
127
linenumber, source code, and fielddocs.
127
128
"""
128
129
type DocStr
129
- text :: UTF8String
130
+ text :: Core.SimpleVector
130
131
object :: Nullable
131
132
data :: Dict{Symbol, Any}
132
-
133
- DocStr (text:: AbstractString , data) = new (text, Nullable (), data)
134
- DocStr (object, data) = new (" " , Nullable (object), data)
135
- DocStr (docstr:: DocStr , data) = docstr
136
133
end
137
134
138
135
function docstr (binding:: Binding , typesig:: ANY = Union{})
@@ -147,7 +144,13 @@ function docstr(binding::Binding, typesig::ANY = Union{})
147
144
end
148
145
error (" could not find matching docstring for '$binding :: $typesig '." )
149
146
end
150
- docstr (object, data = Dict ()) = DocStr (object, data)
147
+ docstr (object, data = Dict ()) = _docstr (object, data)
148
+
149
+ _docstr (vec:: Core.SimpleVector , data) = DocStr (vec, Nullable (), data)
150
+ _docstr (str:: AbstractString , data) = DocStr (Core. svec (str), Nullable (), data)
151
+ _docstr (object, data) = DocStr (Core. svec (), Nullable (object), data)
152
+
153
+ _docstr (doc:: DocStr , data) = (doc. data = merge (data, doc. data); doc)
151
154
152
155
macro ref (x)
153
156
binding = bindingexpr (namify (x))
157
160
158
161
docexpr (args... ) = Expr (:call , docstr, args... )
159
162
163
+ function formatdoc (d:: DocStr )
164
+ buffer = IOBuffer ()
165
+ for part in d. text
166
+ formatdoc (buffer, d, part)
167
+ end
168
+ Markdown. parse (seekstart (buffer))
169
+ end
170
+ @noinline formatdoc (buffer, d, part) = print (buffer, part)
171
+
160
172
function parsedoc (d:: DocStr )
161
173
if isnull (d. object)
162
- md = Markdown . parse (d . text )
174
+ md = formatdoc (d )
163
175
md. meta[:module ] = d. data[:module ]
164
176
md. meta[:path ] = d. data[:path ]
165
177
d. object = Nullable (md)
@@ -282,7 +294,10 @@ function fielddoc(binding::Binding, field::Symbol)
282
294
multidoc = dict[binding]
283
295
if haskey (multidoc. docs, Union{})
284
296
fields = multidoc. docs[Union{}]. data[:fields ]
285
- haskey (fields, field) && return Markdown. parse (fields[field])
297
+ if haskey (fields, field)
298
+ doc = fields[field]
299
+ return isa (doc, Markdown. MD) ? doc : Markdown. parse (doc)
300
+ end
286
301
end
287
302
end
288
303
end
@@ -377,7 +392,7 @@ isdoc(s::AbstractString) = true
377
392
378
393
isdoc (x) = isexpr (x, :string ) ||
379
394
(isexpr (x, :macrocall ) && x. args[1 ] == symbol (" @doc_str" )) ||
380
- (isexpr (x, :call ) && x. args[1 ] == Expr (:., Base. Markdown, QuoteNode ( : doc_str)) )
395
+ (isexpr (x, :call ) && x. args[1 ] == Base. Markdown. doc_str)
381
396
382
397
function unblock (ex)
383
398
isexpr (ex, :block ) || return ex
@@ -430,7 +445,8 @@ function metadata(expr)
430
445
# Source code for the object being documented.
431
446
push! (args, :($ (Pair)(:source , $ (quot (expr)))))
432
447
# Filename and linenumber of the docstring.
433
- push! (args, :($ (Pair)(:path , $ (Base). @__FILE__ )), :($ (Pair)(:linenumber , @__LINE__ )))
448
+ push! (args, :($ (Pair)(:path , $ (Base). @__FILE__ )))
449
+ push! (args, :($ (Pair)(:linenumber , $ (unsafe_load (cglobal (:jl_lineno , Int))))))
434
450
# Module in which the docstring is defined.
435
451
push! (args, :($ (Pair)(:module , $ (current_module)())))
436
452
# Field docs for concrete types.
@@ -451,9 +467,14 @@ function metadata(expr)
451
467
:($ (Dict)($ (args... )))
452
468
end
453
469
470
+ function keyworddoc (str, def)
471
+ docstr = esc (docexpr (lazy_iterpolate (str), metadata (def)))
472
+ :($ (keywords)[$ (esc (quot (def. name)))] = $ docstr)
473
+ end
474
+
454
475
function objectdoc (str, def, expr, sig = :(Union{}))
455
476
binding = esc (bindingexpr (namify (expr)))
456
- docstr = esc (docexpr (str, metadata (expr)))
477
+ docstr = esc (docexpr (lazy_iterpolate ( str) , metadata (expr)))
457
478
quote
458
479
$ (esc (def))
459
480
$ (doc!)($ binding, $ docstr, $ (esc (sig)))
480
501
# Shares a single doc, `meta`, between several expressions from the tuple expression `ex`.
481
502
function multidoc (meta, ex, define)
482
503
out = Expr (:toplevel )
483
- str = docexpr (meta, metadata (ex))
504
+ str = docexpr (lazy_iterpolate ( meta) , metadata (ex))
484
505
ref = Ref {DocStr} ()
485
506
for (n, arg) in enumerate (ex. args)
486
507
# The first `arg` to be documented needs to also create the docstring for the group.
@@ -508,7 +529,7 @@ more than one expression is marked then the same docstring is applied to each ex
508
529
509
530
`@__doc__` has no effect when a macro that uses it is not documented.
510
531
"""
511
- :(Base . @__doc__ )
532
+ :(Core . @__doc__ )
512
533
513
534
function __doc__! (meta, def, define)
514
535
# Two cases must be handled here to avoid redefining all definitions contained in `def`:
@@ -575,6 +596,13 @@ function docm(meta, ex, define = true)
575
596
# Initalise the module's docstring storage.
576
597
initmeta ()
577
598
599
+ # Keywords using the `@kw_str` macro in `base/docs/basedocs.jl`.
600
+ #
601
+ # "..."
602
+ # kw"if", kw"else"
603
+ #
604
+ isa (x, Base. BaseDocs. Keyword) ? keyworddoc (meta, x) :
605
+
578
606
# Method / macro definitions and "call" syntax.
579
607
#
580
608
# function f(...) ... end
@@ -631,7 +659,7 @@ function docerror(ex)
631
659
if isexpr (ex, :macrocall )
632
660
txt *= " \n\n '$(ex. args[1 ]) ' not documentable. See 'Base.@__doc__' docs for details."
633
661
end
634
- :(error ($ txt, " \n " ))
662
+ :($ ( error) ($ txt, " \n " ))
635
663
end
636
664
637
665
function docm (ex)
@@ -652,20 +680,21 @@ function docm(ex)
652
680
end
653
681
end
654
682
655
- # Swap out the bootstrap macro with the real one
656
-
657
- Base. DocBootstrap. setexpand! (docm)
658
-
659
- # Names are resolved relative to the Base module, so inject the ones we need there.
660
-
661
- eval (Base, :(import . Docs: @doc_str ))
662
-
663
- Base. DocBootstrap. loaddocs ()
664
-
665
683
# MD support
666
-
667
684
catdoc (md:: MD... ) = MD (md... )
668
685
669
686
include (" utils.jl" )
670
687
688
+ # Swap out the bootstrap macro with the real one.
689
+ Core. atdoc! (docm)
690
+
691
+ function loaddocs (docs)
692
+ for (mod, ex, str, file, line) in docs
693
+ data = Dict (:path => string (file), :linenumber => line)
694
+ doc = docstr (str, data)
695
+ eval (mod, :(@doc ($ doc, $ ex, false )))
696
+ end
697
+ empty! (docs)
698
+ end
699
+
671
700
end
0 commit comments