Skip to content

Commit 95f792b

Browse files
committed
Show leaf Kinds when printing syntax trees
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 abf099e commit 95f792b

File tree

2 files changed

+68
-45
lines changed

2 files changed

+68
-45
lines changed

src/syntax_tree.jl

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,63 +126,72 @@ byte_range(node::AbstractSyntaxNode) = node.position:(node.position + span(node)
126126
sourcefile(node::AbstractSyntaxNode) = node.source
127127

128128
function _show_syntax_node(io, current_filename, node::AbstractSyntaxNode,
129-
indent, show_byte_offsets)
130-
fname = filename(node)
129+
indent, show_location, show_kind)
131130
line, col = source_location(node)
132-
posstr = "$(lpad(line, 4)):$(rpad(col,3))"
133-
if show_byte_offsets
134-
posstr *= "$(lpad(first_byte(node),6)):$(rpad(last_byte(node),6))"
131+
if show_location
132+
fname = filename(node)
133+
# Add filename if it's changed from the previous node
134+
if fname != current_filename[]
135+
println(io, indent, " -file- │ ", repr(fname))
136+
current_filename[] = fname
137+
end
138+
posstr = "$(lpad(line, 4)):$(rpad(col,3))$(lpad(first_byte(node),6)):$(rpad(last_byte(node),6))"
139+
else
140+
posstr = ""
135141
end
136142
val = node.val
137143
nodestr = !is_leaf(node) ? "[$(untokenize(head(node)))]" :
138-
isa(val, Symbol) ? string(val) : repr(val)
144+
(isa(val, Symbol) ? string(val) : repr(val))
139145
treestr = string(indent, nodestr)
140-
# Add filename if it's changed from the previous node
141-
if fname != current_filename[]
142-
#println(io, "# ", fname)
143-
treestr = string(rpad(treestr, 40), "$fname")
144-
current_filename[] = fname
146+
if show_kind && is_leaf(node)
147+
treestr = rpad(treestr, 40)*" :: "*string(kind(node))
145148
end
146149
println(io, posstr, treestr)
147150
if !is_leaf(node)
148151
new_indent = indent*" "
149152
for n in children(node)
150-
_show_syntax_node(io, current_filename, n, new_indent, show_byte_offsets)
153+
_show_syntax_node(io, current_filename, n, new_indent, show_location, show_kind)
151154
end
152155
end
153156
end
154157

155-
function _show_syntax_node_sexpr(io, node::AbstractSyntaxNode)
158+
function _show_syntax_node_sexpr(io, node::AbstractSyntaxNode, show_kind)
156159
if is_leaf(node)
157160
if is_error(node)
158161
print(io, "(", untokenize(head(node)), ")")
159162
else
160163
val = node.val
161164
print(io, val isa Symbol ? string(val) : repr(val))
165+
if show_kind
166+
print(io, "::", kind(node))
167+
end
162168
end
163169
else
164170
print(io, "(", untokenize(head(node)))
165171
first = true
166172
for n in children(node)
167173
print(io, ' ')
168-
_show_syntax_node_sexpr(io, n)
174+
_show_syntax_node_sexpr(io, n, show_kind)
169175
first = false
170176
end
171177
print(io, ')')
172178
end
173179
end
174180

175-
function Base.show(io::IO, ::MIME"text/plain", node::AbstractSyntaxNode; show_byte_offsets=false)
176-
println(io, "line:col│$(show_byte_offsets ? " byte_range │" : "") tree │ file_name")
177-
_show_syntax_node(io, Ref(""), node, "", show_byte_offsets)
181+
function Base.show(io::IO, ::MIME"text/plain", node::AbstractSyntaxNode; show_location=false, show_kind=true)
182+
println(io, "SyntaxNode:")
183+
if show_location
184+
println(io, "line:col│ byte_range │ tree")
185+
end
186+
_show_syntax_node(io, Ref(""), node, "", show_location, show_kind)
178187
end
179188

180-
function Base.show(io::IO, ::MIME"text/x.sexpression", node::AbstractSyntaxNode)
181-
_show_syntax_node_sexpr(io, node)
189+
function Base.show(io::IO, ::MIME"text/x.sexpression", node::AbstractSyntaxNode; show_kind=false)
190+
_show_syntax_node_sexpr(io, node, show_kind)
182191
end
183192

184193
function Base.show(io::IO, node::AbstractSyntaxNode)
185-
_show_syntax_node_sexpr(io, node)
194+
_show_syntax_node_sexpr(io, node, false)
186195
end
187196

188197
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)