diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index 5527ca3020dc11..b36fd297edef50 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -36,39 +36,42 @@ 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 + block = typevars(expr) + push!(block, sig) + Expr(:let, Expr(:block, block...)) + 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 + +function typevars(expr::Expr) + isexpr(expr, :curly) && return [tvar(x) for x in expr.args[2:end]] + typevars(expr.args[1]) end +typevars(::Symbol) = [] -def_dict(f) = [def => def.func for def in methods(f)] +tvar(x::Expr) = Expr(:(=), x.args[1], :(TypeVar($(quot(x.args[1])), $(x.args[2]), true))) +tvar(s::Symbol) = Expr(:(=), s, :(TypeVar($(quot(s)), Any, true))) function trackmethod(def) - name = uncurly(unblock(def).args[1].args[1]) - f = esc(name) + name = esc(uncurly(unblock(def).args[1].args[1])) 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 + $name, methods($name, $(esc(signature(def))))[1] end end @@ -218,6 +221,8 @@ const keywords = Dict{Symbol,Any}() # Usage macros +quot(x) = Expr(:quote, x) + isexpr(x::Expr) = true isexpr(x) = false isexpr(x::Expr, ts...) = x.head in ts @@ -315,7 +320,7 @@ Base.DocBootstrap.setexpand!(docm) # inject the ones we need there. eval(Base.DocBootstrap, - :(import ..Docs: @init, doc!, doc, newmethod, def_dict, @doc_str)) + :(import ..Docs: @init, doc!, doc, @doc_str)) # Metametadata