Skip to content

Commit a6796b9

Browse files
JeffBezansonKristofferC
authored andcommitted
make @doc x work without REPL loaded (#54499)
fix #52141, fix #52986 (cherry picked from commit 6f569c7)
1 parent 3d6a5af commit a6796b9

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

base/docs/Docs.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,49 @@ isquotedmacrocall(@nospecialize x) =
505505
isbasicdoc(@nospecialize x) = isexpr(x, :.) || isa(x, Union{QuoteNode, Symbol})
506506
is_signature(@nospecialize x) = isexpr(x, :call) || (isexpr(x, :(::), 2) && isexpr(x.args[1], :call)) || isexpr(x, :where)
507507

508+
function _doc(binding::Binding, sig::Type = Union{})
509+
if defined(binding)
510+
result = getdoc(resolve(binding), sig)
511+
result === nothing || return result
512+
end
513+
# Lookup first match for `binding` and `sig` in all modules of the docsystem.
514+
for mod in modules
515+
dict = meta(mod; autoinit=false)
516+
isnothing(dict) && continue
517+
if haskey(dict, binding)
518+
multidoc = dict[binding]
519+
for msig in multidoc.order
520+
sig <: msig && return multidoc.docs[msig]
521+
end
522+
end
523+
end
524+
return nothing
525+
end
526+
527+
# Some additional convenience `doc` methods that take objects rather than `Binding`s.
528+
_doc(obj::UnionAll) = _doc(Base.unwrap_unionall(obj))
529+
_doc(object, sig::Type = Union{}) = _doc(aliasof(object, typeof(object)), sig)
530+
_doc(object, sig...) = _doc(object, Tuple{sig...})
531+
532+
function simple_lookup_doc(ex)
533+
if isa(ex, Expr) && ex.head !== :(.) && Base.isoperator(ex.head)
534+
# handle syntactic operators, e.g. +=, ::, .=
535+
ex = ex.head
536+
end
537+
if haskey(keywords, ex)
538+
return keywords[ex]
539+
elseif !isa(ex, Expr) && !isa(ex, Symbol)
540+
return :($(_doc)($(typeof)($(esc(ex)))))
541+
end
542+
binding = esc(bindingexpr(namify(ex)))
543+
if isexpr(ex, :call) || isexpr(ex, :macrocall) || isexpr(ex, :where)
544+
sig = esc(signature(ex))
545+
:($(_doc)($binding, $sig))
546+
else
547+
:($(_doc)($binding))
548+
end
549+
end
550+
508551
function docm(source::LineNumberNode, mod::Module, ex)
509552
@nospecialize ex
510553
if isexpr(ex, :->) && length(ex.args) > 1
@@ -513,6 +556,8 @@ function docm(source::LineNumberNode, mod::Module, ex)
513556
# TODO: this is a shim to continue to allow `@doc` for looking up docstrings
514557
REPL = Base.REPL_MODULE_REF[]
515558
return invokelatest(REPL.lookup_doc, ex)
559+
else
560+
return simple_lookup_doc(ex)
516561
end
517562
return nothing
518563
end

test/docs.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import Base.Docs: meta, @var, DocStr, parsedoc
44

5+
# check that @doc can work before REPL is loaded
6+
@test !startswith(read(`$(Base.julia_cmd()) -E '@doc sin'`, String), "nothing")
7+
58
using Markdown
69
using REPL
710

0 commit comments

Comments
 (0)