Skip to main content

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// Implementation notes:
12//
13// The implementation is utterly and horribly unsafe. This whole module is an
14// unsafety boundary. It is believed that the API here is, in principle, sound,
15// but the implementation might have bugs.
16//
17// The core type is `NodeData` -- a heap-allocated reference counted object,
18// which points to a green node or a green token, and to the parent `NodeData`.
19// Publicly-exposed `SyntaxNode` and `SyntaxToken` own a reference to
20// `NodeData`.
21//
22// `NodeData`s are transient, and are created and destroyed during tree
23// traversals. In general, only currently referenced nodes and their ancestors
24// are alive at any given moment.
25//
26// More specifically, `NodeData`'s ref count is equal to the number of
27// outstanding `SyntaxNode` and `SyntaxToken` plus the number of children with
28// non-zero ref counts. For example, if the user has only a single `SyntaxNode`
29// pointing somewhere in the middle of the tree, then all `NodeData` on the path
30// from that point towards the root have ref count equal to one.
31//
32// A root `NodeData` owns its green node and is responsible for freeing it.
33
34use std::{
35    cell::Cell,
36    fmt,
37    hash::{Hash, Hasher},
38    iter,
39    mem::ManuallyDrop,
40    ptr, slice,
41};
42
43use countme::Count;
44
45use crate::{
46    green::{GreenChild, GreenElementRef, GreenNodeData, GreenTokenData, SyntaxKind},
47    Direction, GreenNode, GreenToken, NodeOrToken, SyntaxText, TextRange, TextSize, TokenAtOffset,
48    WalkEvent,
49};
50
51enum Green {
52    Node { ptr: ptr::NonNull<GreenNodeData> },
53    Token { ptr: ptr::NonNull<GreenTokenData> },
54}
55
56struct _SyntaxElement;
57
58struct NodeData {
59    _c: Count<_SyntaxElement>,
60
61    rc: Cell<u32>,
62    parent: Option<ptr::NonNull<NodeData>>,
63    index: u32,
64    green: Green,
65    offset: TextSize,
66}
67
68pub type SyntaxElement = NodeOrToken<SyntaxNode, SyntaxToken>;
69
70pub struct SyntaxNode {
71    ptr: ptr::NonNull<NodeData>,
72}
73
74impl Clone for SyntaxNode {
75    #[inline]
76    fn clone(&self) -> Self {
77        self.data().inc_rc();
78        SyntaxNode { ptr: self.ptr }
79    }
80}
81
82impl Drop for SyntaxNode {
83    #[inline]
84    fn drop(&mut self) {
85        if self.data().dec_rc() {
86            unsafe { free(self.ptr) }
87        }
88    }
89}
90
91#[derive(Debug)]
92pub struct SyntaxToken {
93    ptr: ptr::NonNull<NodeData>,
94}
95
96impl Clone for SyntaxToken {
97    #[inline]
98    fn clone(&self) -> Self {
99        self.data().inc_rc();
100        SyntaxToken { ptr: self.ptr }
101    }
102}
103
104impl Drop for SyntaxToken {
105    #[inline]
106    fn drop(&mut self) {
107        if self.data().dec_rc() {
108            unsafe { free(self.ptr) }
109        }
110    }
111}
112
113#[inline(never)]
114unsafe fn free(mut data: ptr::NonNull<NodeData>) {
115    loop {
116        debug_assert_eq!(data.as_ref().rc.get(), 0);
117        let node = Box::from_raw(data.as_ptr());
118        match node.parent {
119            Some(parent) => {
120                debug_assert!(parent.as_ref().rc.get() > 0);
121                if parent.as_ref().dec_rc() {
122                    data = parent;
123                } else {
124                    break;
125                }
126            }
127            None => {
128                if let Green::Node { ptr } = &node.green {
129                    let _ = GreenNode::from_raw(*ptr);
130                } else {
131                    unreachable!("a token cannot be a root");
132                }
133                break;
134            }
135        }
136    }
137}
138
139impl NodeData {
140    #[inline]
141    fn new(
142        parent: Option<SyntaxNode>,
143        index: u32,
144        offset: TextSize,
145        green: Green,
146    ) -> ptr::NonNull<NodeData> {
147        let parent = ManuallyDrop::new(parent);
148        let res = NodeData {
149            _c: Count::new(),
150            rc: Cell::new(1),
151            parent: parent.as_ref().map(|it| it.ptr),
152            index,
153            green,
154            offset,
155        };
156        unsafe { ptr::NonNull::new_unchecked(Box::into_raw(Box::new(res))) }
157    }
158
159    #[inline]
160    fn inc_rc(&self) {
161        let rc = match self.rc.get().checked_add(1) {
162            Some(it) => it,
163            None => std::process::abort(),
164        };
165        self.rc.set(rc)
166    }
167
168    #[inline]
169    fn dec_rc(&self) -> bool {
170        let rc = self.rc.get() - 1;
171        self.rc.set(rc);
172        rc == 0
173    }
174
175    #[inline]
176    fn key(&self) -> (ptr::NonNull<()>, TextSize) {
177        let ptr = match &self.green {
178            Green::Node { ptr } => ptr.cast(),
179            Green::Token { ptr } => ptr.cast(),
180        };
181        (ptr, self.offset())
182    }
183
184    #[inline]
185    fn parent_node(&self) -> Option<SyntaxNode> {
186        let parent = self.parent()?;
187        debug_assert!(matches!(parent.green, Green::Node { .. }));
188        parent.inc_rc();
189        Some(SyntaxNode { ptr: ptr::NonNull::from(parent) })
190    }
191
192    #[inline]
193    fn parent(&self) -> Option<&NodeData> {
194        self.parent.map(|it| unsafe { &*it.as_ptr() })
195    }
196
197    #[inline]
198    fn green(&self) -> GreenElementRef<'_> {
199        match &self.green {
200            Green::Node { ptr } => GreenElementRef::Node(unsafe { &*ptr.as_ptr() }),
201            Green::Token { ptr } => GreenElementRef::Token(unsafe { ptr.as_ref() }),
202        }
203    }
204    #[inline]
205    fn green_siblings(&self) -> slice::Iter<'_, GreenChild> {
206        match &self.parent().map(|it| &it.green) {
207            Some(Green::Node { ptr }) => unsafe { &*ptr.as_ptr() }.children().raw,
208            Some(Green::Token { .. }) => {
209                debug_assert!(false);
210                [].iter()
211            }
212            None => [].iter(),
213        }
214    }
215    #[inline]
216    fn index(&self) -> u32 {
217        self.index
218    }
219
220    #[inline]
221    fn offset(&self) -> TextSize {
222        self.offset
223    }
224
225    #[inline]
226    fn text_range(&self) -> TextRange {
227        let offset = self.offset();
228        let len = self.green().text_len();
229        TextRange::at(offset, len)
230    }
231
232    #[inline]
233    fn kind(&self) -> SyntaxKind {
234        self.green().kind()
235    }
236
237    fn next_sibling(&self) -> Option<SyntaxNode> {
238        let mut siblings = self.green_siblings().enumerate();
239        let index = self.index() as usize;
240
241        siblings.nth(index);
242        siblings.find_map(|(index, child)| {
243            child.as_ref().into_node().and_then(|green| {
244                let parent = self.parent_node()?;
245                let offset = parent.offset() + child.rel_offset();
246                Some(SyntaxNode::new_child(green, parent, index as u32, offset))
247            })
248        })
249    }
250    fn prev_sibling(&self) -> Option<SyntaxNode> {
251        let mut rev_siblings = self.green_siblings().enumerate().rev();
252        let index = rev_siblings.len().checked_sub(self.index() as usize + 1)?;
253
254        rev_siblings.nth(index);
255        rev_siblings.find_map(|(index, child)| {
256            child.as_ref().into_node().and_then(|green| {
257                let parent = self.parent_node()?;
258                let offset = parent.offset() + child.rel_offset();
259                Some(SyntaxNode::new_child(green, parent, index as u32, offset))
260            })
261        })
262    }
263
264    fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
265        let mut siblings = self.green_siblings().enumerate();
266        let index = self.index() as usize + 1;
267
268        siblings.nth(index).and_then(|(index, child)| {
269            let parent = self.parent_node()?;
270            let offset = parent.offset() + child.rel_offset();
271            Some(SyntaxElement::new(child.as_ref(), parent, index as u32, offset))
272        })
273    }
274    fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
275        let mut siblings = self.green_siblings().enumerate();
276        let index = self.index().checked_sub(1)? as usize;
277
278        siblings.nth(index).and_then(|(index, child)| {
279            let parent = self.parent_node()?;
280            let offset = parent.offset() + child.rel_offset();
281            Some(SyntaxElement::new(child.as_ref(), parent, index as u32, offset))
282        })
283    }
284}
285
286impl SyntaxNode {
287    pub fn new_root(green: GreenNode) -> SyntaxNode {
288        let green = GreenNode::into_raw(green);
289        let green = Green::Node { ptr: green };
290        SyntaxNode { ptr: NodeData::new(None, 0, 0.into(), green) }
291    }
292
293    fn new_child(
294        green: &GreenNodeData,
295        parent: SyntaxNode,
296        index: u32,
297        offset: TextSize,
298    ) -> SyntaxNode {
299        let green = Green::Node { ptr: green.into() };
300        SyntaxNode { ptr: NodeData::new(Some(parent), index, offset, green) }
301    }
302
303    pub fn clone_subtree(&self) -> SyntaxNode {
304        SyntaxNode::new_root(self.green().to_owned())
305    }
306
307    #[inline]
308    fn data(&self) -> &NodeData {
309        unsafe { self.ptr.as_ref() }
310    }
311
312    pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
313        assert_eq!(self.kind(), replacement.kind());
314        match &self.parent() {
315            None => replacement,
316            Some(parent) => {
317                let new_parent = parent
318                    .green_ref()
319                    .replace_child(self.data().index() as usize, replacement.into());
320                parent.replace_with(new_parent)
321            }
322        }
323    }
324
325    #[inline]
326    pub fn kind(&self) -> SyntaxKind {
327        self.data().kind()
328    }
329
330    #[inline]
331    fn offset(&self) -> TextSize {
332        self.data().offset()
333    }
334
335    #[inline]
336    pub fn text_range(&self) -> TextRange {
337        self.data().text_range()
338    }
339
340    #[inline]
341    pub fn index(&self) -> usize {
342        self.data().index() as usize
343    }
344
345    #[inline]
346    pub fn text(&self) -> SyntaxText {
347        SyntaxText::new(self.clone())
348    }
349
350    #[inline]
351    pub fn green(&self) -> &GreenNodeData {
352        self.green_ref()
353    }
354    #[inline]
355    fn green_ref(&self) -> &GreenNodeData {
356        self.data().green().into_node().unwrap()
357    }
358
359    #[inline]
360    pub fn parent(&self) -> Option<SyntaxNode> {
361        self.data().parent_node()
362    }
363
364    #[inline]
365    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
366        iter::successors(Some(self.clone()), SyntaxNode::parent)
367    }
368
369    #[inline]
370    pub fn tree_top(&self) -> SyntaxNode {
371        self.ancestors().last().unwrap()
372    }
373
374    #[inline]
375    pub fn children(&self) -> SyntaxNodeChildren {
376        SyntaxNodeChildren::new(self.clone())
377    }
378
379    #[inline]
380    pub fn children_with_tokens(&self) -> SyntaxElementChildren {
381        SyntaxElementChildren::new(self.clone())
382    }
383
384    pub fn first_child(&self) -> Option<SyntaxNode> {
385        self.green_ref().children().raw.enumerate().find_map(|(index, child)| {
386            child.as_ref().into_node().map(|green| {
387                SyntaxNode::new_child(
388                    green,
389                    self.clone(),
390                    index as u32,
391                    self.offset() + child.rel_offset(),
392                )
393            })
394        })
395    }
396    pub fn last_child(&self) -> Option<SyntaxNode> {
397        self.green_ref().children().raw.enumerate().rev().find_map(|(index, child)| {
398            child.as_ref().into_node().map(|green| {
399                SyntaxNode::new_child(
400                    green,
401                    self.clone(),
402                    index as u32,
403                    self.offset() + child.rel_offset(),
404                )
405            })
406        })
407    }
408
409    pub fn first_child_or_token(&self) -> Option<SyntaxElement> {
410        self.green_ref().children().raw.next().map(|child| {
411            SyntaxElement::new(child.as_ref(), self.clone(), 0, self.offset() + child.rel_offset())
412        })
413    }
414    pub fn last_child_or_token(&self) -> Option<SyntaxElement> {
415        self.green_ref().children().raw.enumerate().next_back().map(|(index, child)| {
416            SyntaxElement::new(
417                child.as_ref(),
418                self.clone(),
419                index as u32,
420                self.offset() + child.rel_offset(),
421            )
422        })
423    }
424
425    pub fn next_sibling(&self) -> Option<SyntaxNode> {
426        self.data().next_sibling()
427    }
428    pub fn prev_sibling(&self) -> Option<SyntaxNode> {
429        self.data().prev_sibling()
430    }
431
432    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
433        self.data().next_sibling_or_token()
434    }
435    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
436        self.data().prev_sibling_or_token()
437    }
438
439    pub fn first_token(&self) -> Option<SyntaxToken> {
440        self.first_child_or_token()?.first_token()
441    }
442    pub fn last_token(&self) -> Option<SyntaxToken> {
443        self.last_child_or_token()?.last_token()
444    }
445
446    #[inline]
447    pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode> {
448        iter::successors(Some(self.clone()), move |node| match direction {
449            Direction::Next => node.next_sibling(),
450            Direction::Prev => node.prev_sibling(),
451        })
452    }
453
454    #[inline]
455    pub fn siblings_with_tokens(
456        &self,
457        direction: Direction,
458    ) -> impl Iterator<Item = SyntaxElement> {
459        let me: SyntaxElement = self.clone().into();
460        iter::successors(Some(me), move |el| match direction {
461            Direction::Next => el.next_sibling_or_token(),
462            Direction::Prev => el.prev_sibling_or_token(),
463        })
464    }
465
466    #[inline]
467    pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode> {
468        self.preorder().filter_map(|event| match event {
469            WalkEvent::Enter(node) => Some(node),
470            WalkEvent::Leave(_) => None,
471        })
472    }
473
474    #[inline]
475    pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> {
476        self.preorder_with_tokens().filter_map(|event| match event {
477            WalkEvent::Enter(it) => Some(it),
478            WalkEvent::Leave(_) => None,
479        })
480    }
481
482    #[inline]
483    pub fn preorder(&self) -> Preorder {
484        Preorder::new(self.clone())
485    }
486
487    #[inline]
488    pub fn preorder_with_tokens(&self) -> PreorderWithTokens {
489        PreorderWithTokens::new(self.clone())
490    }
491
492    pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
493        // TODO: this could be faster if we first drill-down to node, and only
494        // then switch to token search. We should also replace explicit
495        // recursion with a loop.
496        let range = self.text_range();
497        assert!(
498            range.start() <= offset && offset <= range.end(),
499            "Bad offset: range {:?} offset {:?}",
500            range,
501            offset
502        );
503        if range.is_empty() {
504            return TokenAtOffset::None;
505        }
506
507        let mut children = self.children_with_tokens().filter(|child| {
508            let child_range = child.text_range();
509            !child_range.is_empty()
510                && (child_range.start() <= offset && offset <= child_range.end())
511        });
512
513        let left = children.next().unwrap();
514        let right = children.next();
515        assert!(children.next().is_none());
516
517        if let Some(right) = right {
518            match (left.token_at_offset(offset), right.token_at_offset(offset)) {
519                (TokenAtOffset::Single(left), TokenAtOffset::Single(right)) => {
520                    TokenAtOffset::Between(left, right)
521                }
522                _ => unreachable!(),
523            }
524        } else {
525            left.token_at_offset(offset)
526        }
527    }
528
529    pub fn covering_element(&self, range: TextRange) -> SyntaxElement {
530        let mut res: SyntaxElement = self.clone().into();
531        loop {
532            assert!(
533                res.text_range().contains_range(range),
534                "Bad range: node range {:?}, range {:?}",
535                res.text_range(),
536                range,
537            );
538            res = match &res {
539                NodeOrToken::Token(_) => return res,
540                NodeOrToken::Node(node) => match node.child_or_token_at_range(range) {
541                    Some(it) => it,
542                    None => return res,
543                },
544            };
545        }
546    }
547
548    pub fn child_or_token_at_range(&self, range: TextRange) -> Option<SyntaxElement> {
549        let rel_range = range - self.offset();
550        self.green_ref().child_at_range(rel_range).map(|(index, rel_offset, green)| {
551            SyntaxElement::new(green, self.clone(), index as u32, self.offset() + rel_offset)
552        })
553    }
554}
555
556impl SyntaxToken {
557    fn new(
558        green: &GreenTokenData,
559        parent: SyntaxNode,
560        index: u32,
561        offset: TextSize,
562    ) -> SyntaxToken {
563        let green = Green::Token { ptr: green.into() };
564        SyntaxToken { ptr: NodeData::new(Some(parent), index, offset, green) }
565    }
566
567    #[inline]
568    fn data(&self) -> &NodeData {
569        unsafe { self.ptr.as_ref() }
570    }
571
572    pub fn replace_with(&self, replacement: GreenToken) -> GreenNode {
573        assert_eq!(self.kind(), replacement.kind());
574        let parent = self.parent().unwrap();
575        let me: u32 = self.data().index();
576
577        let new_parent = parent.green_ref().replace_child(me as usize, replacement.into());
578        parent.replace_with(new_parent)
579    }
580
581    #[inline]
582    pub fn kind(&self) -> SyntaxKind {
583        self.data().kind()
584    }
585
586    #[inline]
587    pub fn text_range(&self) -> TextRange {
588        self.data().text_range()
589    }
590
591    #[inline]
592    pub fn index(&self) -> usize {
593        self.data().index() as usize
594    }
595
596    #[inline]
597    pub fn text(&self) -> &str {
598        match self.data().green().as_token() {
599            Some(it) => it.text(),
600            None => {
601                debug_assert!(
602                    false,
603                    "corrupted tree: a node thinks it is a token: {:?}",
604                    self.data().green().as_node().unwrap().to_string()
605                );
606                ""
607            }
608        }
609    }
610
611    #[inline]
612    pub fn green(&self) -> &GreenTokenData {
613        self.data().green().into_token().unwrap()
614    }
615
616    #[inline]
617    pub fn parent(&self) -> Option<SyntaxNode> {
618        self.data().parent_node()
619    }
620
621    #[inline]
622    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
623        std::iter::successors(self.parent(), SyntaxNode::parent)
624    }
625
626    #[inline]
627    pub fn tree_top(&self) -> SyntaxNode {
628        self.ancestors().last().unwrap()
629    }
630
631    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
632        self.data().next_sibling_or_token()
633    }
634    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
635        self.data().prev_sibling_or_token()
636    }
637
638    #[inline]
639    pub fn siblings_with_tokens(
640        &self,
641        direction: Direction,
642    ) -> impl Iterator<Item = SyntaxElement> {
643        let me: SyntaxElement = self.clone().into();
644        iter::successors(Some(me), move |el| match direction {
645            Direction::Next => el.next_sibling_or_token(),
646            Direction::Prev => el.prev_sibling_or_token(),
647        })
648    }
649
650    pub fn next_token(&self) -> Option<SyntaxToken> {
651        match self.next_sibling_or_token() {
652            Some(element) => element.first_token(),
653            None => self
654                .ancestors()
655                .find_map(|it| it.next_sibling_or_token())
656                .and_then(|element| element.first_token()),
657        }
658    }
659    pub fn prev_token(&self) -> Option<SyntaxToken> {
660        match self.prev_sibling_or_token() {
661            Some(element) => element.last_token(),
662            None => self
663                .ancestors()
664                .find_map(|it| it.prev_sibling_or_token())
665                .and_then(|element| element.last_token()),
666        }
667    }
668}
669
670impl SyntaxElement {
671    fn new(
672        element: GreenElementRef<'_>,
673        parent: SyntaxNode,
674        index: u32,
675        offset: TextSize,
676    ) -> SyntaxElement {
677        match element {
678            NodeOrToken::Node(node) => {
679                SyntaxNode::new_child(node, parent, index as u32, offset).into()
680            }
681            NodeOrToken::Token(token) => {
682                SyntaxToken::new(token, parent, index as u32, offset).into()
683            }
684        }
685    }
686
687    #[inline]
688    pub fn text_range(&self) -> TextRange {
689        match self {
690            NodeOrToken::Node(it) => it.text_range(),
691            NodeOrToken::Token(it) => it.text_range(),
692        }
693    }
694
695    #[inline]
696    pub fn index(&self) -> usize {
697        match self {
698            NodeOrToken::Node(it) => it.index(),
699            NodeOrToken::Token(it) => it.index(),
700        }
701    }
702
703    #[inline]
704    pub fn kind(&self) -> SyntaxKind {
705        match self {
706            NodeOrToken::Node(it) => it.kind(),
707            NodeOrToken::Token(it) => it.kind(),
708        }
709    }
710
711    #[inline]
712    pub fn parent(&self) -> Option<SyntaxNode> {
713        match self {
714            NodeOrToken::Node(it) => it.parent(),
715            NodeOrToken::Token(it) => it.parent(),
716        }
717    }
718
719    #[inline]
720    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
721        let first = match self {
722            NodeOrToken::Node(it) => Some(it.clone()),
723            NodeOrToken::Token(it) => it.parent(),
724        };
725        iter::successors(first, SyntaxNode::parent)
726    }
727
728    #[inline]
729    pub fn tree_top(&self) -> SyntaxNode {
730        match self {
731            NodeOrToken::Node(it) => it.tree_top(),
732            NodeOrToken::Token(it) => it.tree_top(),
733        }
734    }
735
736    pub fn first_token(&self) -> Option<SyntaxToken> {
737        match self {
738            NodeOrToken::Node(it) => it.first_token(),
739            NodeOrToken::Token(it) => Some(it.clone()),
740        }
741    }
742    pub fn last_token(&self) -> Option<SyntaxToken> {
743        match self {
744            NodeOrToken::Node(it) => it.last_token(),
745            NodeOrToken::Token(it) => Some(it.clone()),
746        }
747    }
748
749    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
750        match self {
751            NodeOrToken::Node(it) => it.next_sibling_or_token(),
752            NodeOrToken::Token(it) => it.next_sibling_or_token(),
753        }
754    }
755    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
756        match self {
757            NodeOrToken::Node(it) => it.prev_sibling_or_token(),
758            NodeOrToken::Token(it) => it.prev_sibling_or_token(),
759        }
760    }
761
762    fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
763        assert!(self.text_range().start() <= offset && offset <= self.text_range().end());
764        match self {
765            NodeOrToken::Token(token) => TokenAtOffset::Single(token.clone()),
766            NodeOrToken::Node(node) => node.token_at_offset(offset),
767        }
768    }
769}
770
771// region: impls
772
773// Identity semantics for hash & eq
774impl PartialEq for SyntaxNode {
775    #[inline]
776    fn eq(&self, other: &SyntaxNode) -> bool {
777        self.data().key() == other.data().key()
778    }
779}
780
781impl Eq for SyntaxNode {}
782
783impl Hash for SyntaxNode {
784    #[inline]
785    fn hash<H: Hasher>(&self, state: &mut H) {
786        self.data().key().hash(state);
787    }
788}
789
790impl fmt::Debug for SyntaxNode {
791    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
792        f.debug_struct("SyntaxNode")
793            .field("kind", &self.kind())
794            .field("text_range", &self.text_range())
795            .finish()
796    }
797}
798
799impl fmt::Display for SyntaxNode {
800    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
801        self.preorder_with_tokens()
802            .filter_map(|event| match event {
803                WalkEvent::Enter(NodeOrToken::Token(token)) => Some(token),
804                _ => None,
805            })
806            .try_for_each(|it| fmt::Display::fmt(&it, f))
807    }
808}
809
810// Identity semantics for hash & eq
811impl PartialEq for SyntaxToken {
812    #[inline]
813    fn eq(&self, other: &SyntaxToken) -> bool {
814        self.data().key() == other.data().key()
815    }
816}
817
818impl Eq for SyntaxToken {}
819
820impl Hash for SyntaxToken {
821    #[inline]
822    fn hash<H: Hasher>(&self, state: &mut H) {
823        self.data().key().hash(state);
824    }
825}
826
827impl fmt::Display for SyntaxToken {
828    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
829        fmt::Display::fmt(self.text(), f)
830    }
831}
832
833impl From<SyntaxNode> for SyntaxElement {
834    #[inline]
835    fn from(node: SyntaxNode) -> SyntaxElement {
836        NodeOrToken::Node(node)
837    }
838}
839
840impl From<SyntaxToken> for SyntaxElement {
841    #[inline]
842    fn from(token: SyntaxToken) -> SyntaxElement {
843        NodeOrToken::Token(token)
844    }
845}
846
847// endregion
848
849// region: iterators
850
851#[derive(Clone, Debug)]
852pub struct SyntaxNodeChildren {
853    next: Option<SyntaxNode>,
854}
855
856impl SyntaxNodeChildren {
857    fn new(parent: SyntaxNode) -> SyntaxNodeChildren {
858        SyntaxNodeChildren { next: parent.first_child() }
859    }
860}
861
862impl Iterator for SyntaxNodeChildren {
863    type Item = SyntaxNode;
864    fn next(&mut self) -> Option<SyntaxNode> {
865        self.next.take().map(|next| {
866            self.next = next.next_sibling();
867            next
868        })
869    }
870}
871
872#[derive(Clone, Debug)]
873pub struct SyntaxElementChildren {
874    next: Option<SyntaxElement>,
875}
876
877impl SyntaxElementChildren {
878    fn new(parent: SyntaxNode) -> SyntaxElementChildren {
879        SyntaxElementChildren { next: parent.first_child_or_token() }
880    }
881}
882
883impl Iterator for SyntaxElementChildren {
884    type Item = SyntaxElement;
885    fn next(&mut self) -> Option<SyntaxElement> {
886        self.next.take().map(|next| {
887            self.next = next.next_sibling_or_token();
888            next
889        })
890    }
891}
892
893#[derive(Debug, Clone)]
894pub struct Preorder {
895    start: SyntaxNode,
896    next: Option<WalkEvent<SyntaxNode>>,
897    skip_subtree: bool,
898}
899
900impl Preorder {
901    fn new(start: SyntaxNode) -> Preorder {
902        let next = Some(WalkEvent::Enter(start.clone()));
903        Preorder { start, next, skip_subtree: false }
904    }
905
906    pub fn skip_subtree(&mut self) {
907        self.skip_subtree = true;
908    }
909
910    #[cold]
911    fn do_skip(&mut self) {
912        self.next = self.next.take().map(|next| match next {
913            WalkEvent::Enter(first_child) => WalkEvent::Leave(first_child.parent().unwrap()),
914            WalkEvent::Leave(parent) => WalkEvent::Leave(parent),
915        })
916    }
917}
918
919impl Iterator for Preorder {
920    type Item = WalkEvent<SyntaxNode>;
921
922    fn next(&mut self) -> Option<WalkEvent<SyntaxNode>> {
923        if self.skip_subtree {
924            self.do_skip();
925            self.skip_subtree = false;
926        }
927        let next = self.next.take();
928        self.next = next.as_ref().and_then(|next| {
929            Some(match next {
930                WalkEvent::Enter(node) => match node.first_child() {
931                    Some(child) => WalkEvent::Enter(child),
932                    None => WalkEvent::Leave(node.clone()),
933                },
934                WalkEvent::Leave(node) => {
935                    if node == &self.start {
936                        return None;
937                    }
938                    match node.next_sibling() {
939                        Some(sibling) => WalkEvent::Enter(sibling),
940                        None => WalkEvent::Leave(node.parent()?),
941                    }
942                }
943            })
944        });
945        next
946    }
947}
948
949#[derive(Debug, Clone)]
950pub struct PreorderWithTokens {
951    start: SyntaxElement,
952    next: Option<WalkEvent<SyntaxElement>>,
953    skip_subtree: bool,
954}
955
956impl PreorderWithTokens {
957    fn new(start: SyntaxNode) -> PreorderWithTokens {
958        let next = Some(WalkEvent::Enter(start.clone().into()));
959        PreorderWithTokens { start: start.into(), next, skip_subtree: false }
960    }
961
962    pub fn skip_subtree(&mut self) {
963        self.skip_subtree = true;
964    }
965
966    #[cold]
967    fn do_skip(&mut self) {
968        self.next = self.next.take().map(|next| match next {
969            WalkEvent::Enter(first_child) => WalkEvent::Leave(first_child.parent().unwrap().into()),
970            WalkEvent::Leave(parent) => WalkEvent::Leave(parent),
971        })
972    }
973}
974
975impl Iterator for PreorderWithTokens {
976    type Item = WalkEvent<SyntaxElement>;
977
978    fn next(&mut self) -> Option<WalkEvent<SyntaxElement>> {
979        if self.skip_subtree {
980            self.do_skip();
981            self.skip_subtree = false;
982        }
983        let next = self.next.take();
984        self.next = next.as_ref().and_then(|next| {
985            Some(match next {
986                WalkEvent::Enter(el) => match el {
987                    NodeOrToken::Node(node) => match node.first_child_or_token() {
988                        Some(child) => WalkEvent::Enter(child),
989                        None => WalkEvent::Leave(node.clone().into()),
990                    },
991                    NodeOrToken::Token(token) => WalkEvent::Leave(token.clone().into()),
992                },
993                WalkEvent::Leave(el) if el == &self.start => return None,
994                WalkEvent::Leave(el) => match el.next_sibling_or_token() {
995                    Some(sibling) => WalkEvent::Enter(sibling),
996                    None => WalkEvent::Leave(el.parent()?.into()),
997                },
998            })
999        });
1000        next
1001    }
1002}
1003// endregion