From 1060bfeabd1568bd17947b20a8887758c92b7f23 Mon Sep 17 00:00:00 2001 From: Michael Hatherly Date: Mon, 29 Jun 2015 15:29:27 +0200 Subject: [PATCH] Fix #11798. --- base/docs/Docs.jl | 65 ++++++++++++++++++++++------------------------- test/docs.jl | 14 ++++++++++ 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index 11eade73e43d49..6d8706fc1ee0d2 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -3,6 +3,7 @@ module Docs import Base.Markdown: @doc_str, MD +import Base.Meta: quot export doc @@ -36,41 +37,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, typevars(expr)..., sig)) + 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 @@ -254,11 +248,13 @@ function namedoc(meta, def, name) end function funcdoc(meta, def) + f = esc(namify(def)) + 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 @@ -288,7 +284,7 @@ function docm(meta, def) isexpr(def′, :type, :bitstype) && return typedoc(meta, def, namify(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) + fexpr(def′) && return funcdoc(meta, def′) isexpr(def′, :macrocall) && (def = namify(def′)) return objdoc(meta, def) end @@ -314,8 +310,7 @@ 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)) # Metametadata diff --git a/test/docs.jl b/test/docs.jl index 956455e4d7dba3..6814187b4a1459 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -9,6 +9,20 @@ macro macro_doctest() end @macro_doctest @test (@doc @macro_doctest) != nothing +# issue #11798 + +module I11798 + +"read" +read(x) = x + +end + +let fd = I11798.META[I11798.read] + @test fd.order[1] == which(I11798.read, Tuple{Any}) + @test fd.meta[fd.order[1]] == doc"read" +end + # issue #11548 module ModuleMacroDoc