syntax_lang/tree.rs
1//! The tree itself: [`Node`] interior nodes, [`Element`] children, and the
2//! iterative traversals over them.
3
4use alloc::vec;
5use alloc::vec::Vec;
6use core::slice;
7
8use span_lang::Span;
9use token_lang::Token;
10
11/// One child of a [`Node`]: either a nested node or a leaf token.
12///
13/// A concrete syntax tree alternates between the two — a node groups a run of
14/// children under a kind, and a [`Token`] is a leaf carrying a classified span of
15/// source. Trivia (whitespace, comments) is not special: it rides as an ordinary
16/// leaf token, which is what makes the tree lossless.
17///
18/// # Examples
19///
20/// ```
21/// use syntax_lang::{Element, Node, Span, Token};
22///
23/// let leaf: Element<&str> = Element::Token(Token::new("ident", Span::new(0, 3)));
24/// assert!(leaf.is_token());
25/// assert_eq!(leaf.kind(), &"ident");
26/// assert_eq!(leaf.span(), Span::new(0, 3));
27///
28/// let group = Element::Node(Node::new("expr", vec![leaf]));
29/// assert!(group.is_node());
30/// assert_eq!(group.span(), Span::new(0, 3));
31/// ```
32#[derive(Clone, Debug, PartialEq, Eq)]
33pub enum Element<K> {
34 /// A nested interior node.
35 Node(Node<K>),
36 /// A leaf token: a classified span of source.
37 Token(Token<K>),
38}
39
40impl<K> Element<K> {
41 /// The span of source this child covers — the node's covering span or the
42 /// token's own span.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// use syntax_lang::{Element, Span, Token};
48 ///
49 /// let e = Element::Token(Token::new('x', Span::new(4, 5)));
50 /// assert_eq!(e.span(), Span::new(4, 5));
51 /// ```
52 #[inline]
53 #[must_use]
54 pub fn span(&self) -> Span {
55 match self {
56 Element::Node(node) => node.span(),
57 Element::Token(token) => token.span(),
58 }
59 }
60
61 /// Borrows the kind of this child — the node's kind or the token's kind.
62 ///
63 /// Node kinds and token kinds share one type `K` (the rowan model), so a
64 /// caller can read a child's kind without first knowing whether it is a node
65 /// or a leaf.
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// use syntax_lang::{Element, Span, Token};
71 ///
72 /// let e = Element::Token(Token::new("plus", Span::new(1, 2)));
73 /// assert_eq!(e.kind(), &"plus");
74 /// ```
75 #[inline]
76 #[must_use]
77 pub fn kind(&self) -> &K {
78 match self {
79 Element::Node(node) => node.kind(),
80 Element::Token(token) => token.kind(),
81 }
82 }
83
84 /// Returns the nested node if this child is one, otherwise `None`.
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// use syntax_lang::{Element, Node, Span, Token};
90 ///
91 /// let node = Element::Node(Node::new("n", vec![Element::Token(Token::new("t", Span::new(0, 1)))]));
92 /// assert!(node.as_node().is_some());
93 /// assert!(node.as_token().is_none());
94 /// ```
95 #[inline]
96 #[must_use]
97 pub fn as_node(&self) -> Option<&Node<K>> {
98 match self {
99 Element::Node(node) => Some(node),
100 Element::Token(_) => None,
101 }
102 }
103
104 /// Returns the leaf token if this child is one, otherwise `None`.
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// use syntax_lang::{Element, Span, Token};
110 ///
111 /// let e = Element::Token(Token::new("t", Span::new(0, 1)));
112 /// assert_eq!(e.as_token().map(|t| *t.kind()), Some("t"));
113 /// ```
114 #[inline]
115 #[must_use]
116 pub fn as_token(&self) -> Option<&Token<K>> {
117 match self {
118 Element::Token(token) => Some(token),
119 Element::Node(_) => None,
120 }
121 }
122
123 /// Whether this child is a nested node.
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use syntax_lang::{Element, Span, Token};
129 ///
130 /// assert!(!Element::Token(Token::new(0u8, Span::new(0, 1))).is_node());
131 /// ```
132 #[inline]
133 #[must_use]
134 pub fn is_node(&self) -> bool {
135 matches!(self, Element::Node(_))
136 }
137
138 /// Whether this child is a leaf token.
139 ///
140 /// # Examples
141 ///
142 /// ```
143 /// use syntax_lang::{Element, Span, Token};
144 ///
145 /// assert!(Element::Token(Token::new(0u8, Span::new(0, 1))).is_token());
146 /// ```
147 #[inline]
148 #[must_use]
149 pub fn is_token(&self) -> bool {
150 matches!(self, Element::Token(_))
151 }
152}
153
154/// An interior node of a concrete syntax tree: a [`kind`](Node::kind), the
155/// [`span`](Node::span) of source it covers, and its ordered [`children`](Node::children).
156///
157/// A node owns its children directly, so a whole tree is a single owned value with
158/// no arena or handle bookkeeping. The children are in source order; a node's
159/// covering span is the union of its children's spans, computed once when the node
160/// is built. Because trivia rides as ordinary leaf tokens, the tree is *lossless*:
161/// slicing the original source by a node's span — or concatenating its
162/// [`tokens`](Node::tokens) — reproduces exactly the source that node came from.
163///
164/// The kind type `K` is shared by nodes and tokens alike (an `enum` a language
165/// defines with both composite and lexical variants), following the model
166/// [`token_lang`](token_lang) establishes. The node type itself is generic over any
167/// `K` and needs no trait bound.
168///
169/// # Stack safety
170///
171/// Traversal ([`tokens`](Node::tokens), [`descendants`](Node::descendants)) and
172/// teardown (`Drop`) are *iterative*: a tree tens of thousands of levels deep is
173/// walked and freed without recursing on the call stack. `Clone`, `PartialEq`, and
174/// `Debug` recurse with tree depth and so suit trees of realistic source depth.
175///
176/// # Examples
177///
178/// ```
179/// use syntax_lang::{Element, Node, Span, Token};
180///
181/// // `1 + 2` as a tiny expression node with three leaf tokens.
182/// let node = Node::new(
183/// "add",
184/// vec![
185/// Element::Token(Token::new("num", Span::new(0, 1))),
186/// Element::Token(Token::new("plus", Span::new(2, 3))),
187/// Element::Token(Token::new("num", Span::new(4, 5))),
188/// ],
189/// );
190///
191/// assert_eq!(node.kind(), &"add");
192/// assert_eq!(node.span(), Span::new(0, 5));
193/// assert_eq!(node.text("1 + 2"), Some("1 + 2"));
194/// assert_eq!(node.children().count(), 3);
195/// ```
196#[derive(Clone, Debug, PartialEq, Eq)]
197pub struct Node<K> {
198 kind: K,
199 span: Span,
200 children: Vec<Element<K>>,
201}
202
203impl<K> Node<K> {
204 /// Builds a node from a kind and its ordered children, computing the covering
205 /// span as the union of the children's spans.
206 ///
207 /// Children are taken in source order. A node with no children reports an empty
208 /// span at offset `0`; build such nodes through a [`Builder`](crate::Builder)
209 /// instead, which places an empty node at the current stream position.
210 ///
211 /// # Examples
212 ///
213 /// ```
214 /// use syntax_lang::{Element, Node, Span, Token};
215 ///
216 /// let n = Node::new(
217 /// "paren",
218 /// vec![
219 /// Element::Token(Token::new("(", Span::new(0, 1))),
220 /// Element::Token(Token::new(")", Span::new(1, 2))),
221 /// ],
222 /// );
223 /// assert_eq!(n.span(), Span::new(0, 2));
224 /// ```
225 #[must_use]
226 pub fn new(kind: K, children: Vec<Element<K>>) -> Self {
227 let span = cover(&children, Span::empty(0));
228 Self {
229 kind,
230 span,
231 children,
232 }
233 }
234
235 /// Builds a node with a caller-supplied span, used by the
236 /// [`Builder`](crate::Builder) to place an empty node at the current stream
237 /// cursor rather than at offset `0`. For a node with children the span still
238 /// equals the union of their spans; this only differs for the childless case.
239 #[must_use]
240 pub(crate) fn with_span(kind: K, children: Vec<Element<K>>, empty: Span) -> Self {
241 let span = cover(&children, empty);
242 Self {
243 kind,
244 span,
245 children,
246 }
247 }
248
249 /// Borrows this node's kind.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// use syntax_lang::Node;
255 ///
256 /// let n: Node<&str> = Node::new("root", vec![]);
257 /// assert_eq!(n.kind(), &"root");
258 /// ```
259 #[inline]
260 #[must_use]
261 pub fn kind(&self) -> &K {
262 &self.kind
263 }
264
265 /// Returns the span of source this node covers: the union of its children's
266 /// spans, or an empty span if it has none.
267 ///
268 /// # Examples
269 ///
270 /// ```
271 /// use syntax_lang::{Element, Node, Span, Token};
272 ///
273 /// let n = Node::new("n", vec![Element::Token(Token::new("t", Span::new(3, 8)))]);
274 /// assert_eq!(n.span(), Span::new(3, 8));
275 /// ```
276 #[inline]
277 #[must_use]
278 pub fn span(&self) -> Span {
279 self.span
280 }
281
282 /// Whether this node has no children.
283 ///
284 /// # Examples
285 ///
286 /// ```
287 /// use syntax_lang::Node;
288 ///
289 /// let n: Node<&str> = Node::new("empty", vec![]);
290 /// assert!(n.is_empty());
291 /// ```
292 #[inline]
293 #[must_use]
294 pub fn is_empty(&self) -> bool {
295 self.children.is_empty()
296 }
297
298 /// The number of direct children (nodes and tokens) this node has.
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// use syntax_lang::{Element, Node, Span, Token};
304 ///
305 /// let n = Node::new("n", vec![Element::Token(Token::new("t", Span::new(0, 1)))]);
306 /// assert_eq!(n.len(), 1);
307 /// ```
308 #[inline]
309 #[must_use]
310 pub fn len(&self) -> usize {
311 self.children.len()
312 }
313
314 /// Iterates this node's direct children — nodes and tokens interleaved in
315 /// source order.
316 ///
317 /// # Examples
318 ///
319 /// ```
320 /// use syntax_lang::{Element, Node, Span, Token};
321 ///
322 /// let n = Node::new(
323 /// "n",
324 /// vec![
325 /// Element::Token(Token::new("a", Span::new(0, 1))),
326 /// Element::Node(Node::new("inner", vec![Element::Token(Token::new("b", Span::new(1, 2)))])),
327 /// ],
328 /// );
329 /// let kinds: Vec<_> = n.children().map(Element::kind).copied().collect();
330 /// assert_eq!(kinds, ["a", "inner"]);
331 /// ```
332 #[inline]
333 pub fn children(&self) -> impl Iterator<Item = &Element<K>> {
334 self.children.iter()
335 }
336
337 /// Iterates only the direct children that are nested nodes, skipping leaf
338 /// tokens.
339 ///
340 /// # Examples
341 ///
342 /// ```
343 /// use syntax_lang::{Element, Node, Span, Token};
344 ///
345 /// let n = Node::new(
346 /// "n",
347 /// vec![
348 /// Element::Token(Token::new("a", Span::new(0, 1))),
349 /// Element::Node(Node::new("inner", vec![Element::Token(Token::new("b", Span::new(1, 2)))])),
350 /// ],
351 /// );
352 /// assert_eq!(n.child_nodes().count(), 1);
353 /// ```
354 #[inline]
355 pub fn child_nodes(&self) -> impl Iterator<Item = &Node<K>> {
356 self.children.iter().filter_map(Element::as_node)
357 }
358
359 /// Iterates only the direct children that are leaf tokens, skipping nested
360 /// nodes.
361 ///
362 /// # Examples
363 ///
364 /// ```
365 /// use syntax_lang::{Element, Node, Span, Token};
366 ///
367 /// let n = Node::new(
368 /// "n",
369 /// vec![
370 /// Element::Token(Token::new("a", Span::new(0, 1))),
371 /// Element::Node(Node::new("inner", vec![Element::Token(Token::new("b", Span::new(1, 2)))])),
372 /// ],
373 /// );
374 /// let direct: Vec<_> = n.child_tokens().map(|t| *t.kind()).collect();
375 /// assert_eq!(direct, ["a"]);
376 /// ```
377 #[inline]
378 pub fn child_tokens(&self) -> impl Iterator<Item = &Token<K>> {
379 self.children.iter().filter_map(Element::as_token)
380 }
381
382 /// Iterates this node and every node beneath it in pre-order (a parent before
383 /// its descendants, children in source order).
384 ///
385 /// The walk is iterative — its work stack lives on the heap — so a tree of any
386 /// depth is traversed without overflowing the call stack.
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// use syntax_lang::{Element, Node, Span, Token};
392 ///
393 /// let tree = Node::new(
394 /// "root",
395 /// vec![Element::Node(Node::new(
396 /// "inner",
397 /// vec![Element::Token(Token::new("t", Span::new(0, 1)))],
398 /// ))],
399 /// );
400 /// let kinds: Vec<_> = tree.descendants().map(Node::kind).copied().collect();
401 /// assert_eq!(kinds, ["root", "inner"]);
402 /// ```
403 #[inline]
404 pub fn descendants(&self) -> impl Iterator<Item = &Node<K>> {
405 Descendants {
406 root: Some(self),
407 stack: Vec::new(),
408 }
409 }
410
411 /// Iterates every leaf token in the tree in source order — the lossless token
412 /// stream, trivia included.
413 ///
414 /// Concatenating these tokens' source slices reproduces the node's source
415 /// exactly; the walk is iterative and safe on any depth.
416 ///
417 /// # Examples
418 ///
419 /// ```
420 /// use syntax_lang::{Element, Node, Span, Token};
421 ///
422 /// let tree = Node::new(
423 /// "root",
424 /// vec![Element::Node(Node::new(
425 /// "inner",
426 /// vec![
427 /// Element::Token(Token::new("a", Span::new(0, 1))),
428 /// Element::Token(Token::new("b", Span::new(1, 2))),
429 /// ],
430 /// ))],
431 /// );
432 /// let leaves: Vec<_> = tree.tokens().map(|t| *t.kind()).collect();
433 /// assert_eq!(leaves, ["a", "b"]);
434 /// ```
435 #[inline]
436 pub fn tokens(&self) -> impl Iterator<Item = &Token<K>> {
437 Tokens {
438 stack: vec![self.children.iter()],
439 }
440 }
441
442 /// Slices `source` by this node's covering span, returning the exact text the
443 /// node came from, or `None` if the span lies outside `source`.
444 ///
445 /// This is zero-copy: it borrows a sub-slice of `source` rather than allocating.
446 /// Pass the same source the tree was built from; the `None` case guards against
447 /// a mismatched or truncated string rather than panicking.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// use syntax_lang::{Element, Node, Span, Token};
453 ///
454 /// let n = Node::new(
455 /// "call",
456 /// vec![
457 /// Element::Token(Token::new("id", Span::new(0, 1))),
458 /// Element::Token(Token::new("(", Span::new(1, 2))),
459 /// Element::Token(Token::new(")", Span::new(2, 3))),
460 /// ],
461 /// );
462 /// assert_eq!(n.text("f()"), Some("f()"));
463 /// assert_eq!(n.text("f"), None); // span runs past the string
464 /// ```
465 #[inline]
466 #[must_use]
467 pub fn text<'s>(&self, source: &'s str) -> Option<&'s str> {
468 let start = self.span.start().to_usize();
469 let end = self.span.end().to_usize();
470 source.get(start..end)
471 }
472}
473
474impl<K> Drop for Node<K> {
475 /// Frees the tree without recursion.
476 ///
477 /// The default drop glue would recurse once per level of nesting, overflowing
478 /// the stack on a pathologically deep tree (a long chain of single-child
479 /// nodes). This moves every descendant node onto an explicit heap worklist and
480 /// drops them there, so teardown depth is bounded by heap, not stack.
481 fn drop(&mut self) {
482 // Fast path: a leaf-only node (or already-drained node) has no nested nodes
483 // to recurse into, so the default glue is already non-recursive.
484 if self.children.iter().all(Element::is_token) {
485 return;
486 }
487 let mut stack: Vec<Node<K>> = Vec::new();
488 drain_nodes(&mut self.children, &mut stack);
489 while let Some(mut node) = stack.pop() {
490 // Detaching `node`'s children before it drops means its own drop glue
491 // runs against an empty vector — no further recursion.
492 drain_nodes(&mut node.children, &mut stack);
493 }
494 }
495}
496
497/// Moves every nested node out of `children` onto `stack`; leaf tokens drop in
498/// place as the source vector is cleared.
499fn drain_nodes<K>(children: &mut Vec<Element<K>>, stack: &mut Vec<Node<K>>) {
500 for element in children.drain(..) {
501 if let Element::Node(node) = element {
502 stack.push(node);
503 }
504 }
505}
506
507/// Folds the children's spans into their covering span, falling back to `empty`
508/// for a childless node.
509fn cover<K>(children: &[Element<K>], empty: Span) -> Span {
510 let mut iter = children.iter();
511 match iter.next() {
512 None => empty,
513 Some(first) => iter.fold(first.span(), |acc, child| acc.merge(child.span())),
514 }
515}
516
517/// Pre-order iterator over a node and its descendants. Returned by
518/// [`Node::descendants`]; iterative, so it never recurses on the call stack.
519struct Descendants<'a, K> {
520 root: Option<&'a Node<K>>,
521 stack: Vec<slice::Iter<'a, Element<K>>>,
522}
523
524impl<'a, K> Iterator for Descendants<'a, K> {
525 type Item = &'a Node<K>;
526
527 fn next(&mut self) -> Option<Self::Item> {
528 if let Some(root) = self.root.take() {
529 self.stack.push(root.children.iter());
530 return Some(root);
531 }
532 loop {
533 let top = self.stack.last_mut()?;
534 match top.next() {
535 None => {
536 let _ = self.stack.pop();
537 }
538 Some(Element::Node(node)) => {
539 self.stack.push(node.children.iter());
540 return Some(node);
541 }
542 Some(Element::Token(_)) => {}
543 }
544 }
545 }
546}
547
548/// Source-order iterator over every leaf token in a tree. Returned by
549/// [`Node::tokens`]; iterative, so it never recurses on the call stack.
550struct Tokens<'a, K> {
551 stack: Vec<slice::Iter<'a, Element<K>>>,
552}
553
554impl<'a, K> Iterator for Tokens<'a, K> {
555 type Item = &'a Token<K>;
556
557 fn next(&mut self) -> Option<Self::Item> {
558 loop {
559 let top = self.stack.last_mut()?;
560 match top.next() {
561 None => {
562 let _ = self.stack.pop();
563 }
564 Some(Element::Node(node)) => {
565 self.stack.push(node.children.iter());
566 }
567 Some(Element::Token(token)) => return Some(token),
568 }
569 }
570 }
571}
572
573#[cfg(test)]
574mod tests {
575 use super::*;
576 use alloc::vec;
577
578 fn tok(kind: &'static str, lo: u32, hi: u32) -> Element<&'static str> {
579 Element::Token(Token::new(kind, Span::new(lo, hi)))
580 }
581
582 #[test]
583 fn test_new_covers_children_span() {
584 let n = Node::new("n", vec![tok("a", 2, 4), tok("b", 4, 9)]);
585 assert_eq!(n.span(), Span::new(2, 9));
586 }
587
588 #[test]
589 fn test_new_empty_node_has_empty_span() {
590 let n: Node<&str> = Node::new("n", vec![]);
591 assert_eq!(n.span(), Span::empty(0));
592 assert!(n.is_empty());
593 assert_eq!(n.len(), 0);
594 }
595
596 #[test]
597 fn test_children_iterators_split_nodes_and_tokens() {
598 let inner = Element::Node(Node::new("inner", vec![tok("x", 1, 2)]));
599 let n = Node::new("n", vec![tok("a", 0, 1), inner]);
600 assert_eq!(n.children().count(), 2);
601 assert_eq!(n.child_nodes().count(), 1);
602 assert_eq!(
603 n.child_tokens().map(|t| *t.kind()).collect::<Vec<_>>(),
604 ["a"]
605 );
606 }
607
608 #[test]
609 fn test_descendants_preorder() {
610 let tree = Node::new(
611 "root",
612 vec![
613 Element::Node(Node::new("l", vec![tok("a", 0, 1)])),
614 Element::Node(Node::new("r", vec![tok("b", 1, 2)])),
615 ],
616 );
617 let kinds: Vec<_> = tree.descendants().map(Node::kind).copied().collect();
618 assert_eq!(kinds, ["root", "l", "r"]);
619 }
620
621 #[test]
622 fn test_tokens_source_order_includes_all_leaves() {
623 let tree = Node::new(
624 "root",
625 vec![
626 tok("a", 0, 1),
627 Element::Node(Node::new("inner", vec![tok("b", 1, 2), tok("c", 2, 3)])),
628 tok("d", 3, 4),
629 ],
630 );
631 let leaves: Vec<_> = tree.tokens().map(|t| *t.kind()).collect();
632 assert_eq!(leaves, ["a", "b", "c", "d"]);
633 }
634
635 #[test]
636 fn test_text_slices_source_and_rejects_out_of_bounds() {
637 let n = Node::new("n", vec![tok("a", 0, 2), tok("b", 2, 5)]);
638 assert_eq!(n.text("hello"), Some("hello"));
639 assert_eq!(n.text("hi"), None);
640 }
641
642 #[test]
643 fn test_element_accessors() {
644 let e = tok("a", 0, 1);
645 assert!(e.is_token());
646 assert!(!e.is_node());
647 assert_eq!(e.kind(), &"a");
648 assert_eq!(e.span(), Span::new(0, 1));
649 assert!(e.as_token().is_some());
650 assert!(e.as_node().is_none());
651 }
652
653 #[test]
654 fn test_deep_tree_drops_without_stack_overflow() {
655 // A 200_000-level left chain: recursive drop glue would overflow here.
656 let mut node = Node::new("leaf", vec![tok("t", 0, 1)]);
657 for _ in 0..200_000 {
658 node = Node::new("link", vec![Element::Node(node)]);
659 }
660 drop(node);
661 }
662
663 #[test]
664 fn test_deep_tree_tokens_and_descendants_are_iterative() {
665 let mut node = Node::new("leaf", vec![tok("t", 0, 1)]);
666 for _ in 0..100_000 {
667 node = Node::new("link", vec![Element::Node(node)]);
668 }
669 assert_eq!(node.tokens().count(), 1);
670 assert_eq!(node.descendants().count(), 100_001);
671 }
672}