Skip to main content

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}