Skip to content
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
19 changes: 14 additions & 5 deletions src/abbreviations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,25 @@ 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
signatures with types that match the given docstring. See [`printmethod`](@ref) for details on
the simplifications that are applied.

!!! tip "Disabling the Return Type"
In many codebases the return types are not annotated meaning the return
type is printed as `Any`. To reduce clutter, the return type may be omitted by
calling [`TypedMethodSignatures`](@ref) and passing `false` to its constructor:
`\$(DocStringExtensions.TypedMethodSignatures(false))`.

# Examples

The generated markdown text will look similar to the following example where a function `f`
Expand All @@ -358,9 +366,9 @@ f(x::Int, y::Int; a, b...)
```
````
"""
const TYPEDSIGNATURES = TypedMethodSignatures()
const TYPEDSIGNATURES = TypedMethodSignatures(true)

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 +403,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.TypedMethodSignatures(false), 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(DSE.TypedMethodSignatures(false), 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.TypedMethodSignatures(false), 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.TypedMethodSignatures(false), 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
Loading