Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/DocStringExtensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module DocStringExtensions
# Exports.

export @template, FIELDS, TYPEDFIELDS, EXPORTS, METHODLIST, IMPORTS
export SIGNATURES, TYPEDSIGNATURES, TYPEDEF, DOCSTRING, FUNCTIONNAME
export SIGNATURES, TYPEDSIGNATURES, TYPEDSIGNATURESNORETURN, TYPEDEF, DOCSTRING, FUNCTIONNAME
export README, LICENSE
# export interpolation

Expand Down
21 changes: 16 additions & 5 deletions src/abbreviations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,13 @@ end
#

"""
The singleton type for [`TYPEDSIGNATURES`](@ref) abbreviations.
The type for [`TYPEDSIGNATURES`](@ref) abbreviations.

$(:FIELDS)
"""
struct TypedMethodSignatures <: Abbreviation end
struct TypedMethodSignatures <: Abbreviation
return_types::Bool
end

"""
An [`Abbreviation`](@ref) for including a simplified representation of all the method
Expand All @@ -358,9 +360,17 @@ f(x::Int, y::Int; a, b...)
```
````
"""
const TYPEDSIGNATURES = TypedMethodSignatures()
const TYPEDSIGNATURES = TypedMethodSignatures(true)

"""
An alternative to [`TYPEDSIGNATURES`](@ref) that omits the return type.

The return type shown by [`TYPEDSIGNATURES`](@ref) is often `-> Any`, which is usually not
correct. It is nicer to then just omit the type completely.
"""
const TYPEDSIGNATURESNORETURN = TypedMethodSignatures(false)

function format(::TypedMethodSignatures, buf, doc)
function format(tms::TypedMethodSignatures, buf, doc)
local binding = doc.data[:binding]
local typesig = doc.data[:typesig]
local modname = doc.data[:module]
Expand Down Expand Up @@ -395,7 +405,8 @@ function format(::TypedMethodSignatures, buf, doc)
else
t = tuples[findfirst(f, tuples)]
end
printmethod(buf, binding, func, method, t)
printmethod(buf, binding, func, method, t;
print_return_types=tms.return_types)
println(buf)
end
println(buf, "\n```\n")
Expand Down
23 changes: 18 additions & 5 deletions src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ f(x::Int; a = 1, b...) = x
sig = printmethod(Docs.Binding(Main, :f), f, first(methods(f)))
```
"""
function printmethod(buffer::IOBuffer, binding::Docs.Binding, func, method::Method, typesig)
function printmethod(buffer::IOBuffer, binding::Docs.Binding, func, method::Method, typesig; print_return_types=true)
# TODO: print qualified?
local args = string.(arguments(method))
local kws = string.(keywords(func, method))
Expand Down Expand Up @@ -397,11 +397,24 @@ function printmethod(buffer::IOBuffer, binding::Docs.Binding, func, method::Meth
end

rt = Base.return_types(func, typesig)
return_type_string = if (
print_return_types &&
length(rt) >= 1 &&
rt[1] !== Nothing &&
rt[1] !== Union{}
)
" -> $(rt[1])"
else
""
end

return printmethod_format(buffer, string(binding.var), args, string.(kws);
return_type =
length(rt) >= 1 && rt[1] !== Nothing && rt[1] !== Union{} ?
" -> $(rt[1])" : "")
return printmethod_format(
buffer,
string(binding.var),
args,
string.(kws);
return_type=return_type_string
)
end

printmethod(b, f, m) = String(take!(printmethod(IOBuffer(), b, f, m)))
Expand Down
75 changes: 75 additions & 0 deletions test/tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,81 @@ end

end

@testset "method signatures with types (no return type)" begin
doc.data = Dict(
:binding => Docs.Binding(M, :h_1),
:typesig => Tuple{M.A},
:module => M,
)
DSE.format(DSE.TYPEDSIGNATURESNORETURN, buf, doc)
str = String(take!(buf))
@test occursin("\n```julia\n", str)
f = str -> replace(str, " " => "")
str = f(str)
if Sys.iswindows() && VERSION < v"1.8"
@test occursin(f("h_1(x::Union{Array{T,4}, Array{T,3}} where T)"), str)
else
@test occursin(f("h_1(x::Union{Array{T,3}, Array{T,4}} where T)"), str)
end
@test !occursin("->", str)
@test occursin("\n```\n", str)


doc.data = Dict(
:binding => Docs.Binding(M, :g_2),
:typesig => Tuple{String},
:module => M,
)
DSE.format(TYPEDSIGNATURESNORETURN, buf, doc)
str = String(take!(buf))
@test occursin("\n```julia\n", str)
@test occursin("\ng_2(x::String)", str)
@test occursin("\n```\n", str)

doc.data = Dict(
:binding => Docs.Binding(M, :h),
:typesig => Tuple{Int, Int, Int},
:module => M,
)
DSE.format(DSE.TYPEDSIGNATURESNORETURN, buf, doc)
str = String(take!(buf))
@test occursin("\n```julia\n", str)
if typeof(1) === Int64
@test occursin("\nh(x::Int64, y::Int64, z::Int64; kwargs...)\n", str)
else
@test occursin("\nh(x::Int32, y::Int32, z::Int32; kwargs...)\n", str)
end
@test occursin("\n```\n", str)

doc.data = Dict(
:binding => Docs.Binding(M, :h),
:typesig => Tuple{Int},
:module => M,
)
DSE.format(DSE.TYPEDSIGNATURESNORETURN, buf, doc)
str = String(take!(buf))
@test occursin("\n```julia\n", str)
if typeof(1) === Int64
# On 1.10+, automatically generated methods have keywords in the metadata,
# hence the display difference between Julia versions.
if VERSION >= v"1.10"
@test occursin("\nh(x::Int64; ...)\n", str)
else
@test occursin("\nh(x::Int64)\n", str)
end
else
# On 1.10+, automatically generated methods have keywords in the metadata,
# hence the display difference between Julia versions.
if VERSION >= v"1.10"
@test occursin("\nh(x::Int32; ...)\n", str)
else
@test occursin("\nh(x::Int32)\n", str)
end
end
@test occursin("\n```\n", str)

end

@testset "function names" begin
doc.data = Dict(
:binding => Docs.Binding(M, :f),
Expand Down