diff --git a/Project.toml b/Project.toml index 0a698ef..caa097f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DocStringExtensions" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.4" +version = "0.9.5" [compat] julia = "1" diff --git a/src/utilities.jl b/src/utilities.jl index 7506ffd..e04d459 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -452,24 +452,28 @@ kws = keywords(f, first(methods(f))) ``` """ function keywords(func, m::Method) - table = methods(func).mt - # table is a MethodTable object. For some reason, the :kwsorter field is not always - # defined. An undefined kwsorter seems to imply that there are no methods in the - # MethodTable with keyword arguments. - if !(Base.fieldindex(Core.MethodTable, :kwsorter, false) > 0) || isdefined(table, :kwsorter) - # Fetching method keywords stolen from base/replutil.jl:572-576 (commit 3b45cdc9aab0): - kwargs = VERSION < v"1.4.0-DEV.215" ? Base.kwarg_decl(m, typeof(table.kwsorter)) : Base.kwarg_decl(m) - if isa(kwargs, Vector) && length(kwargs) > 0 - filter!(arg -> !occursin("#", string(arg)), kwargs) - # Keywords *may* not be sorted correctly. We move the vararg one to the end. - index = findfirst(arg -> endswith(string(arg), "..."), kwargs) - if index != nothing - kwargs[index], kwargs[end] = kwargs[end], kwargs[index] - end - return kwargs + kwargs = @static if VERSION < v"1.4.0-DEV.215" + table::Core.MethodTable = methods(func).mt + # For some reason, the :kwsorter field is not always defined. + # An undefined kwsorter seems to imply that there are no methods + # in the MethodTable with keyword arguments. + if Base.fieldindex(Core.MethodTable, :kwsorter, false) > 0 && !isdefined(table, :kwsorter) + return Symbol[] end + Base.kwarg_decl(m, typeof(table.kwsorter)) + else + Base.kwarg_decl(m) end - return Symbol[] + if !isa(kwargs, Vector) || isempty(kwargs) + return Symbol[] + end + filter!(arg -> !occursin("#", string(arg)), kwargs) + # Keywords *may* not be sorted correctly. We move the vararg one to the end. + index = findfirst(arg -> endswith(string(arg), "..."), kwargs) + if index != nothing + kwargs[index], kwargs[end] = kwargs[end], kwargs[index] + end + return kwargs end diff --git a/test/tests.jl b/test/tests.jl index fead702..913fa9f 100644 --- a/test/tests.jl +++ b/test/tests.jl @@ -40,15 +40,15 @@ end # Its signature is kwarg_decl(m::Method, kwtype::DataType). The second argument # should be the type of the kwsorter from the corresponding MethodTable. @test isa(methods(M.j_1), Base.MethodList) - @test isdefined(methods(M.j_1), :mt) - local mt = methods(M.j_1).mt + get_mt(func) = VERSION ≥ v"1.13.0-DEV.647" ? Core.GlobalMethods : methods(func).mt + local mt = get_mt(M.j_1) @test isa(mt, Core.MethodTable) if Base.fieldindex(Core.MethodTable, :kwsorter, false) > 0 @test isdefined(mt, :kwsorter) end # .kwsorter is not always defined -- namely, it seems when none of the methods # have keyword arguments: - @test isdefined(methods(M.f).mt, :kwsorter) === false + @test isdefined(get_mt(M.f), :kwsorter) === false # M.j_1 has two methods. Fetch the single argument one.. local m = which(M.j_1, (Any,)) @test isa(m, Method) @@ -61,7 +61,7 @@ end # that does not have any arguments m = which(M.j_1, (Any,Any)) # fetch the no-keyword method if VERSION < v"1.4.0-DEV.215" - @test Base.kwarg_decl(m, typeof(methods(M.j_1).mt.kwsorter)) == Tuple{}() + @test Base.kwarg_decl(m, typeof(get_mt(M.j_1).kwsorter)) == Tuple{}() else @test Base.kwarg_decl(m) == [] end @@ -83,7 +83,9 @@ end DSE.format(IMPORTS, buf, doc) str = String(take!(buf)) @test occursin("\n - `Base`\n", str) - @test occursin("\n - `Core`\n", str) + if VERSION < v"1.13-DEV" + @test occursin("\n - `Core`\n", str) + end # Module exports. DSE.format(EXPORTS, buf, doc)