Skip to content

Commit 6532515

Browse files
authored
Show leaf Kinds when printing syntax trees (#489)
The leaf kind is fairly critical information - this change ensures it's shown by default when printing syntax trees. Conversely, the byte offset and line/column is generally not very useful, so hide this by default.
1 parent b92fc5e commit 6532515

File tree

2 files changed

+67
-44
lines changed

2 files changed

+67
-44
lines changed

src/syntax_tree.jl

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,61 +139,70 @@ function leaf_string(ex)
139139
end
140140

141141
function _show_syntax_node(io, current_filename, node::AbstractSyntaxNode,
142-
indent, show_byte_offsets)
143-
fname = filename(node)
142+
indent, show_location, show_kind)
144143
line, col = source_location(node)
145-
posstr = "$(lpad(line, 4)):$(rpad(col,3))"
146-
if show_byte_offsets
147-
posstr *= "$(lpad(first_byte(node),6)):$(rpad(last_byte(node),6))"
144+
if show_location
145+
fname = filename(node)
146+
# Add filename if it's changed from the previous node
147+
if fname != current_filename[]
148+
println(io, indent, " -file- │ ", repr(fname))
149+
current_filename[] = fname
150+
end
151+
posstr = "$(lpad(line, 4)):$(rpad(col,3))$(lpad(first_byte(node),6)):$(rpad(last_byte(node),6))"
152+
else
153+
posstr = ""
148154
end
149155
val = node.val
150156
nodestr = is_leaf(node) ? leaf_string(node) : "[$(untokenize(head(node)))]"
151157
treestr = string(indent, nodestr)
152-
# Add filename if it's changed from the previous node
153-
if fname != current_filename[]
154-
#println(io, "# ", fname)
155-
treestr = string(rpad(treestr, 40), "$fname")
156-
current_filename[] = fname
158+
if show_kind && is_leaf(node)
159+
treestr = rpad(treestr, 40)*" :: "*string(kind(node))
157160
end
158161
println(io, posstr, treestr)
159162
if !is_leaf(node)
160163
new_indent = indent*" "
161164
for n in children(node)
162-
_show_syntax_node(io, current_filename, n, new_indent, show_byte_offsets)
165+
_show_syntax_node(io, current_filename, n, new_indent, show_location, show_kind)
163166
end
164167
end
165168
end
166169

167-
function _show_syntax_node_sexpr(io, node::AbstractSyntaxNode)
170+
function _show_syntax_node_sexpr(io, node::AbstractSyntaxNode, show_kind)
168171
if is_leaf(node)
169172
if is_error(node)
170173
print(io, "(", untokenize(head(node)), ")")
171174
else
172175
print(io, leaf_string(node))
176+
if show_kind
177+
print(io, "::", kind(node))
178+
end
173179
end
174180
else
175181
print(io, "(", untokenize(head(node)))
176182
first = true
177183
for n in children(node)
178184
print(io, ' ')
179-
_show_syntax_node_sexpr(io, n)
185+
_show_syntax_node_sexpr(io, n, show_kind)
180186
first = false
181187
end
182188
print(io, ')')
183189
end
184190
end
185191

186-
function Base.show(io::IO, ::MIME"text/plain", node::AbstractSyntaxNode; show_byte_offsets=false)
187-
println(io, "line:col│$(show_byte_offsets ? " byte_range │" : "") tree │ file_name")
188-
_show_syntax_node(io, Ref(""), node, "", show_byte_offsets)
192+
function Base.show(io::IO, ::MIME"text/plain", node::AbstractSyntaxNode; show_location=false, show_kind=true)
193+
println(io, "SyntaxNode:")
194+
if show_location
195+
println(io, "line:col│ byte_range │ tree")
196+
end
197+
_show_syntax_node(io, Ref(""), node, "", show_location, show_kind)
189198
end
190199

191-
function Base.show(io::IO, ::MIME"text/x.sexpression", node::AbstractSyntaxNode)
192-
_show_syntax_node_sexpr(io, node)
200+
function Base.show(io::IO, ::MIME"text/x.sexpression", node::AbstractSyntaxNode; show_kind=false)
201+
_show_syntax_node_sexpr(io, node, show_kind)
193202
end
194203

195204
function Base.show(io::IO, node::AbstractSyntaxNode)
196-
_show_syntax_node_sexpr(io, node)
205+
_show_syntax_node_sexpr(io, node, false)
197206
end
198207

199208
function Base.push!(node::SN, child::SN) where SN<:AbstractSyntaxNode

test/syntax_tree.jl

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@
2222
# as `lastindex(t, 2)` isn't well defined
2323

2424
@test sprint(show, t) == "(call-i (call-i a * b) + c)"
25-
str = sprint(show, MIME("text/plain"), t)
26-
# These tests are deliberately quite relaxed to avoid being too specific about display style
27-
@test occursin("line:col", str)
28-
@test occursin("call-i", str)
25+
@test sprint(io->show(io, MIME("text/x.sexpression"), t, show_kind=true)) ==
26+
"(call-i (call-i a::Identifier *::* b::Identifier) +::+ c::Identifier)"
27+
2928
@test sprint(highlight, child(t, 1, 3)) == "a*b + c\n# ╙"
3029
@test sprint(highlight, t.source, t.raw, 1, 3) == "a*b + c\n# ╙"
3130

@@ -69,30 +68,45 @@ end
6968
@testset "SyntaxNode pretty printing" begin
7069
t = parsestmt(SyntaxNode, "f(a*b,\n c)", filename="foo.jl")
7170
@test sprint(show, MIME("text/plain"), t) == """
72-
line:col│ tree │ file_name
73-
1:1 │[call] │foo.jl
74-
1:1 │ f
75-
1:3 │ [call-i]
76-
1:3 │ a
77-
1:4 │ *
78-
1:5 │ b
79-
2:3 │ c
71+
SyntaxNode:
72+
[call]
73+
f :: Identifier
74+
[call-i]
75+
a :: Identifier
76+
* :: *
77+
b :: Identifier
78+
c :: Identifier
8079
"""
81-
@test sprint(io->show(io, MIME("text/plain"), t, show_byte_offsets=true)) == """
82-
line:col│ byte_range │ tree │ file_name
83-
1:1 │ 1:11 │[call] │foo.jl
84-
1:1 │ 1:1 │ f
80+
81+
@test sprint(io->show(io, MIME("text/plain"), t, show_location=true)) == """
82+
SyntaxNode:
83+
line:col│ byte_range │ tree
84+
-file- │ "foo.jl"
85+
1:1 │ 1:11 │[call]
86+
1:1 │ 1:1 │ f :: Identifier
8587
1:3 │ 3:5 │ [call-i]
86-
1:3 │ 3:3 │ a
87-
1:4 │ 4:4 │ *
88-
1:5 │ 5:5 │ b
89-
2:3 │ 10:10 │ c
88+
1:3 │ 3:3 │ a :: Identifier
89+
1:4 │ 4:4 │ * :: *
90+
1:5 │ 5:5 │ b :: Identifier
91+
2:3 │ 10:10 │ c :: Identifier
9092
"""
9193

92-
t,_ = parsestmt(SyntaxNode, "begin a end\nbegin b end", 13)
93-
@test sprint(show, MIME("text/plain"), t) == """
94-
line:col│ tree │ file_name
95-
1:1 │[block]
96-
1:7 │ b
94+
@test sprint(io->show(io, MIME("text/plain"), t, show_kind=false)) == """
95+
SyntaxNode:
96+
[call]
97+
f
98+
[call-i]
99+
a
100+
*
101+
b
102+
c
103+
"""
104+
105+
t,_ = parsestmt(SyntaxNode, "begin a end\nbegin b end", 13, first_line=100)
106+
@test sprint(io->show(io, MIME("text/plain"), t, show_location=true)) == """
107+
SyntaxNode:
108+
line:col│ byte_range │ tree
109+
100:1 │ 13:23 │[block]
110+
100:7 │ 19:19 │ b :: Identifier
97111
"""
98112
end

0 commit comments

Comments
 (0)