Skip to content

Commit

Permalink
Merge pull request JuliaLang#14404 from JuliaLang/jcb/fixannoyingdocb…
Browse files Browse the repository at this point in the history
…indingerror

Fix exception being thrown when a binding is not defined
  • Loading branch information
jakebolewski committed Dec 16, 2015
2 parents 2778a52 + 9e2f5dc commit 381d480
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 32 deletions.
88 changes: 57 additions & 31 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ end

function get_obj_meta(obj)
for mod in modules
haskey(meta(mod), obj) && return meta(mod)[obj]
if haskey(meta(mod), obj)
return meta(mod)[obj]
end
end
nothing
end

"`doc(obj)`: Get the metadata associated with `obj`."
Expand Down Expand Up @@ -146,38 +149,60 @@ function functionsummary(func::Function)
return Markdown.parse(takebuf_string(io))
end

function qualified_name(b::Binding)
if b.mod === Main
string(b.var)
else
join((b.mod, b.var), '.')
end
end

function doc(b::Binding)
d = get_obj_meta(b)
if d === nothing
v = getfield(b.mod,b.var)
d = doc(v)
if d === nothing
if startswith(string(b.var),'@')
# check to see if the binding var is a macro
d = catdoc(Markdown.parse("""
No documentation found.
"""), macrosummary(b.var, v))
elseif isa(v,Function)
d = catdoc(Markdown.parse("""
No documentation found.
`$(b.mod === Main ? b.var : join((b.mod, b.var),'.'))` is $(isgeneric(v) ? "a generic" : "an anonymous") `Function`.
"""), functionsummary(v))
elseif isa(v,DataType)
d = catdoc(Markdown.parse("""
No documentation found.
"""), typesummary(v))
else
T = typeof(v)
d = catdoc(Markdown.parse("""
No documentation found.
if d !== nothing
return d
end
if !(b.defined)
return Markdown.parse("""
`$(b.mod === Main ? b.var : join((b.mod, b.var),'.'))` is of type `$T`:
"""), typesummary(typeof(v)))
end
end
No documentation found.
Binding `$(qualified_name(b))` does not exist.
""")
end
v = getfield(b.mod,b.var)
d = doc(v)
if d !== nothing
return d
end
if startswith(string(b.var),'@')
# check to see if the binding var is a macro
d = catdoc(Markdown.parse("""
No documentation found.
"""), macrosummary(b.var, v))
elseif isa(v,Function)
d = catdoc(Markdown.parse("""
No documentation found.
`$(qualified_name(b))` is $(isgeneric(v) ? "a generic" : "an anonymous") `Function`.
"""), functionsummary(v))
elseif isa(v,DataType)
d = catdoc(Markdown.parse("""
No documentation found.
"""), typesummary(v))
else
T = typeof(v)
d = catdoc(Markdown.parse("""
No documentation found.
`$(qualified_name(b))` is of type `$T`:
"""), typesummary(typeof(v)))
end
return d
end
Expand Down Expand Up @@ -518,8 +543,9 @@ function docm(meta, def, define = true)

def′ = unblock(def)

isexpr(def′, :quote) && isexpr(def′.args[1], :macrocall) &&
if isexpr(def′, :quote) && isexpr(def′.args[1], :macrocall)
return vardoc(meta, nothing, namify(def′.args[1]))
end

ex = def # Save unexpanded expression for error reporting.
def = macroexpand(def)
Expand Down
10 changes: 9 additions & 1 deletion base/docs/bindings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ export @var
immutable Binding
mod::Module
var::Symbol
Binding(m, v) = new(Base.which_module(m, v), v)
defined::Bool

function Binding(m, v)
if !isdefined(m, v)
new(m, v, false)
else
new(Base.binding_module(m, v), v, true)
end
end
end

function splitexpr(x::Expr)
Expand Down
21 changes: 21 additions & 0 deletions test/docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,12 @@ undocumented(x,y) = 3

end

@test docstrings_equal(@doc(Undocumented.bindingdoesnotexist), doc"""
No documentation found.
Binding `Undocumented.bindingdoesnotexist` does not exist.
""")

@test docstrings_equal(@doc(Undocumented.A), doc"""
No documentation found.
Expand Down Expand Up @@ -577,32 +583,47 @@ end
import Base.Docs: @var, Binding

let x = Binding(Base, symbol("@time"))
@test x.defined == true
@test @var(@time) == x
@test @var(Base.@time) == x
@test @var(Base.Pkg.@time) == x
end

let x = Binding(Base.LinAlg, :norm)
@test x.defined == true
@test @var(norm) == x
@test @var(Base.norm) == x
@test @var(Base.LinAlg.norm) == x
@test @var(Base.Pkg.Dir.norm) == x
end

let x = Binding(Core, :Int)
@test x.defined == true
@test @var(Int) == x
@test @var(Base.Int) == x
@test @var(Core.Int) == x
@test @var(Base.Pkg.Resolve.Int) == x
end

let x = Binding(Base, :Pkg)
@test x.defined == true
@test @var(Pkg) == x
@test @var(Base.Pkg) == x
@test @var(Main.Pkg) == x
end

let x = Binding(Base, :VERSION)
@test x.defined == true
@test @var(VERSION) == x
@test @var(Base.VERSION) == x
end

let x = Binding(Base, :bindingdoesnotexist)
@test x.defined == false
@test @var(Base.bindingdoesnotexist) == x
end

let x = Binding(Main, :bindingdoesnotexist)
@test x.defined == false
@test @var(bindingdoesnotexist) == x
end

0 comments on commit 381d480

Please sign in to comment.