Skip to content

Commit 46834a2

Browse files
authored
better methodshow for non-standard identifiers (#37750)
1 parent 912cd3f commit 46834a2

File tree

4 files changed

+65
-17
lines changed

4 files changed

+65
-17
lines changed

base/methodshow.jl

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
# Method and method table pretty-printing
44

5+
const empty_sym = Symbol("")
6+
function strip_gensym(sym)
7+
if sym === Symbol("#self#") || sym === Symbol("#unused#")
8+
return empty_sym
9+
end
10+
return Symbol(replace(String(sym), r"^(.*)#(.*#)?\d+$" => s"\1"))
11+
end
12+
513
function argtype_decl(env, n, @nospecialize(sig::DataType), i::Int, nargs, isva::Bool) # -> (argname, argtype)
614
t = sig.parameters[i]
715
if i == nargs && isva && !isvarargtype(t)
@@ -10,13 +18,13 @@ function argtype_decl(env, n, @nospecialize(sig::DataType), i::Int, nargs, isva:
1018
if isa(n,Expr)
1119
n = n.args[1] # handle n::T in arg list
1220
end
13-
s = string(n)::String
14-
i = findfirst(isequal('#'), s)
15-
if i !== nothing
16-
s = s[1:prevind(s, i)::Int]
17-
end
18-
if t === Any && !isempty(s)
19-
return s, ""
21+
n = strip_gensym(n)
22+
local s
23+
if n === empty_sym
24+
s = ""
25+
else
26+
s = sprint(show_sym, n)
27+
t === Any && return s, ""
2028
end
2129
if isvarargtype(t)
2230
v1, v2 = nothing, nothing
@@ -73,8 +81,6 @@ function arg_decl_parts(m::Method, html=false)
7381
return tv, decls, file, line
7482
end
7583

76-
const empty_sym = Symbol("")
77-
7884
# NOTE: second argument is deprecated and is no longer used
7985
function kwarg_decl(m::Method, kwtype = nothing)
8086
mt = get_methodtable(m)
@@ -186,6 +192,15 @@ function functionloc(@nospecialize(f))
186192
return functionloc(first(mt))
187193
end
188194

195+
function sym_to_string(sym)
196+
s = String(sym)
197+
if endswith(s, "...")
198+
return string(sprint(show_sym, Symbol(s[1:end-3])), "...")
199+
else
200+
return sprint(show_sym, sym)
201+
end
202+
end
203+
189204
function show(io::IO, m::Method)
190205
tv, decls, file, line = arg_decl_parts(m)
191206
sig = unwrap_unionall(m.sig)
@@ -195,12 +210,16 @@ function show(io::IO, m::Method)
195210
return
196211
end
197212
print(io, decls[1][2], "(")
198-
join(io, String[isempty(d[2]) ? d[1] : d[1]*"::"*d[2] for d in decls[2:end]],
199-
", ", ", ")
213+
join(
214+
io,
215+
String[isempty(d[2]) ? d[1] : string(d[1], "::", d[2]) for d in decls[2:end]],
216+
", ",
217+
", ",
218+
)
200219
kwargs = kwarg_decl(m)
201220
if !isempty(kwargs)
202221
print(io, "; ")
203-
join(io, kwargs, ", ", ", ")
222+
join(io, map(sym_to_string, kwargs), ", ", ", ")
204223
end
205224
print(io, ")")
206225
show_method_params(io, tv)
@@ -341,12 +360,18 @@ function show(io::IO, ::MIME"text/html", m::Method)
341360
return
342361
end
343362
print(io, decls[1][2], "(")
344-
join(io, String[isempty(d[2]) ? d[1] : d[1]*"::<b>"*d[2]*"</b>"
345-
for d in decls[2:end]], ", ", ", ")
363+
join(
364+
io,
365+
String[
366+
isempty(d[2]) ? d[1] : string(d[1], "::<b>", d[2], "</b>") for d in decls[2:end]
367+
],
368+
", ",
369+
", ",
370+
)
346371
kwargs = kwarg_decl(m)
347372
if !isempty(kwargs)
348373
print(io, "; <i>")
349-
join(io, kwargs, ", ", ", ")
374+
join(io, map(sym_to_string, kwargs), ", ", ", ")
350375
print(io, "</i>")
351376
end
352377
print(io, ")")

base/show.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2064,7 +2064,7 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg
20642064
if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) &&
20652065
isdefined(uw.name.module, uw.name.mt.name) &&
20662066
ft == typeof(getfield(uw.name.module, uw.name.mt.name))
2067-
print(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
2067+
show_sym(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
20682068
elseif isa(ft, DataType) && ft.name === Type.body.name &&
20692069
(f = ft.parameters[1]; !isa(f, TypeVar))
20702070
uwf = unwrap_unionall(f)

test/errorshow.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ let err_str,
426426
@test startswith(sprint(show, which(Complex{Int}, Tuple{Int})),
427427
"Complex{T}(")
428428
@test startswith(sprint(show, which(getfield(Base, Symbol("@doc")), Tuple{LineNumberNode, Module, Vararg{Any}})),
429-
"@doc(__source__::LineNumberNode, __module__::Module, x...) in Core at boot.jl:")
429+
"var\"@doc\"(__source__::LineNumberNode, __module__::Module, x...) in Core at boot.jl:")
430430
@test startswith(sprint(show, which(FunctionLike(), Tuple{})),
431431
"(::$(curmod_prefix)FunctionLike)() in $curmod_str at $sp:$(method_defs_lineno + 7)")
432432
@test startswith(sprint(show, which(StructWithUnionAllMethodDefs{<:Integer}, (Any,))),

test/show.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,3 +2037,26 @@ for s in (Symbol("'"), Symbol("'⁻¹"))
20372037
@test !Base.isbinaryoperator(s)
20382038
@test Base.ispostfixoperator(s)
20392039
end
2040+
2041+
@testset "method printing with non-standard identifiers ($mime)" for mime in (
2042+
MIME("text/plain"), MIME("text/html"),
2043+
)
2044+
_show(io, x) = show(io, MIME(mime), x)
2045+
2046+
@eval var","(x) = x
2047+
@test occursin("var\",\"(x)", sprint(_show, methods(var",")))
2048+
2049+
@eval f1(var"a.b") = 3
2050+
@test occursin("f1(var\"a.b\")", sprint(_show, methods(f1)))
2051+
2052+
italic(s) = mime == MIME("text/html") ? "<i>$s</i>" : s
2053+
2054+
@eval f2(; var"123") = 5
2055+
@test occursin("f2(; $(italic("var\"123\"")))", sprint(_show, methods(f2)))
2056+
2057+
@eval f3(; var"%!"...) = 7
2058+
@test occursin("f3(; $(italic("var\"%!\"...")))", sprint(_show, methods(f3)))
2059+
2060+
@eval f4(; var"...") = 9
2061+
@test_broken occursin("f4(; $(italic("var\"...\"")))", sprint(_show, methods(f4)))
2062+
end

0 commit comments

Comments
 (0)