Skip to content

Commit 8d10edf

Browse files
committed
add text/html writemime for MethodList and Method (fix #4952)
1 parent ab372c3 commit 8d10edf

File tree

3 files changed

+135
-76
lines changed

3 files changed

+135
-76
lines changed

base/methodshow.jl

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Method and method-table pretty-printing
2+
3+
function argtype_decl(n, t) # -> (argname, argtype)
4+
if isa(n,Expr)
5+
n = n.args[1] # handle n::T in arg list
6+
end
7+
s = string(n)
8+
i = search(s,'#')
9+
if i > 0
10+
s = s[1:i-1]
11+
end
12+
if t === Any && !isempty(s)
13+
return s, ""
14+
end
15+
if t <: Vararg && t !== None && t.parameters[1] === Any
16+
return string(s, "..."), ""
17+
end
18+
return s, string(t)
19+
end
20+
21+
function arg_decl_parts(m::Method)
22+
tv = m.tvars
23+
if !isa(tv,Tuple)
24+
tv = (tv,)
25+
end
26+
li = m.func.code
27+
e = uncompressed_ast(li)
28+
argnames = e.args[1]
29+
s = symbol("?")
30+
decls = [argtype_decl(get(argnames,i,s), m.sig[i]) for i=1:length(m.sig)]
31+
return tv, decls, li.file, li.line
32+
end
33+
34+
function show(io::IO, m::Method)
35+
tv, decls, file, line = arg_decl_parts(m)
36+
if !isempty(tv)
37+
show_delim_array(io, tv, '{', ',', '}', false)
38+
end
39+
print(io, "(")
40+
print_joined(io, [isempty(d[2]) ? d[1] : d[1]*"::"*d[2] for d in decls],
41+
",", ",")
42+
print(io, ")")
43+
if line > 0
44+
print(io, " at ", file, ":", line)
45+
end
46+
end
47+
48+
function show_method_table(io::IO, mt::MethodTable, max::Int=-1, header::Bool=true)
49+
name = mt.name
50+
n = length(mt)
51+
if header
52+
m = n==1 ? "method" : "methods"
53+
print(io, "# $n $m for generic function \"$name\":")
54+
end
55+
d = mt.defs
56+
n = rest = 0
57+
while !is(d,())
58+
if max==-1 || n<max || (rest==0 && n==max && d.next === ())
59+
println(io)
60+
print(io, name)
61+
show(io, d)
62+
n += 1
63+
else
64+
rest += 1
65+
end
66+
d = d.next
67+
end
68+
if rest > 0
69+
println(io)
70+
print(io,"... $rest methods not shown (use methods($name) to see them all)")
71+
end
72+
end
73+
74+
show(io::IO, mt::MethodTable) = show_method_table(io, mt)
75+
76+
inbase(m::Module) = m == Base ? true : m == Main ? false : inbase(module_parent(m))
77+
function url(m::Method)
78+
M = m.func.code.module
79+
file = string(m.func.code.file)
80+
line = m.func.code.line
81+
line <= 0 || ismatch(r"In\[[0-9]+\]", file) && return ""
82+
if inbase(M)
83+
return "https://github.com/JuliaLang/julia/tree/$(Base.BUILD_INFO.commit)/base/$file#L$line"
84+
else
85+
try
86+
pkg = Pkg.dir(string(M))
87+
if file[1:length(pkg)] != pkg
88+
return "file://"*find_source_file(file)
89+
end
90+
u = Git.readchomp(`config remote.origin.url`, dir=pkg)
91+
u = match(Git.GITHUB_REGEX,u).captures[1]
92+
commit = Git.readchomp(`rev-parse HEAD`, dir=pkg)
93+
return "https://github.com/$u/tree/$commit/"*file[length(pkg)+2:end]*"#L$line"
94+
catch
95+
return "file://"*find_source_file(file)
96+
end
97+
end
98+
end
99+
100+
function writemime(io::IO, ::MIME"text/html", m::Method)
101+
tv, decls, file, line = arg_decl_parts(m)
102+
if !isempty(tv)
103+
print(io,"<i>")
104+
show_delim_array(io, tv, '{', ',', '}', false)
105+
print(io,"</i>")
106+
end
107+
print(io, "(")
108+
print_joined(io, [isempty(d[2]) ? d[1] : d[1]*"::<b>"*d[2]*"</b>"
109+
for d in decls], ",", ",")
110+
print(io, ")")
111+
if line > 0
112+
u = url(m)
113+
if isempty(u)
114+
print(io, " at ", file, ":", line)
115+
else
116+
print(io, """ at <a href="$u" target="_blank">""",
117+
file, ":", line, "</a>")
118+
end
119+
end
120+
end
121+
122+
function writemime(io::IO, mime::MIME"text/html", mt::MethodTable)
123+
name = mt.name
124+
n = length(mt)
125+
meths = n==1 ? "method" : "methods"
126+
print(io, "$n $meths for generic function <b>$name</b>:<ul>")
127+
d = mt.defs
128+
while !is(d,())
129+
print(io, "<li> ", name)
130+
writemime(io, mime, d)
131+
d = d.next
132+
end
133+
print(io, "</ul>")
134+
end

base/show.jl

-76
Original file line numberDiff line numberDiff line change
@@ -388,82 +388,6 @@ function show_unquoted(io::IO, ex::SymbolNode)
388388
show_expr_type(io, ex.typ)
389389
end
390390

391-
function clean_gensym(s::Symbol)
392-
s = string(s)
393-
i = search(s,'#')
394-
if i > 0
395-
return s[1:i-1]
396-
end
397-
return s
398-
end
399-
400-
function argtype_decl_string(n, t)
401-
if isa(n,Expr)
402-
n = n.args[1] # handle n::T in arg list
403-
end
404-
n = clean_gensym(n)
405-
if t === Any && !isempty(n)
406-
return n
407-
end
408-
if t <: Vararg && t !== None && t.parameters[1] === Any
409-
return string(n, "...")
410-
end
411-
return string(n, "::", t)
412-
end
413-
414-
function show(io::IO, m::Method)
415-
tv = m.tvars
416-
if !isa(tv,Tuple)
417-
tv = (tv,)
418-
end
419-
if !isempty(tv)
420-
show_delim_array(io, tv, '{', ',', '}', false)
421-
end
422-
li = m.func.code
423-
e = uncompressed_ast(li)
424-
argnames = e.args[1]
425-
if length(argnames) != length(m.sig)
426-
s = symbol("?")
427-
decls = map(argtype_decl_string, { s for i=1:length(m.sig) }, {m.sig...})
428-
else
429-
decls = map(argtype_decl_string, argnames, {m.sig...})
430-
end
431-
print(io, "(")
432-
print_joined(io, decls, ",", ",")
433-
print(io, ")")
434-
if li.line > 0
435-
print(io, " at ", li.file, ":", li.line)
436-
end
437-
end
438-
439-
function show_method_table(io::IO, mt::MethodTable, max::Int=-1, header::Bool=true)
440-
name = mt.name
441-
n = length(mt)
442-
if header
443-
m = n==1 ? "method" : "methods"
444-
print(io, "# $n $m for generic function \"$name\":")
445-
end
446-
d = mt.defs
447-
n = rest = 0
448-
while !is(d,())
449-
if max==-1 || n<max || (rest==0 && n==max && d.next === ())
450-
println(io)
451-
print(io, name)
452-
show(io, d)
453-
n += 1
454-
else
455-
rest += 1
456-
end
457-
d = d.next
458-
end
459-
if rest > 0
460-
println(io)
461-
print(io,"... $rest methods not shown (use methods($name) to see them all)")
462-
end
463-
end
464-
465-
show(io::IO, mt::MethodTable) = show_method_table(io, mt)
466-
467391
# dump & xdump - structured tree representation like R's str()
468392
# - dump is for the user-facing structure
469393
# - xdump is for the internal structure

base/sysimg.jl

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ import .Grisu.print_shortest
105105
include("printf.jl")
106106
importall .Printf
107107
include("file.jl")
108+
include("methodshow.jl")
108109

109110
# core math functions
110111
include("floatfuncs.jl")

0 commit comments

Comments
 (0)