|
| 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 |
0 commit comments