Skip to content

Commit

Permalink
better methodshow for non-standard identifiers (#37750)
Browse files Browse the repository at this point in the history
  • Loading branch information
simeonschaub authored Oct 17, 2020
1 parent 912cd3f commit 46834a2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 17 deletions.
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 @@ -186,6 +192,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 @@ -195,12 +210,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 @@ -341,12 +360,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 @@ -2064,7 +2064,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 @@ -2037,3 +2037,26 @@ for s in (Symbol("'"), Symbol("'⁻¹"))
@test !Base.isbinaryoperator(s)
@test Base.ispostfixoperator(s)
end

@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

0 comments on commit 46834a2

Please sign in to comment.