Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #11798 & load bootstrapped docs. #11932

Merged
merged 2 commits into from
Aug 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 46 additions & 45 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module Docs

import Base.Markdown: @doc_str, MD
import Base.Meta: quot

export doc

Expand Down Expand Up @@ -40,41 +41,34 @@ end

# Function / Method support

function newmethod(defs)
keylen = -1
key = nothing
for def in defs
length(def.sig.parameters) > keylen && (keylen = length(def.sig.parameters); key = def)
function signature(expr::Expr)
if isexpr(expr, :call)
sig = :(Tuple{})
for arg in expr.args[2:end]
isexpr(arg, :parameters) && continue
push!(sig.args, argtype(arg))
end
Expr(:let, Expr(:block, sig), typevars(expr)...)
else
signature(expr.args[1])
end
return key
end

function newmethod(funcs, f)
applicable = Method[]
for def in methods(f)
(!haskey(funcs, def) || funcs[def] != def.func) && push!(applicable, def)
end
return newmethod(applicable)
function argtype(expr::Expr)
isexpr(expr, :(::)) && return expr.args[end]
isexpr(expr, :(...)) && return :(Vararg{$(argtype(expr.args[1]))})
argtype(expr.args[1])
end
argtype(::Symbol) = :Any

def_dict(f) = [def => def.func for def in methods(f)]

function trackmethod(def)
name = uncurly(unblock(def).args[1].args[1])
f = esc(name)
quote
funcs = nothing
if $(isexpr(name, Symbol)) && isdefined($(Expr(:quote, name))) && isgeneric($f)
funcs = def_dict($f)
end
$(esc(def))
if funcs !== nothing
$f, newmethod(funcs, $f)
else
$f, newmethod(methods($f))
end
end
function typevars(expr::Expr)
isexpr(expr, :curly) && return [tvar(x) for x in expr.args[2:end]]
typevars(expr.args[1])
end
typevars(::Symbol) = []

tvar(x::Expr) = :($(x.args[1]) = TypeVar($(quot(x.args[1])), $(x.args[2]), true))
tvar(s::Symbol) = :($(s) = TypeVar($(quot(s)), Any, true))

type FuncDoc
main
Expand Down Expand Up @@ -258,12 +252,14 @@ function namedoc(meta, def, name)
end
end

function funcdoc(meta, def)
function funcdoc(meta, def, def′, name)
f = esc(name)
m = :(which($f, $(esc(signature(def′)))))
quote
@init
f, m = $(trackmethod(def))
doc!(f, m, $(mdify(meta)), $(esc(Expr(:quote, def))))
f
$(esc(def))
doc!($f, $m, $(mdify(meta)), $(esc(quot(def))))
$f
end
end

Expand All @@ -279,15 +275,13 @@ end
function objdoc(meta, def)
quote
@init
f = $(esc(def))
doc!(f, $(mdify(meta)))
f
doc!($(esc(def)), $(mdify(meta)))
end
end

fexpr(ex) = isexpr(ex, :function, :(=)) && isexpr(ex.args[1], :call)

function docm(meta, def)
function docm(meta, def, define = true)
# Quote, Unblock and Macroexpand
# * Always do macro expansion unless it's a quote (for consistency)
# * Unblock before checking for Expr(:quote) to support `->` syntax
Expand All @@ -305,12 +299,18 @@ function docm(meta, def)
# Allow more general macrocall for now unless it causes confusion.
return objdoc(meta, namify(def′.args[1]))
end
isexpr(def′, :macro) && return namedoc(meta, def, symbol("@", namify(def′)))
isexpr(def′, :type) && return typedoc(meta, def, namify(def′.args[2]))
isexpr(def′, :bitstype) && return namedoc(meta, def, def′.args[2])
isexpr(def′, :abstract) && return namedoc(meta, def, namify(def′))
isexpr(def′, :module) && return namedoc(meta, def, def′.args[2])
fexpr(def′) && return funcdoc(meta, def)

define || (def = nothing)

fexpr(def′) && return funcdoc(meta, def, def′, namify(def′))
isexpr(def′, :type) && return typedoc(meta, def, namify(def′.args[2]))
isexpr(def′, :macro) && return namedoc(meta, def, symbol("@", namify(def′)))
isexpr(def′, :abstract) && return namedoc(meta, def, namify(def′))
isexpr(def′, :bitstype) && return namedoc(meta, def, def′.args[2])
isexpr(def′, :module) && return namedoc(meta, def, def′.args[2])
isexpr(def′, :(=), :const) && return namedoc(meta, def, namify(def′))

isexpr(def′, :macrocall) && (def = namify(def′))
return objdoc(meta, def)
end

Expand All @@ -335,8 +335,9 @@ Base.DocBootstrap.setexpand!(docm)
# Names are resolved relative to the DocBootstrap module, so
# inject the ones we need there.

eval(Base.DocBootstrap,
:(import ..Docs: @init, doc!, doc, newmethod, def_dict, @doc_str))
eval(Base.DocBootstrap, :(import ..Docs: @init, doc!, doc, @doc_str))

Base.DocBootstrap.loaddocs()

# Metametadata

Expand Down
13 changes: 9 additions & 4 deletions base/docs/bootstrap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ _expand_ = nothing
setexpand!(f) = global _expand_ = f

macro doc(args...)
_expand_(args...)
_expand_(args...)
end

setexpand!() do str, obj
# str, obj = ex.args[1], ex.args[2]
push!(docs, (current_module(), str, obj))
return esc(obj)
push!(docs, (current_module(), str, obj))
return esc(obj)
end

function loaddocs()
for (mod, str, obj) in docs
eval(mod, :(Base.@doc($str, $obj, false)))
end
end

end
10 changes: 4 additions & 6 deletions base/markdown/Julia/Julia.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# This file is a part of Julia. License is MIT: http://julialang.org/license

"""
This file contains markdown extensions designed to make documenting
Julia easy peasy.

We start by borrowing GitHub's `fencedcode` extension – more to follow.
"""
# This file contains markdown extensions designed to make documenting
# Julia easy peasy.
#
# We start by borrowing GitHub's `fencedcode` extension – more to follow.

include("interp.jl")

Expand Down
14 changes: 14 additions & 0 deletions test/docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,17 @@ f1_11993()
@test (@doc f2_11993) !== nothing

f2_11993()

# issue #11798

module I11798

"read"
read(x) = x

end

let fd = meta(I11798)[I11798.read]
@test fd.order[1] == which(I11798.read, Tuple{Any})
@test fd.meta[fd.order[1]] == doc"read"
end