@@ -106,10 +106,36 @@ function _to_SyntaxNode(source::SourceFile, txtbuf::Vector{UInt8}, offset::Int,
106106 end
107107end
108108
109+ """
110+ is_leaf(node)
111+
112+ Determine whether the node is a leaf of the tree. In our trees a "leaf"
113+ corresponds to a single token in the source text.
114+ """
109115is_leaf (node:: TreeNode ) = node. children === nothing
110- children (node:: TreeNode ) = (c = node. children; return c === nothing ? () : c)
116+
117+ """
118+ children(node)
119+
120+ Return an iterable list of children for the node. For leaves, return `nothing`.
121+ """
122+ children (node:: TreeNode ) = node. children
123+
124+ """
125+ numchildren(node)
126+
127+ Return `length(children(node))` but possibly computed in a more efficient way.
128+ """
111129numchildren (node:: TreeNode ) = (isnothing (node. children) ? 0 : length (node. children))
112130
131+ Base. getindex (node:: AbstractSyntaxNode , i:: Int ) = children (node)[i]
132+ Base. getindex (node:: AbstractSyntaxNode , rng:: UnitRange ) = view (children (node), rng)
133+ Base. firstindex (node:: AbstractSyntaxNode ) = 1
134+ Base. lastindex (node:: AbstractSyntaxNode ) = length (children (node))
135+
136+ function Base. setindex! (node:: SN , x:: SN , i:: Int ) where {SN<: AbstractSyntaxNode }
137+ children (node)[i] = x
138+ end
113139
114140"""
115141 head(x)
@@ -217,10 +243,12 @@ function Base.copy(node::TreeNode)
217243 # copy the container but not the data (ie, deep copy the tree, shallow copy the data). copy(::Expr) is similar
218244 # copy "un-parents" the top-level `node` that you're copying
219245 newnode = typeof (node)(nothing , is_leaf (node) ? nothing : typeof (node)[], copy (node. data))
220- for child in children (node)
221- newchild = copy (child)
222- newchild. parent = newnode
223- push! (newnode, newchild)
246+ if ! is_leaf (node)
247+ for child in children (node)
248+ newchild = copy (child)
249+ newchild. parent = newnode
250+ push! (newnode, newchild)
251+ end
224252 end
225253 return newnode
226254end
@@ -235,71 +263,4 @@ function build_tree(::Type{SyntaxNode}, stream::ParseStream;
235263 SyntaxNode (source, green_tree, position= first_byte (stream), keep_parens= keep_parens)
236264end
237265
238- # -------------------------------------------------------------------------------
239- # Tree utilities
240-
241- """
242- child(node, i1, i2, ...)
243-
244- Get child at a tree path. If indexing accessed children, it would be
245- `node[i1][i2][...]`
246- """
247- function child (node, path:: Integer... )
248- n = node
249- for index in path
250- n = children (n)[index]
251- end
252- return n
253- end
254-
255- function setchild! (node:: SyntaxNode , path, x)
256- n1 = child (node, path[1 : end - 1 ]. .. )
257- n1. children[path[end ]] = x
258- end
259-
260- # We can overload multidimensional Base.getindex / Base.setindex! for node
261- # types.
262- #
263- # The justification for this is to view a tree as a multidimensional ragged
264- # array, where descending depthwise into the tree corresponds to dimensions of
265- # the array.
266- #
267- # However... this analogy is only good for complete trees at a given depth (=
268- # dimension). But the syntax is oh-so-handy!
269- function Base. getindex (node:: Union{SyntaxNode,GreenNode} , path:: Int... )
270- child (node, path... )
271- end
272- function Base. lastindex (node:: Union{SyntaxNode,GreenNode} )
273- length (children (node))
274- end
275-
276- function Base. setindex! (node:: SyntaxNode , x:: SyntaxNode , path:: Int... )
277- setchild! (node, path, x)
278- end
279-
280- """
281- Get absolute position and span of the child of `node` at the given tree `path`.
282- """
283- function child_position_span (node:: GreenNode , path:: Int... )
284- n = node
285- p = 1
286- for index in path
287- cs = children (n)
288- for i = 1 : index- 1
289- p += span (cs[i])
290- end
291- n = cs[index]
292- end
293- return n, p, n. span
294- end
295-
296- function child_position_span (node:: SyntaxNode , path:: Int... )
297- n = child (node, path... )
298- n, n. position, span (n)
299- end
300-
301- function highlight (io:: IO , source:: SourceFile , node:: GreenNode , path:: Int... ; kws... )
302- _, p, span = child_position_span (node, path... )
303- q = p + span - 1
304- highlight (io, source, p: q; kws... )
305- end
266+ @deprecate haschildren (x) ! is_leaf (x) false
0 commit comments