Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better methodshow for non-standard identifiers #37750

Merged
merged 3 commits into from
Oct 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
55 changes: 40 additions & 15 deletions base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

# Method and method table pretty-printing

const empty_sym = Symbol("")
function strip_gensym(sym)
if sym === Symbol("#self#") || sym === Symbol("#unused#")
return empty_sym
end
return Symbol(replace(String(sym), r"^(.*)#(.*#)?\d+$" => s"\1"))
end

function argtype_decl(env, n, @nospecialize(sig::DataType), i::Int, nargs, isva::Bool) # -> (argname, argtype)
t = sig.parameters[i]
if i == nargs && isva && !isvarargtype(t)
Expand All @@ -10,13 +18,13 @@ function argtype_decl(env, n, @nospecialize(sig::DataType), i::Int, nargs, isva:
if isa(n,Expr)
n = n.args[1] # handle n::T in arg list
end
s = string(n)::String
i = findfirst(isequal('#'), s)
if i !== nothing
s = s[1:prevind(s, i)::Int]
end
if t === Any && !isempty(s)
return s, ""
n = strip_gensym(n)
local s
if n === empty_sym
s = ""
else
s = sprint(show_sym, n)
t === Any && return s, ""
end
if isvarargtype(t)
v1, v2 = nothing, nothing
Expand Down Expand Up @@ -73,8 +81,6 @@ function arg_decl_parts(m::Method, html=false)
return tv, decls, file, line
end

const empty_sym = Symbol("")

# NOTE: second argument is deprecated and is no longer used
function kwarg_decl(m::Method, kwtype = nothing)
mt = get_methodtable(m)
Expand Down Expand Up @@ -184,6 +190,15 @@ function functionloc(@nospecialize(f))
return functionloc(first(mt))
end

function sym_to_string(sym)
s = String(sym)
if endswith(s, "...")
return string(sprint(show_sym, Symbol(s[1:end-3])), "...")
else
return sprint(show_sym, sym)
end
end

function show(io::IO, m::Method)
tv, decls, file, line = arg_decl_parts(m)
sig = unwrap_unionall(m.sig)
Expand All @@ -193,12 +208,16 @@ function show(io::IO, m::Method)
return
end
print(io, decls[1][2], "(")
join(io, String[isempty(d[2]) ? d[1] : d[1]*"::"*d[2] for d in decls[2:end]],
", ", ", ")
join(
io,
String[isempty(d[2]) ? d[1] : string(d[1], "::", d[2]) for d in decls[2:end]],
", ",
", ",
)
kwargs = kwarg_decl(m)
if !isempty(kwargs)
print(io, "; ")
join(io, kwargs, ", ", ", ")
join(io, map(sym_to_string, kwargs), ", ", ", ")
end
print(io, ")")
show_method_params(io, tv)
Expand Down Expand Up @@ -339,12 +358,18 @@ function show(io::IO, ::MIME"text/html", m::Method)
return
end
print(io, decls[1][2], "(")
join(io, String[isempty(d[2]) ? d[1] : d[1]*"::<b>"*d[2]*"</b>"
for d in decls[2:end]], ", ", ", ")
join(
io,
String[
isempty(d[2]) ? d[1] : string(d[1], "::<b>", d[2], "</b>") for d in decls[2:end]
],
", ",
", ",
)
kwargs = kwarg_decl(m)
if !isempty(kwargs)
print(io, "; <i>")
join(io, kwargs, ", ", ", ")
join(io, map(sym_to_string, kwargs), ", ", ", ")
print(io, "</i>")
end
print(io, ")")
Expand Down
2 changes: 1 addition & 1 deletion base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,7 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg
if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) &&
isdefined(uw.name.module, uw.name.mt.name) &&
ft == typeof(getfield(uw.name.module, uw.name.mt.name))
print(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
show_sym(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
elseif isa(ft, DataType) && ft.name === Type.body.name &&
(f = ft.parameters[1]; !isa(f, TypeVar))
uwf = unwrap_unionall(f)
Expand Down
2 changes: 1 addition & 1 deletion test/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ let err_str,
@test startswith(sprint(show, which(Complex{Int}, Tuple{Int})),
"Complex{T}(")
@test startswith(sprint(show, which(getfield(Base, Symbol("@doc")), Tuple{LineNumberNode, Module, Vararg{Any}})),
"@doc(__source__::LineNumberNode, __module__::Module, x...) in Core at boot.jl:")
"var\"@doc\"(__source__::LineNumberNode, __module__::Module, x...) in Core at boot.jl:")
@test startswith(sprint(show, which(FunctionLike(), Tuple{})),
"(::$(curmod_prefix)FunctionLike)() in $curmod_str at $sp:$(method_defs_lineno + 7)")
@test startswith(sprint(show, which(StructWithUnionAllMethodDefs{<:Integer}, (Any,))),
Expand Down
23 changes: 23 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2018,3 +2018,26 @@ end
@test Base.make_typealias(M37012.AStruct{1}) === nothing
@test isempty(Base.make_typealiases(M37012.AStruct{1})[1])
@test string(M37012.AStruct{1}) == "$(curmod_prefix)M37012.AStruct{1}"

@testset "method printing with non-standard identifiers ($mime)" for mime in (
MIME("text/plain"), MIME("text/html"),
)
_show(io, x) = show(io, MIME(mime), x)

@eval var","(x) = x
@test occursin("var\",\"(x)", sprint(_show, methods(var",")))

@eval f1(var"a.b") = 3
@test occursin("f1(var\"a.b\")", sprint(_show, methods(f1)))

italic(s) = mime == MIME("text/html") ? "<i>$s</i>" : s

@eval f2(; var"123") = 5
@test occursin("f2(; $(italic("var\"123\"")))", sprint(_show, methods(f2)))

@eval f3(; var"%!"...) = 7
@test occursin("f3(; $(italic("var\"%!\"...")))", sprint(_show, methods(f3)))

@eval f4(; var"...") = 9
@test_broken occursin("f4(; $(italic("var\"...\"")))", sprint(_show, methods(f4)))
end