Skip to main content

miden_rowan/
cursor.rs

1//! Implementation of the cursors -- API for convenient access to syntax trees.
2//!
3//! Functional programmers will recognize that this module implements a zipper
4//! for a purely functional (green) tree.
5//!
6//! A cursor node (`SyntaxNode`) points to a `GreenNode` and a parent
7//! `SyntaxNode`. This allows cursor to provide iteration over both ancestors
8//! and descendants, as well as a cheep access to absolute offset of the node in
9//! file.
10//!
11//! By default `SyntaxNode`s are immutable, but you can get a mutable copy of
12//! the tree by calling `clone_for_update`. Mutation is based on interior
13//! mutability and doesn't need `&mut`. You can have two `SyntaxNode`s pointing
14//! at different parts of the same tree; mutations via the first node will be
15//! reflected in the other.
16
17// Implementation notes:
18//
19// The implementation is utterly and horribly unsafe. This whole module is an
20// unsafety boundary. It is believed that the API here is, in principle, sound,
21// but the implementation might have bugs.
22//
23// The core type is `NodeData` -- a heap-allocated reference counted object,
24// which points to a green node or a green token, and to the parent `NodeData`.
25// Publicly-exposed `SyntaxNode` and `SyntaxToken` own a reference to
26// `NodeData`.
27//
28// `NodeData`s are transient, and are created and destroyed during tree
29// traversals. In general, only currently referenced nodes and their ancestors
30// are alive at any given moment.
31//
32// More specifically, `NodeData`'s ref count is equal to the number of
33// outstanding `SyntaxNode` and `SyntaxToken` plus the number of children with
34// non-zero ref counts. For example, if the user has only a single `SyntaxNode`
35// pointing somewhere in the middle of the tree, then all `NodeData` on the path
36// from that point towards the root have ref count equal to one.
37//
38// `NodeData` which doesn't have a parent (is a root) owns the corresponding
39// green node or token, and is responsible for freeing it.
40//
41// That's mostly it for the immutable subset of the API. Mutation is fun though,
42// you'll like it!
43//
44// Mutability is a run-time property of a tree of `NodeData`. The whole tree is
45// either mutable or immutable. `clone_for_update` clones the whole tree of
46// `NodeData`s, making it mutable (note that the green tree is re-used).
47//
48// If the tree is mutable, then all live `NodeData` are additionally liked to
49// each other via intrusive liked lists. Specifically, there are two pointers to
50// siblings, as well as a pointer to the first child. Note that only live nodes
51// are considered. If the user only has `SyntaxNode`s for  the first and last
52// children of some particular node, then their `NodeData` will point at each
53// other.
54//
55// The links are used to propagate mutations across the tree. Specifically, each
56// `NodeData` remembers it's index in parent. When the node is detached from or
57// attached to the tree, we need to adjust the indices of all subsequent
58// siblings. That's what makes the `for c in node.children() { c.detach() }`
59// pattern work despite the apparent iterator invalidation.
60//
61// This code is encapsulated into the sorted linked list (`sll`) module.
62//
63// The actual mutation consist of functionally "mutating" (creating a
64// structurally shared copy) the green node, and then re-spinning the tree. This
65// is a delicate process: `NodeData` point directly to the green nodes, so we
66// must make sure that those nodes don't move. Additionally, during mutation a
67// node might become or might stop being a root, so we must take care to not
68// double free / leak its green node.
69//
70// Because we can change green nodes using only shared references, handing out
71// references into green nodes in the public API would be unsound. We don't do
72// that, but we do use such references internally a lot. Additionally, for
73// tokens the underlying green token actually is immutable, so we can, and do
74// return `&str`.
75//
76// Invariants [must not leak outside of the module]:
77//    - Mutability is the property of the whole tree. Intermixing elements that
78//      differ in mutability is not allowed.
79//    - Mutability property is persistent.
80//    - References to the green elements' data are not exposed into public API
81//      when the tree is mutable.
82//    - TBD
83
84use alloc::{
85    borrow::{Cow, ToOwned},
86    boxed::Box,
87    string::ToString,
88};
89use core::{
90    cell::Cell,
91    fmt,
92    hash::{Hash, Hasher},
93    iter,
94    mem::{self, ManuallyDrop},
95    ops::Range,
96    ptr, slice,
97};
98
99use crate::{
100    Direction, GreenNode, GreenToken, NodeOrToken, SyntaxText, TextRange, TextSize, TokenAtOffset,
101    WalkEvent,
102    countme::Count,
103    green::{GreenChild, GreenElementRef, GreenNodeData, GreenTokenData, SyntaxKind},
104    sll,
105    utility_types::Delta,
106};
107
108enum Green {
109    Node { ptr: Cell<ptr::NonNull<GreenNodeData>> },
110    Token { ptr: ptr::NonNull<GreenTokenData> },
111}
112
113struct _SyntaxElement;
114
115struct NodeData {
116    _c: Count<_SyntaxElement>,
117
118    rc: Cell<u32>,
119    parent: Cell<Option<ptr::NonNull<NodeData>>>,
120    index: Cell<u32>,
121    green: Green,
122
123    /// Invariant: never changes after NodeData is created.
124    mutable: bool,
125    /// Absolute offset for immutable nodes, unused for mutable nodes.
126    offset: TextSize,
127    // The following links only have meaning when `mutable` is true.
128    first: Cell<*const NodeData>,
129    /// Invariant: never null if mutable.
130    next: Cell<*const NodeData>,
131    /// Invariant: never null if mutable.
132    prev: Cell<*const NodeData>,
133}
134
135unsafe impl sll::Elem for NodeData {
136    fn prev(&self) -> &Cell<*const Self> {
137        &self.prev
138    }
139    fn next(&self) -> &Cell<*const Self> {
140        &self.next
141    }
142    fn key(&self) -> &Cell<u32> {
143        &self.index
144    }
145}
146
147pub type SyntaxElement = NodeOrToken<SyntaxNode, SyntaxToken>;
148
149pub struct SyntaxNode {
150    ptr: ptr::NonNull<NodeData>,
151}
152
153impl Clone for SyntaxNode {
154    #[inline]
155    fn clone(&self) -> Self {
156        self.data().inc_rc();
157        SyntaxNode { ptr: self.ptr }
158    }
159}
160
161impl Drop for SyntaxNode {
162    #[inline]
163    fn drop(&mut self) {
164        if self.data().dec_rc() {
165            unsafe { free(self.ptr) }
166        }
167    }
168}
169
170#[derive(Debug)]
171pub struct SyntaxToken {
172    ptr: ptr::NonNull<NodeData>,
173}
174
175impl Clone for SyntaxToken {
176    #[inline]
177    fn clone(&self) -> Self {
178        self.data().inc_rc();
179        SyntaxToken { ptr: self.ptr }
180    }
181}
182
183impl Drop for SyntaxToken {
184    #[inline]
185    fn drop(&mut self) {
186        if self.data().dec_rc() {
187            unsafe { free(self.ptr) }
188        }
189    }
190}
191
192#[inline(never)]
193unsafe fn free(mut data: ptr::NonNull<NodeData>) {
194    unsafe {
195        loop {
196            debug_assert_eq!(data.as_ref().rc.get(), 0);
197            debug_assert!(data.as_ref().first.get().is_null());
198            let node = Box::from_raw(data.as_ptr());
199            match node.parent.take() {
200                Some(parent) => {
201                    debug_assert!(parent.as_ref().rc.get() > 0);
202                    if node.mutable {
203                        sll::unlink(&parent.as_ref().first, &*node)
204                    }
205                    if parent.as_ref().dec_rc() {
206                        data = parent;
207                    } else {
208                        break;
209                    }
210                }
211                None => {
212                    match &node.green {
213                        Green::Node { ptr } => {
214                            let _ = GreenNode::from_raw(ptr.get());
215                        }
216                        Green::Token { ptr } => {
217                            let _ = GreenToken::from_raw(*ptr);
218                        }
219                    }
220                    break;
221                }
222            }
223        }
224    }
225}
226
227impl NodeData {
228    #[inline]
229    fn new(
230        parent: Option<SyntaxNode>,
231        index: u32,
232        offset: TextSize,
233        green: Green,
234        mutable: bool,
235    ) -> ptr::NonNull<NodeData> {
236        let parent = ManuallyDrop::new(parent);
237        let res = NodeData {
238            _c: Count::new(),
239            rc: Cell::new(1),
240            parent: Cell::new(parent.as_ref().map(|it| it.ptr)),
241            index: Cell::new(index),
242            green,
243
244            mutable,
245            offset,
246            first: Cell::new(ptr::null()),
247            next: Cell::new(ptr::null()),
248            prev: Cell::new(ptr::null()),
249        };
250        unsafe {
251            if mutable {
252                let res_ptr: *const NodeData = &res;
253                match sll::init((*res_ptr).parent().map(|it| &it.first), res_ptr.as_ref().unwrap())
254                {
255                    sll::AddToSllResult::AlreadyInSll(node) => {
256                        if cfg!(debug_assertions) {
257                            assert_eq!((*node).index(), (*res_ptr).index());
258                            match ((*node).green(), (*res_ptr).green()) {
259                                (NodeOrToken::Node(lhs), NodeOrToken::Node(rhs)) => {
260                                    assert!(ptr::eq(lhs, rhs))
261                                }
262                                (NodeOrToken::Token(lhs), NodeOrToken::Token(rhs)) => {
263                                    assert!(ptr::eq(lhs, rhs))
264                                }
265                                it => {
266                                    panic!("node/token confusion: {:?}", it)
267                                }
268                            }
269                        }
270
271                        ManuallyDrop::into_inner(parent);
272                        let res = node as *mut NodeData;
273                        (*res).inc_rc();
274                        return ptr::NonNull::new_unchecked(res);
275                    }
276                    it => {
277                        let res = Box::into_raw(Box::new(res));
278                        it.add_to_sll(res);
279                        return ptr::NonNull::new_unchecked(res);
280                    }
281                }
282            }
283            ptr::NonNull::new_unchecked(Box::into_raw(Box::new(res)))
284        }
285    }
286
287    #[inline]
288    fn inc_rc(&self) {
289        let rc = match self.rc.get().checked_add(1) {
290            Some(it) => it,
291            None => panic!("reference count overflow"),
292        };
293        self.rc.set(rc)
294    }
295
296    #[inline]
297    fn dec_rc(&self) -> bool {
298        let rc = self.rc.get() - 1;
299        self.rc.set(rc);
300        rc == 0
301    }
302
303    #[inline]
304    fn key(&self) -> (ptr::NonNull<()>, TextSize) {
305        let ptr = match &self.green {
306            Green::Node { ptr } => ptr.get().cast(),
307            Green::Token { ptr } => ptr.cast(),
308        };
309        (ptr, self.offset())
310    }
311
312    #[inline]
313    fn parent_node(&self) -> Option<SyntaxNode> {
314        let parent = self.parent()?;
315        debug_assert!(matches!(parent.green, Green::Node { .. }));
316        parent.inc_rc();
317        Some(SyntaxNode { ptr: ptr::NonNull::from(parent) })
318    }
319
320    #[inline]
321    fn parent(&self) -> Option<&NodeData> {
322        self.parent.get().map(|it| unsafe { &*it.as_ptr() })
323    }
324
325    #[inline]
326    fn green(&self) -> GreenElementRef<'_> {
327        match &self.green {
328            Green::Node { ptr } => GreenElementRef::Node(unsafe { &*ptr.get().as_ptr() }),
329            Green::Token { ptr } => GreenElementRef::Token(unsafe { ptr.as_ref() }),
330        }
331    }
332    #[inline]
333    fn green_siblings(&self) -> slice::Iter<'_, GreenChild> {
334        match &self.parent().map(|it| &it.green) {
335            Some(Green::Node { ptr }) => unsafe { &*ptr.get().as_ptr() }.children().raw,
336            Some(Green::Token { .. }) => {
337                debug_assert!(false);
338                [].iter()
339            }
340            None => [].iter(),
341        }
342    }
343    #[inline]
344    fn index(&self) -> u32 {
345        self.index.get()
346    }
347
348    #[inline]
349    fn offset(&self) -> TextSize {
350        if self.mutable { self.offset_mut() } else { self.offset }
351    }
352
353    #[cold]
354    fn offset_mut(&self) -> TextSize {
355        let mut res = TextSize::from(0);
356
357        let mut node = self;
358        while let Some(parent) = node.parent() {
359            let green = parent.green().into_node().unwrap();
360            res += green.children().raw.nth(node.index() as usize).unwrap().rel_offset();
361            node = parent;
362        }
363
364        res
365    }
366
367    #[inline]
368    fn text_range(&self) -> TextRange {
369        let offset = self.offset();
370        let len = self.green().text_len();
371        TextRange::at(offset, len)
372    }
373
374    #[inline]
375    fn kind(&self) -> SyntaxKind {
376        self.green().kind()
377    }
378
379    fn next_sibling(&self) -> Option<SyntaxNode> {
380        let siblings = self.green_siblings().enumerate();
381        let index = self.index() as usize;
382
383        siblings.skip(index + 1).find_map(|(index, child)| {
384            child.as_ref().into_node().and_then(|green| {
385                let parent = self.parent_node()?;
386                let offset = parent.offset() + child.rel_offset();
387                Some(SyntaxNode::new_child(green, parent, index as u32, offset))
388            })
389        })
390    }
391
392    fn next_sibling_by_kind(&self, matcher: &impl Fn(SyntaxKind) -> bool) -> Option<SyntaxNode> {
393        let siblings = self.green_siblings().enumerate();
394        let index = self.index() as usize;
395
396        siblings.skip(index + 1).find_map(|(index, child)| {
397            if !matcher(child.as_ref().kind()) {
398                return None;
399            }
400            child.as_ref().into_node().and_then(|green| {
401                let parent = self.parent_node()?;
402                let offset = parent.offset() + child.rel_offset();
403                Some(SyntaxNode::new_child(green, parent, index as u32, offset))
404            })
405        })
406    }
407
408    fn prev_sibling(&self) -> Option<SyntaxNode> {
409        let rev_siblings = self.green_siblings().enumerate().rev();
410        let index = rev_siblings.len().checked_sub(self.index() as usize)?;
411
412        rev_siblings.skip(index).find_map(|(index, child)| {
413            child.as_ref().into_node().and_then(|green| {
414                let parent = self.parent_node()?;
415                let offset = parent.offset() + child.rel_offset();
416                Some(SyntaxNode::new_child(green, parent, index as u32, offset))
417            })
418        })
419    }
420
421    fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
422        let mut siblings = self.green_siblings().enumerate();
423        let index = self.index() as usize + 1;
424
425        siblings.nth(index).and_then(|(index, child)| {
426            let parent = self.parent_node()?;
427            let offset = parent.offset() + child.rel_offset();
428            Some(SyntaxElement::new(child.as_ref(), parent, index as u32, offset))
429        })
430    }
431
432    fn next_sibling_or_token_by_kind(
433        &self,
434        matcher: &impl Fn(SyntaxKind) -> bool,
435    ) -> Option<SyntaxElement> {
436        let siblings = self.green_siblings().enumerate();
437        let index = self.index() as usize;
438
439        siblings.skip(index + 1).find_map(|(index, child)| {
440            if !matcher(child.as_ref().kind()) {
441                return None;
442            }
443            let parent = self.parent_node()?;
444            let offset = parent.offset() + child.rel_offset();
445            Some(SyntaxElement::new(child.as_ref(), parent, index as u32, offset))
446        })
447    }
448
449    fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
450        let mut siblings = self.green_siblings().enumerate();
451        let index = self.index().checked_sub(1)? as usize;
452
453        siblings.nth(index).and_then(|(index, child)| {
454            let parent = self.parent_node()?;
455            let offset = parent.offset() + child.rel_offset();
456            Some(SyntaxElement::new(child.as_ref(), parent, index as u32, offset))
457        })
458    }
459
460    fn detach(&self) {
461        assert!(self.mutable);
462        assert!(self.rc.get() > 0);
463        let parent_ptr = match self.parent.take() {
464            Some(parent) => parent,
465            None => return,
466        };
467
468        sll::adjust(self, self.index() + 1, Delta::Sub(1));
469        let parent = unsafe { parent_ptr.as_ref() };
470        sll::unlink(&parent.first, self);
471
472        // Add strong ref to green
473        match self.green().to_owned() {
474            NodeOrToken::Node(it) => {
475                GreenNode::into_raw(it);
476            }
477            NodeOrToken::Token(it) => {
478                GreenToken::into_raw(it);
479            }
480        }
481
482        match parent.green() {
483            NodeOrToken::Node(green) => {
484                let green = green.remove_child(self.index() as usize);
485                unsafe { parent.respine(green) }
486            }
487            NodeOrToken::Token(_) => unreachable!(),
488        }
489
490        if parent.dec_rc() {
491            unsafe { free(parent_ptr) }
492        }
493    }
494    fn attach_child(&self, index: usize, child: &NodeData) {
495        assert!(self.mutable && child.mutable && child.parent().is_none());
496        assert!(self.rc.get() > 0 && child.rc.get() > 0);
497
498        child.index.set(index as u32);
499        child.parent.set(Some(self.into()));
500        self.inc_rc();
501
502        if !self.first.get().is_null() {
503            sll::adjust(unsafe { &*self.first.get() }, index as u32, Delta::Add(1));
504        }
505
506        match sll::link(&self.first, child) {
507            sll::AddToSllResult::AlreadyInSll(_) => {
508                panic!("Child already in sorted linked list")
509            }
510            it => it.add_to_sll(child),
511        }
512
513        match self.green() {
514            NodeOrToken::Node(green) => {
515                // Child is root, so it owns the green node. Steal it!
516                let child_green = match &child.green {
517                    Green::Node { ptr } => unsafe { GreenNode::from_raw(ptr.get()).into() },
518                    Green::Token { ptr } => unsafe { GreenToken::from_raw(*ptr).into() },
519                };
520
521                let green = green.insert_child(index, child_green);
522                unsafe { self.respine(green) };
523            }
524            NodeOrToken::Token(_) => unreachable!(),
525        }
526    }
527    unsafe fn respine(&self, mut new_green: GreenNode) {
528        unsafe {
529            let mut node = self;
530            loop {
531                let old_green = match &node.green {
532                    Green::Node { ptr } => ptr.replace(ptr::NonNull::from(&*new_green)),
533                    Green::Token { .. } => unreachable!(),
534                };
535                match node.parent() {
536                    Some(parent) => match parent.green() {
537                        NodeOrToken::Node(parent_green) => {
538                            new_green =
539                                parent_green.replace_child(node.index() as usize, new_green.into());
540                            node = parent;
541                        }
542                        _ => unreachable!(),
543                    },
544                    None => {
545                        mem::forget(new_green);
546                        let _ = GreenNode::from_raw(old_green);
547                        break;
548                    }
549                }
550            }
551        }
552    }
553}
554
555impl SyntaxNode {
556    pub fn new_root(green: GreenNode) -> SyntaxNode {
557        let green = GreenNode::into_raw(green);
558        let green = Green::Node { ptr: Cell::new(green) };
559        SyntaxNode { ptr: NodeData::new(None, 0, 0.into(), green, false) }
560    }
561
562    pub fn new_root_mut(green: GreenNode) -> SyntaxNode {
563        let green = GreenNode::into_raw(green);
564        let green = Green::Node { ptr: Cell::new(green) };
565        SyntaxNode { ptr: NodeData::new(None, 0, 0.into(), green, true) }
566    }
567
568    fn new_child(
569        green: &GreenNodeData,
570        parent: SyntaxNode,
571        index: u32,
572        offset: TextSize,
573    ) -> SyntaxNode {
574        let mutable = parent.data().mutable;
575        let green = Green::Node { ptr: Cell::new(green.into()) };
576        SyntaxNode { ptr: NodeData::new(Some(parent), index, offset, green, mutable) }
577    }
578
579    pub fn is_mutable(&self) -> bool {
580        self.data().mutable
581    }
582
583    pub fn clone_for_update(&self) -> SyntaxNode {
584        assert!(!self.data().mutable);
585        match self.parent() {
586            Some(parent) => {
587                let parent = parent.clone_for_update();
588                SyntaxNode::new_child(self.green_ref(), parent, self.data().index(), self.offset())
589            }
590            None => SyntaxNode::new_root_mut(self.green_ref().to_owned()),
591        }
592    }
593
594    pub fn clone_subtree(&self) -> SyntaxNode {
595        SyntaxNode::new_root(self.green().into())
596    }
597
598    #[inline]
599    fn data(&self) -> &NodeData {
600        unsafe { self.ptr.as_ref() }
601    }
602
603    #[inline]
604    fn can_take_ptr(&self) -> bool {
605        self.data().rc.get() == 1 && !self.data().mutable
606    }
607
608    #[inline]
609    fn take_ptr(self) -> ptr::NonNull<NodeData> {
610        assert!(self.can_take_ptr());
611        let ret = self.ptr;
612        // don't change the refcount when self gets dropped
613        mem::forget(self);
614        ret
615    }
616
617    pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
618        assert_eq!(self.kind(), replacement.kind());
619        match &self.parent() {
620            None => replacement,
621            Some(parent) => {
622                let new_parent = parent
623                    .green_ref()
624                    .replace_child(self.data().index() as usize, replacement.into());
625                parent.replace_with(new_parent)
626            }
627        }
628    }
629
630    #[inline]
631    pub fn kind(&self) -> SyntaxKind {
632        self.data().kind()
633    }
634
635    #[inline]
636    fn offset(&self) -> TextSize {
637        self.data().offset()
638    }
639
640    #[inline]
641    pub fn text_range(&self) -> TextRange {
642        self.data().text_range()
643    }
644
645    #[inline]
646    pub fn index(&self) -> usize {
647        self.data().index() as usize
648    }
649
650    #[inline]
651    pub fn text(&self) -> SyntaxText {
652        SyntaxText::new(self.clone())
653    }
654
655    #[inline]
656    pub fn green(&self) -> Cow<'_, GreenNodeData> {
657        let green_ref = self.green_ref();
658        match self.data().mutable {
659            false => Cow::Borrowed(green_ref),
660            true => Cow::Owned(green_ref.to_owned()),
661        }
662    }
663    #[inline]
664    fn green_ref(&self) -> &GreenNodeData {
665        self.data().green().into_node().unwrap()
666    }
667
668    #[inline]
669    pub fn parent(&self) -> Option<SyntaxNode> {
670        self.data().parent_node()
671    }
672
673    #[inline]
674    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> + use<> {
675        iter::successors(Some(self.clone()), SyntaxNode::parent)
676    }
677
678    #[inline]
679    pub fn children(&self) -> SyntaxNodeChildren {
680        SyntaxNodeChildren::new(self.clone())
681    }
682
683    #[inline]
684    pub fn children_with_tokens(&self) -> SyntaxElementChildren {
685        SyntaxElementChildren::new(self.clone())
686    }
687
688    pub fn first_child(&self) -> Option<SyntaxNode> {
689        self.green_ref().children().raw.enumerate().find_map(|(index, child)| {
690            child.as_ref().into_node().map(|green| {
691                SyntaxNode::new_child(
692                    green,
693                    self.clone(),
694                    index as u32,
695                    self.offset() + child.rel_offset(),
696                )
697            })
698        })
699    }
700
701    pub fn first_child_by_kind(&self, matcher: &impl Fn(SyntaxKind) -> bool) -> Option<SyntaxNode> {
702        self.green_ref().children().raw.enumerate().find_map(|(index, child)| {
703            if !matcher(child.as_ref().kind()) {
704                return None;
705            }
706            child.as_ref().into_node().map(|green| {
707                SyntaxNode::new_child(
708                    green,
709                    self.clone(),
710                    index as u32,
711                    self.offset() + child.rel_offset(),
712                )
713            })
714        })
715    }
716
717    pub fn last_child(&self) -> Option<SyntaxNode> {
718        self.green_ref().children().raw.enumerate().rev().find_map(|(index, child)| {
719            child.as_ref().into_node().map(|green| {
720                SyntaxNode::new_child(
721                    green,
722                    self.clone(),
723                    index as u32,
724                    self.offset() + child.rel_offset(),
725                )
726            })
727        })
728    }
729
730    pub fn first_child_or_token(&self) -> Option<SyntaxElement> {
731        self.green_ref().children().raw.next().map(|child| {
732            SyntaxElement::new(child.as_ref(), self.clone(), 0, self.offset() + child.rel_offset())
733        })
734    }
735
736    pub fn first_child_or_token_by_kind(
737        &self,
738        matcher: &impl Fn(SyntaxKind) -> bool,
739    ) -> Option<SyntaxElement> {
740        self.green_ref().children().raw.enumerate().find_map(|(index, child)| {
741            if !matcher(child.as_ref().kind()) {
742                return None;
743            }
744            Some(SyntaxElement::new(
745                child.as_ref(),
746                self.clone(),
747                index as u32,
748                self.offset() + child.rel_offset(),
749            ))
750        })
751    }
752
753    pub fn last_child_or_token(&self) -> Option<SyntaxElement> {
754        self.green_ref().children().raw.enumerate().next_back().map(|(index, child)| {
755            SyntaxElement::new(
756                child.as_ref(),
757                self.clone(),
758                index as u32,
759                self.offset() + child.rel_offset(),
760            )
761        })
762    }
763
764    // if possible (i.e. unshared), consume self and advance it to point to the next sibling
765    // this way, we can reuse the previously allocated buffer
766    pub fn to_next_sibling(self) -> Option<SyntaxNode> {
767        if !self.can_take_ptr() {
768            // cannot mutate in-place
769            return self.next_sibling();
770        }
771
772        let mut ptr = self.take_ptr();
773        let data = unsafe { ptr.as_mut() };
774        assert!(data.rc.get() == 1);
775
776        let parent = data.parent_node()?;
777        let parent_offset = parent.offset();
778        let siblings = parent.green_ref().children().raw.enumerate();
779        let index = data.index() as usize;
780
781        siblings
782            .skip(index + 1)
783            .find_map(|(index, child)| {
784                child.as_ref().into_node().map(|green| (green, index as u32, child.rel_offset()))
785            })
786            .map(|(green, index, rel_offset)| {
787                data.index.set(index);
788                data.offset = parent_offset + rel_offset;
789                data.green = Green::Node { ptr: Cell::new(green.into()) };
790                SyntaxNode { ptr }
791            })
792            .or_else(|| {
793                data.dec_rc();
794                unsafe { free(ptr) };
795                None
796            })
797    }
798
799    pub fn next_sibling(&self) -> Option<SyntaxNode> {
800        self.data().next_sibling()
801    }
802
803    pub fn next_sibling_by_kind(
804        &self,
805        matcher: &impl Fn(SyntaxKind) -> bool,
806    ) -> Option<SyntaxNode> {
807        self.data().next_sibling_by_kind(matcher)
808    }
809
810    pub fn prev_sibling(&self) -> Option<SyntaxNode> {
811        self.data().prev_sibling()
812    }
813
814    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
815        self.data().next_sibling_or_token()
816    }
817
818    pub fn next_sibling_or_token_by_kind(
819        &self,
820        matcher: &impl Fn(SyntaxKind) -> bool,
821    ) -> Option<SyntaxElement> {
822        self.data().next_sibling_or_token_by_kind(matcher)
823    }
824
825    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
826        self.data().prev_sibling_or_token()
827    }
828
829    pub fn first_token(&self) -> Option<SyntaxToken> {
830        self.first_child_or_token()?.first_token()
831    }
832    pub fn last_token(&self) -> Option<SyntaxToken> {
833        self.last_child_or_token()?.last_token()
834    }
835
836    #[inline]
837    pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode> + use<> {
838        iter::successors(Some(self.clone()), move |node| match direction {
839            Direction::Next => node.next_sibling(),
840            Direction::Prev => node.prev_sibling(),
841        })
842    }
843
844    #[inline]
845    pub fn siblings_with_tokens(
846        &self,
847        direction: Direction,
848    ) -> impl Iterator<Item = SyntaxElement> + use<> {
849        let me: SyntaxElement = self.clone().into();
850        iter::successors(Some(me), move |el| match direction {
851            Direction::Next => el.next_sibling_or_token(),
852            Direction::Prev => el.prev_sibling_or_token(),
853        })
854    }
855
856    #[inline]
857    pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode> + use<> {
858        self.preorder().filter_map(|event| match event {
859            WalkEvent::Enter(node) => Some(node),
860            WalkEvent::Leave(_) => None,
861        })
862    }
863
864    #[inline]
865    pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> + use<> {
866        self.preorder_with_tokens().filter_map(|event| match event {
867            WalkEvent::Enter(it) => Some(it),
868            WalkEvent::Leave(_) => None,
869        })
870    }
871
872    #[inline]
873    pub fn preorder(&self) -> Preorder {
874        Preorder::new(self.clone())
875    }
876
877    #[inline]
878    pub fn preorder_with_tokens(&self) -> PreorderWithTokens {
879        PreorderWithTokens::new(self.clone())
880    }
881
882    pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
883        // TODO: this could be faster if we first drill-down to node, and only
884        // then switch to token search. We should also replace explicit
885        // recursion with a loop.
886        let range = self.text_range();
887        assert!(
888            range.start() <= offset && offset <= range.end(),
889            "Bad offset: range {:?} offset {:?}",
890            range,
891            offset
892        );
893        if range.is_empty() {
894            return TokenAtOffset::None;
895        }
896
897        let mut children = self.children_with_tokens().filter(|child| {
898            let child_range = child.text_range();
899            !child_range.is_empty()
900                && (child_range.start() <= offset && offset <= child_range.end())
901        });
902
903        let left = children.next().unwrap();
904        let right = children.next();
905        assert!(children.next().is_none());
906
907        if let Some(right) = right {
908            match (left.token_at_offset(offset), right.token_at_offset(offset)) {
909                (TokenAtOffset::Single(left), TokenAtOffset::Single(right)) => {
910                    TokenAtOffset::Between(left, right)
911                }
912                _ => unreachable!(),
913            }
914        } else {
915            left.token_at_offset(offset)
916        }
917    }
918
919    pub fn covering_element(&self, range: TextRange) -> SyntaxElement {
920        let mut res: SyntaxElement = self.clone().into();
921        loop {
922            assert!(
923                res.text_range().contains_range(range),
924                "Bad range: node range {:?}, range {:?}",
925                res.text_range(),
926                range,
927            );
928            res = match &res {
929                NodeOrToken::Token(_) => return res,
930                NodeOrToken::Node(node) => match node.child_or_token_at_range(range) {
931                    Some(it) => it,
932                    None => return res,
933                },
934            };
935        }
936    }
937
938    pub fn child_or_token_at_range(&self, range: TextRange) -> Option<SyntaxElement> {
939        let rel_range = range - self.offset();
940        self.green_ref().child_at_range(rel_range).map(|(index, rel_offset, green)| {
941            SyntaxElement::new(green, self.clone(), index as u32, self.offset() + rel_offset)
942        })
943    }
944
945    pub fn splice_children<I: IntoIterator<Item = SyntaxElement>>(
946        &self,
947        to_delete: Range<usize>,
948        to_insert: I,
949    ) {
950        assert!(self.data().mutable, "immutable tree: {}", self);
951        for (i, child) in self.children_with_tokens().enumerate() {
952            if to_delete.contains(&i) {
953                child.detach();
954            }
955        }
956        let mut index = to_delete.start;
957        for child in to_insert {
958            self.attach_child(index, child);
959            index += 1;
960        }
961    }
962
963    pub fn detach(&self) {
964        assert!(self.data().mutable, "immutable tree: {}", self);
965        self.data().detach()
966    }
967
968    fn attach_child(&self, index: usize, child: SyntaxElement) {
969        assert!(self.data().mutable, "immutable tree: {}", self);
970        child.detach();
971        let data = match &child {
972            NodeOrToken::Node(it) => it.data(),
973            NodeOrToken::Token(it) => it.data(),
974        };
975        self.data().attach_child(index, data)
976    }
977}
978
979impl SyntaxToken {
980    fn new(
981        green: &GreenTokenData,
982        parent: SyntaxNode,
983        index: u32,
984        offset: TextSize,
985    ) -> SyntaxToken {
986        let mutable = parent.data().mutable;
987        let green = Green::Token { ptr: green.into() };
988        SyntaxToken { ptr: NodeData::new(Some(parent), index, offset, green, mutable) }
989    }
990
991    #[inline]
992    fn data(&self) -> &NodeData {
993        unsafe { self.ptr.as_ref() }
994    }
995
996    #[inline]
997    fn can_take_ptr(&self) -> bool {
998        self.data().rc.get() == 1 && !self.data().mutable
999    }
1000
1001    #[inline]
1002    fn take_ptr(self) -> ptr::NonNull<NodeData> {
1003        assert!(self.can_take_ptr());
1004        let ret = self.ptr;
1005        // don't change the refcount when self gets dropped
1006        mem::forget(self);
1007        ret
1008    }
1009
1010    pub fn replace_with(&self, replacement: GreenToken) -> GreenNode {
1011        assert_eq!(self.kind(), replacement.kind());
1012        let parent = self.parent().unwrap();
1013        let me: u32 = self.data().index();
1014
1015        let new_parent = parent.green_ref().replace_child(me as usize, replacement.into());
1016        parent.replace_with(new_parent)
1017    }
1018
1019    #[inline]
1020    pub fn kind(&self) -> SyntaxKind {
1021        self.data().kind()
1022    }
1023
1024    #[inline]
1025    pub fn text_range(&self) -> TextRange {
1026        self.data().text_range()
1027    }
1028
1029    #[inline]
1030    pub fn index(&self) -> usize {
1031        self.data().index() as usize
1032    }
1033
1034    #[inline]
1035    pub fn text(&self) -> &str {
1036        match self.data().green().as_token() {
1037            Some(it) => it.text(),
1038            None => {
1039                debug_assert!(
1040                    false,
1041                    "corrupted tree: a node thinks it is a token: {:?}",
1042                    self.data().green().as_node().unwrap().to_string()
1043                );
1044                ""
1045            }
1046        }
1047    }
1048
1049    #[inline]
1050    pub fn green(&self) -> &GreenTokenData {
1051        self.data().green().into_token().unwrap()
1052    }
1053
1054    #[inline]
1055    pub fn parent(&self) -> Option<SyntaxNode> {
1056        self.data().parent_node()
1057    }
1058
1059    #[inline]
1060    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> + use<> {
1061        iter::successors(self.parent(), SyntaxNode::parent)
1062    }
1063
1064    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
1065        self.data().next_sibling_or_token()
1066    }
1067
1068    pub fn next_sibling_or_token_by_kind(
1069        &self,
1070        matcher: &impl Fn(SyntaxKind) -> bool,
1071    ) -> Option<SyntaxElement> {
1072        self.data().next_sibling_or_token_by_kind(matcher)
1073    }
1074
1075    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
1076        self.data().prev_sibling_or_token()
1077    }
1078
1079    #[inline]
1080    pub fn siblings_with_tokens(
1081        &self,
1082        direction: Direction,
1083    ) -> impl Iterator<Item = SyntaxElement> + use<> {
1084        let me: SyntaxElement = self.clone().into();
1085        iter::successors(Some(me), move |el| match direction {
1086            Direction::Next => el.next_sibling_or_token(),
1087            Direction::Prev => el.prev_sibling_or_token(),
1088        })
1089    }
1090
1091    pub fn next_token(&self) -> Option<SyntaxToken> {
1092        match self.next_sibling_or_token() {
1093            Some(element) => element.first_token(),
1094            None => self
1095                .ancestors()
1096                .find_map(|it| it.next_sibling_or_token())
1097                .and_then(|element| element.first_token()),
1098        }
1099    }
1100    pub fn prev_token(&self) -> Option<SyntaxToken> {
1101        match self.prev_sibling_or_token() {
1102            Some(element) => element.last_token(),
1103            None => self
1104                .ancestors()
1105                .find_map(|it| it.prev_sibling_or_token())
1106                .and_then(|element| element.last_token()),
1107        }
1108    }
1109
1110    pub fn detach(&self) {
1111        assert!(self.data().mutable, "immutable tree: {}", self);
1112        self.data().detach()
1113    }
1114}
1115
1116impl SyntaxElement {
1117    fn new(
1118        element: GreenElementRef<'_>,
1119        parent: SyntaxNode,
1120        index: u32,
1121        offset: TextSize,
1122    ) -> SyntaxElement {
1123        match element {
1124            NodeOrToken::Node(node) => SyntaxNode::new_child(node, parent, index, offset).into(),
1125            NodeOrToken::Token(token) => SyntaxToken::new(token, parent, index, offset).into(),
1126        }
1127    }
1128
1129    #[inline]
1130    pub fn text_range(&self) -> TextRange {
1131        match self {
1132            NodeOrToken::Node(it) => it.text_range(),
1133            NodeOrToken::Token(it) => it.text_range(),
1134        }
1135    }
1136
1137    #[inline]
1138    pub fn index(&self) -> usize {
1139        match self {
1140            NodeOrToken::Node(it) => it.index(),
1141            NodeOrToken::Token(it) => it.index(),
1142        }
1143    }
1144
1145    #[inline]
1146    pub fn kind(&self) -> SyntaxKind {
1147        match self {
1148            NodeOrToken::Node(it) => it.kind(),
1149            NodeOrToken::Token(it) => it.kind(),
1150        }
1151    }
1152
1153    #[inline]
1154    pub fn parent(&self) -> Option<SyntaxNode> {
1155        match self {
1156            NodeOrToken::Node(it) => it.parent(),
1157            NodeOrToken::Token(it) => it.parent(),
1158        }
1159    }
1160
1161    #[inline]
1162    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> + use<> {
1163        let first = match self {
1164            NodeOrToken::Node(it) => Some(it.clone()),
1165            NodeOrToken::Token(it) => it.parent(),
1166        };
1167        iter::successors(first, SyntaxNode::parent)
1168    }
1169
1170    pub fn first_token(&self) -> Option<SyntaxToken> {
1171        match self {
1172            NodeOrToken::Node(it) => it.first_token(),
1173            NodeOrToken::Token(it) => Some(it.clone()),
1174        }
1175    }
1176    pub fn last_token(&self) -> Option<SyntaxToken> {
1177        match self {
1178            NodeOrToken::Node(it) => it.last_token(),
1179            NodeOrToken::Token(it) => Some(it.clone()),
1180        }
1181    }
1182
1183    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
1184        match self {
1185            NodeOrToken::Node(it) => it.next_sibling_or_token(),
1186            NodeOrToken::Token(it) => it.next_sibling_or_token(),
1187        }
1188    }
1189
1190    fn can_take_ptr(&self) -> bool {
1191        match self {
1192            NodeOrToken::Node(it) => it.can_take_ptr(),
1193            NodeOrToken::Token(it) => it.can_take_ptr(),
1194        }
1195    }
1196
1197    fn take_ptr(self) -> ptr::NonNull<NodeData> {
1198        match self {
1199            NodeOrToken::Node(it) => it.take_ptr(),
1200            NodeOrToken::Token(it) => it.take_ptr(),
1201        }
1202    }
1203
1204    // if possible (i.e. unshared), consume self and advance it to point to the next sibling
1205    // this way, we can reuse the previously allocated buffer
1206    pub fn to_next_sibling_or_token(self) -> Option<SyntaxElement> {
1207        if !self.can_take_ptr() {
1208            // cannot mutate in-place
1209            return self.next_sibling_or_token();
1210        }
1211
1212        let mut ptr = self.take_ptr();
1213        let data = unsafe { ptr.as_mut() };
1214
1215        let parent = data.parent_node()?;
1216        let parent_offset = parent.offset();
1217        let siblings = parent.green_ref().children().raw.enumerate();
1218        let index = data.index() as usize;
1219
1220        siblings
1221            .skip(index + 1)
1222            .map(|(index, green)| {
1223                data.index.set(index as u32);
1224                data.offset = parent_offset + green.rel_offset();
1225
1226                match green.as_ref() {
1227                    NodeOrToken::Node(node) => {
1228                        data.green = Green::Node { ptr: Cell::new(node.into()) };
1229                        Some(SyntaxElement::Node(SyntaxNode { ptr }))
1230                    }
1231                    NodeOrToken::Token(token) => {
1232                        data.green = Green::Token { ptr: token.into() };
1233                        Some(SyntaxElement::Token(SyntaxToken { ptr }))
1234                    }
1235                }
1236            })
1237            .next()
1238            .flatten()
1239            .or_else(|| {
1240                data.dec_rc();
1241                unsafe { free(ptr) };
1242                None
1243            })
1244    }
1245
1246    pub fn next_sibling_or_token_by_kind(
1247        &self,
1248        matcher: &impl Fn(SyntaxKind) -> bool,
1249    ) -> Option<SyntaxElement> {
1250        match self {
1251            NodeOrToken::Node(it) => it.next_sibling_or_token_by_kind(matcher),
1252            NodeOrToken::Token(it) => it.next_sibling_or_token_by_kind(matcher),
1253        }
1254    }
1255
1256    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
1257        match self {
1258            NodeOrToken::Node(it) => it.prev_sibling_or_token(),
1259            NodeOrToken::Token(it) => it.prev_sibling_or_token(),
1260        }
1261    }
1262
1263    fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
1264        assert!(self.text_range().start() <= offset && offset <= self.text_range().end());
1265        match self {
1266            NodeOrToken::Token(token) => TokenAtOffset::Single(token.clone()),
1267            NodeOrToken::Node(node) => node.token_at_offset(offset),
1268        }
1269    }
1270
1271    pub fn detach(&self) {
1272        match self {
1273            NodeOrToken::Node(it) => it.detach(),
1274            NodeOrToken::Token(it) => it.detach(),
1275        }
1276    }
1277}
1278
1279// region: impls
1280
1281// Identity semantics for hash & eq
1282impl PartialEq for SyntaxNode {
1283    #[inline]
1284    fn eq(&self, other: &SyntaxNode) -> bool {
1285        self.data().key() == other.data().key()
1286    }
1287}
1288
1289impl Eq for SyntaxNode {}
1290
1291impl Hash for SyntaxNode {
1292    #[inline]
1293    fn hash<H: Hasher>(&self, state: &mut H) {
1294        self.data().key().hash(state);
1295    }
1296}
1297
1298impl fmt::Debug for SyntaxNode {
1299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300        f.debug_struct("SyntaxNode")
1301            .field("kind", &self.kind())
1302            .field("text_range", &self.text_range())
1303            .finish()
1304    }
1305}
1306
1307impl fmt::Display for SyntaxNode {
1308    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1309        self.preorder_with_tokens()
1310            .filter_map(|event| match event {
1311                WalkEvent::Enter(NodeOrToken::Token(token)) => Some(token),
1312                _ => None,
1313            })
1314            .try_for_each(|it| fmt::Display::fmt(&it, f))
1315    }
1316}
1317
1318// Identity semantics for hash & eq
1319impl PartialEq for SyntaxToken {
1320    #[inline]
1321    fn eq(&self, other: &SyntaxToken) -> bool {
1322        self.data().key() == other.data().key()
1323    }
1324}
1325
1326impl Eq for SyntaxToken {}
1327
1328impl Hash for SyntaxToken {
1329    #[inline]
1330    fn hash<H: Hasher>(&self, state: &mut H) {
1331        self.data().key().hash(state);
1332    }
1333}
1334
1335impl fmt::Display for SyntaxToken {
1336    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1337        fmt::Display::fmt(self.text(), f)
1338    }
1339}
1340
1341impl From<SyntaxNode> for SyntaxElement {
1342    #[inline]
1343    fn from(node: SyntaxNode) -> SyntaxElement {
1344        NodeOrToken::Node(node)
1345    }
1346}
1347
1348impl From<SyntaxToken> for SyntaxElement {
1349    #[inline]
1350    fn from(token: SyntaxToken) -> SyntaxElement {
1351        NodeOrToken::Token(token)
1352    }
1353}
1354
1355// endregion
1356
1357// region: iterators
1358
1359#[derive(Clone, Debug)]
1360pub struct SyntaxNodeChildren {
1361    parent: SyntaxNode,
1362    next: Option<SyntaxNode>,
1363    next_initialized: bool,
1364}
1365
1366impl SyntaxNodeChildren {
1367    fn new(parent: SyntaxNode) -> SyntaxNodeChildren {
1368        SyntaxNodeChildren { parent, next: None, next_initialized: false }
1369    }
1370
1371    pub fn by_kind<F: Fn(SyntaxKind) -> bool>(self, matcher: F) -> SyntaxNodeChildrenByKind<F> {
1372        if !self.next_initialized {
1373            SyntaxNodeChildrenByKind { next: self.parent.first_child_by_kind(&matcher), matcher }
1374        } else {
1375            SyntaxNodeChildrenByKind {
1376                next: self.next.and_then(|node| {
1377                    if matcher(node.kind()) {
1378                        Some(node)
1379                    } else {
1380                        node.next_sibling_by_kind(&matcher)
1381                    }
1382                }),
1383                matcher,
1384            }
1385        }
1386    }
1387}
1388
1389impl Iterator for SyntaxNodeChildren {
1390    type Item = SyntaxNode;
1391    fn next(&mut self) -> Option<SyntaxNode> {
1392        if !self.next_initialized {
1393            self.next = self.parent.first_child();
1394            self.next_initialized = true;
1395        } else {
1396            self.next = self.next.take().and_then(|next| next.to_next_sibling());
1397        }
1398
1399        self.next.clone()
1400    }
1401}
1402
1403#[derive(Clone, Debug)]
1404pub struct SyntaxNodeChildrenByKind<F: Fn(SyntaxKind) -> bool> {
1405    next: Option<SyntaxNode>,
1406    matcher: F,
1407}
1408
1409impl<F: Fn(SyntaxKind) -> bool> Iterator for SyntaxNodeChildrenByKind<F> {
1410    type Item = SyntaxNode;
1411    fn next(&mut self) -> Option<SyntaxNode> {
1412        self.next.take().inspect(|next| {
1413            self.next = next.next_sibling_by_kind(&self.matcher);
1414        })
1415    }
1416}
1417
1418#[derive(Clone, Debug)]
1419pub struct SyntaxElementChildren {
1420    parent: SyntaxNode,
1421    next: Option<SyntaxElement>,
1422    next_initialized: bool,
1423}
1424
1425impl SyntaxElementChildren {
1426    fn new(parent: SyntaxNode) -> SyntaxElementChildren {
1427        SyntaxElementChildren { parent, next: None, next_initialized: false }
1428    }
1429
1430    pub fn by_kind<F: Fn(SyntaxKind) -> bool>(self, matcher: F) -> SyntaxElementChildrenByKind<F> {
1431        if !self.next_initialized {
1432            SyntaxElementChildrenByKind {
1433                next: self.parent.first_child_or_token_by_kind(&matcher),
1434                matcher,
1435            }
1436        } else {
1437            SyntaxElementChildrenByKind {
1438                next: self.next.and_then(|node| {
1439                    if matcher(node.kind()) {
1440                        Some(node)
1441                    } else {
1442                        node.next_sibling_or_token_by_kind(&matcher)
1443                    }
1444                }),
1445                matcher,
1446            }
1447        }
1448    }
1449}
1450
1451impl Iterator for SyntaxElementChildren {
1452    type Item = SyntaxElement;
1453    fn next(&mut self) -> Option<SyntaxElement> {
1454        if !self.next_initialized {
1455            self.next = self.parent.first_child_or_token();
1456            self.next_initialized = true;
1457        } else {
1458            self.next = self.next.take().and_then(|next| next.to_next_sibling_or_token());
1459        }
1460
1461        self.next.clone()
1462    }
1463}
1464
1465#[derive(Clone, Debug)]
1466pub struct SyntaxElementChildrenByKind<F: Fn(SyntaxKind) -> bool> {
1467    next: Option<SyntaxElement>,
1468    matcher: F,
1469}
1470
1471impl<F: Fn(SyntaxKind) -> bool> Iterator for SyntaxElementChildrenByKind<F> {
1472    type Item = SyntaxElement;
1473    fn next(&mut self) -> Option<SyntaxElement> {
1474        self.next.take().inspect(|next| {
1475            self.next = next.next_sibling_or_token_by_kind(&self.matcher);
1476        })
1477    }
1478}
1479
1480#[derive(Debug, Clone)]
1481pub struct Preorder {
1482    start: SyntaxNode,
1483    next: Option<WalkEvent<SyntaxNode>>,
1484    skip_subtree: bool,
1485}
1486
1487impl Preorder {
1488    fn new(start: SyntaxNode) -> Preorder {
1489        let next = Some(WalkEvent::Enter(start.clone()));
1490        Preorder { start, next, skip_subtree: false }
1491    }
1492
1493    pub fn skip_subtree(&mut self) {
1494        self.skip_subtree = true;
1495    }
1496
1497    #[cold]
1498    fn do_skip(&mut self) {
1499        self.next = self.next.take().map(|next| match next {
1500            WalkEvent::Enter(first_child) => WalkEvent::Leave(first_child.parent().unwrap()),
1501            WalkEvent::Leave(parent) => WalkEvent::Leave(parent),
1502        })
1503    }
1504}
1505
1506impl Iterator for Preorder {
1507    type Item = WalkEvent<SyntaxNode>;
1508
1509    fn next(&mut self) -> Option<WalkEvent<SyntaxNode>> {
1510        if self.skip_subtree {
1511            self.do_skip();
1512            self.skip_subtree = false;
1513        }
1514        let next = self.next.take();
1515        self.next = next.as_ref().and_then(|next| {
1516            Some(match next {
1517                WalkEvent::Enter(node) => match node.first_child() {
1518                    Some(child) => WalkEvent::Enter(child),
1519                    None => WalkEvent::Leave(node.clone()),
1520                },
1521                WalkEvent::Leave(node) => {
1522                    if node == &self.start {
1523                        return None;
1524                    }
1525                    match node.next_sibling() {
1526                        Some(sibling) => WalkEvent::Enter(sibling),
1527                        None => WalkEvent::Leave(node.parent()?),
1528                    }
1529                }
1530            })
1531        });
1532        next
1533    }
1534}
1535
1536#[derive(Debug, Clone)]
1537pub struct PreorderWithTokens {
1538    start: SyntaxElement,
1539    next: Option<WalkEvent<SyntaxElement>>,
1540    skip_subtree: bool,
1541}
1542
1543impl PreorderWithTokens {
1544    fn new(start: SyntaxNode) -> PreorderWithTokens {
1545        let next = Some(WalkEvent::Enter(start.clone().into()));
1546        PreorderWithTokens { start: start.into(), next, skip_subtree: false }
1547    }
1548
1549    pub fn skip_subtree(&mut self) {
1550        self.skip_subtree = true;
1551    }
1552
1553    #[cold]
1554    fn do_skip(&mut self) {
1555        self.next = self.next.take().map(|next| match next {
1556            WalkEvent::Enter(first_child) => WalkEvent::Leave(first_child.parent().unwrap().into()),
1557            WalkEvent::Leave(parent) => WalkEvent::Leave(parent),
1558        })
1559    }
1560}
1561
1562impl Iterator for PreorderWithTokens {
1563    type Item = WalkEvent<SyntaxElement>;
1564
1565    fn next(&mut self) -> Option<WalkEvent<SyntaxElement>> {
1566        if self.skip_subtree {
1567            self.do_skip();
1568            self.skip_subtree = false;
1569        }
1570        let next = self.next.take();
1571        self.next = next.as_ref().and_then(|next| {
1572            Some(match next {
1573                WalkEvent::Enter(el) => match el {
1574                    NodeOrToken::Node(node) => match node.first_child_or_token() {
1575                        Some(child) => WalkEvent::Enter(child),
1576                        None => WalkEvent::Leave(node.clone().into()),
1577                    },
1578                    NodeOrToken::Token(token) => WalkEvent::Leave(token.clone().into()),
1579                },
1580                WalkEvent::Leave(el) if el == &self.start => return None,
1581                WalkEvent::Leave(el) => match el.next_sibling_or_token() {
1582                    Some(sibling) => WalkEvent::Enter(sibling),
1583                    None => WalkEvent::Leave(el.parent()?.into()),
1584                },
1585            })
1586        });
1587        next
1588    }
1589}
1590// endregion