Skip to content

Commit

Permalink
Rename haschildren() to is_leaf()
Browse files Browse the repository at this point in the history
Unfortunately, `haschildren(x)` was a terrible name because it's not
testing the same thing as `numchildren(x) == 0`!

In our ASTs
* Leaves of the tree correspond to tokens in the source text
* Internal nodes are containers for a range of tokens or other internal
  nodes.

Occasionally we can have internal nodes which have no tokens and thus
have `numchildren(node) == 0`. These are, however, still "internal
nodes" and we have `haschildren(node) === true` for these which makes no
sense!
  • Loading branch information
c42f committed Aug 7, 2024
1 parent 38fc0fa commit f59cffd
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ end

function _to_expr(node)
file = sourcefile(node)
if !haschildren(node)
if is_leaf(node)
offset, txtbuf = _unsafe_wrap_substring(sourcetext(file))
return _leaf_to_Expr(file, txtbuf, head(node), byte_range(node) .+ offset, node)
end
Expand Down
20 changes: 10 additions & 10 deletions src/green_tree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ As implementation choices, we choose that:
struct GreenNode{Head}
head::Head
span::UInt32
args::Union{Tuple{},Vector{GreenNode{Head}}}
args::Union{Nothing,Vector{GreenNode{Head}}}
end

function GreenNode(head::Head, span::Integer, args) where {Head}
function GreenNode(head::Head, span::Integer, args=nothing) where {Head}
GreenNode{Head}(head, span, args)
end

# Accessors / predicates
haschildren(node::GreenNode) = !(node.args isa Tuple{})
children(node::GreenNode) = node.args
is_leaf(node::GreenNode) = isnothing(node.args)
children(node::GreenNode) = isnothing(node.args) ? () : node.args
span(node::GreenNode) = node.span
head(node::GreenNode) = node.head

Expand All @@ -49,19 +49,19 @@ function _show_green_node(io, node, indent, pos, str, show_trivia)
return
end
posstr = "$(lpad(pos, 6)):$(rpad(pos+span(node)-1, 6))"
is_leaf = !haschildren(node)
if is_leaf
leaf = is_leaf(node)
if leaf
line = string(posstr, indent, summary(node))
else
line = string(posstr, indent, '[', summary(node), ']')
end
if !is_trivia(node) && is_leaf
if !is_trivia(node) && leaf
line = rpad(line, 40) * ""
end
if is_error(node)
line = rpad(line, 41) * ""
end
if is_leaf && !isnothing(str)
if leaf && !isnothing(str)
line = string(rpad(line, 43), ' ', repr(str[pos:prevind(str, pos + span(node))]))
end
line = line*"\n"
Expand All @@ -70,7 +70,7 @@ function _show_green_node(io, node, indent, pos, str, show_trivia)
else
print(io, line)
end
if !is_leaf
if !leaf
new_indent = indent*" "
p = pos
for x in children(node)
Expand All @@ -91,7 +91,7 @@ end
function build_tree(::Type{GreenNode}, stream::ParseStream; kws...)
build_tree(GreenNode{SyntaxHead}, stream; kws...) do h, srcrange, cs
span = length(srcrange)
isnothing(cs) ? GreenNode(h, span, ()) :
isnothing(cs) ? GreenNode(h, span) :
GreenNode(h, span, collect(GreenNode{SyntaxHead}, cs))
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/hooks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function _first_error(t::SyntaxNode)
if is_error(t)
return 0,t
end
if haschildren(t)
if !is_leaf(t)
for (i,c) in enumerate(children(t))
if is_error(c)
return i,c
Expand Down
14 changes: 7 additions & 7 deletions src/syntax_tree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ end
function _to_SyntaxNode(source::SourceFile, txtbuf::Vector{UInt8}, offset::Int,
raw::GreenNode{SyntaxHead},
position::Int, keep_parens::Bool)
if !haschildren(raw)
if is_leaf(raw)
# Here we parse the values eagerly rather than representing them as
# strings. Maybe this is good. Maybe not.
valrange = position:position + span(raw) - 1
Expand Down Expand Up @@ -106,7 +106,7 @@ function _to_SyntaxNode(source::SourceFile, txtbuf::Vector{UInt8}, offset::Int,
end
end

haschildren(node::TreeNode) = node.children !== nothing
is_leaf(node::TreeNode) = node.children === nothing
children(node::TreeNode) = (c = node.children; return c === nothing ? () : c)
numchildren(node::TreeNode) = (isnothing(node.children) ? 0 : length(node.children))

Expand Down Expand Up @@ -134,7 +134,7 @@ function _show_syntax_node(io, current_filename, node::AbstractSyntaxNode,
posstr *= "$(lpad(first_byte(node),6)):$(rpad(last_byte(node),6))"
end
val = node.val
nodestr = haschildren(node) ? "[$(untokenize(head(node)))]" :
nodestr = !is_leaf(node) ? "[$(untokenize(head(node)))]" :
isa(val, Symbol) ? string(val) : repr(val)
treestr = string(indent, nodestr)
# Add filename if it's changed from the previous node
Expand All @@ -144,7 +144,7 @@ function _show_syntax_node(io, current_filename, node::AbstractSyntaxNode,
current_filename[] = fname
end
println(io, posstr, treestr)
if haschildren(node)
if !is_leaf(node)
new_indent = indent*" "
for n in children(node)
_show_syntax_node(io, current_filename, n, new_indent, show_byte_offsets)
Expand All @@ -153,7 +153,7 @@ function _show_syntax_node(io, current_filename, node::AbstractSyntaxNode,
end

function _show_syntax_node_sexpr(io, node::AbstractSyntaxNode)
if !haschildren(node)
if is_leaf(node)
if is_error(node)
print(io, "(", untokenize(head(node)), ")")
else
Expand Down Expand Up @@ -186,7 +186,7 @@ function Base.show(io::IO, node::AbstractSyntaxNode)
end

function Base.push!(node::SN, child::SN) where SN<:AbstractSyntaxNode
if !haschildren(node)
if is_leaf(node)
error("Cannot add children")
end
args = children(node)
Expand All @@ -196,7 +196,7 @@ end
function Base.copy(node::TreeNode)
# copy the container but not the data (ie, deep copy the tree, shallow copy the data). copy(::Expr) is similar
# copy "un-parents" the top-level `node` that you're copying
newnode = typeof(node)(nothing, haschildren(node) ? typeof(node)[] : nothing, copy(node.data))
newnode = typeof(node)(nothing, is_leaf(node) ? nothing : typeof(node)[], copy(node.data))
for child in children(node)
newchild = copy(child)
newchild.parent = newnode
Expand Down
2 changes: 1 addition & 1 deletion test/green_node.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
t = parsestmt(GreenNode, "aa + b")

@test span(t) == 6
@test haschildren(t)
@test !is_leaf(t)
@test head(t) == SyntaxHead(K"call", 0x0008)
@test span.(children(t)) == [2,1,1,1,1]
@test head.(children(t)) == [
Expand Down
8 changes: 4 additions & 4 deletions test/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ using .JuliaSyntax:
SyntaxHead,
is_trivia,
sourcetext,
haschildren,
is_leaf,
children,
child,
fl_parseall,
Expand Down Expand Up @@ -276,14 +276,14 @@ function _reduce_tree(failing_subtrees, tree; exprs_equal=exprs_equal_no_linenum
if equals_flisp_parse(exprs_equal, tree)
return false
end
if !haschildren(tree)
if is_leaf(tree)
push!(failing_subtrees, tree)
return true
end
had_failing_subtrees = false
if haschildren(tree)
if !is_leaf(tree)
for child in children(tree)
if is_trivia(child) || !haschildren(child)
if is_trivia(child) || is_leaf(child)
continue
end
had_failing_subtrees |= _reduce_tree(failing_subtrees, child; exprs_equal=exprs_equal)
Expand Down

0 comments on commit f59cffd

Please sign in to comment.