biome_rowan/cursor/
element.rs

1use crate::cursor::{SyntaxNode, SyntaxToken};
2use crate::green::{GreenElement, GreenElementRef};
3use crate::{NodeOrToken, RawSyntaxKind, TokenAtOffset};
4use biome_text_size::{TextRange, TextSize};
5use std::iter;
6
7pub(crate) type SyntaxElement = NodeOrToken<SyntaxNode, SyntaxToken>;
8
9impl SyntaxElement {
10    pub(super) fn new(
11        element: GreenElementRef<'_>,
12        parent: SyntaxNode,
13        slot: u32,
14        offset: TextSize,
15    ) -> SyntaxElement {
16        match element {
17            NodeOrToken::Node(node) => SyntaxNode::new_child(node, parent, slot, offset).into(),
18            NodeOrToken::Token(token) => SyntaxToken::new(token, parent, slot, offset).into(),
19        }
20    }
21
22    #[inline]
23    pub fn text_range(&self) -> TextRange {
24        match self {
25            NodeOrToken::Node(it) => it.text_range(),
26            NodeOrToken::Token(it) => it.text_range(),
27        }
28    }
29
30    #[inline]
31    pub fn index(&self) -> usize {
32        match self {
33            NodeOrToken::Node(it) => it.index(),
34            NodeOrToken::Token(it) => it.index(),
35        }
36    }
37
38    #[inline]
39    pub fn kind(&self) -> RawSyntaxKind {
40        match self {
41            NodeOrToken::Node(it) => it.kind(),
42            NodeOrToken::Token(it) => it.kind(),
43        }
44    }
45
46    #[inline]
47    pub fn parent(&self) -> Option<SyntaxNode> {
48        match self {
49            NodeOrToken::Node(it) => it.parent(),
50            NodeOrToken::Token(it) => it.parent(),
51        }
52    }
53
54    #[inline]
55    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
56        let first = match self {
57            NodeOrToken::Node(it) => Some(it.clone()),
58            NodeOrToken::Token(it) => it.parent(),
59        };
60        iter::successors(first, SyntaxNode::parent)
61    }
62
63    pub fn first_token(&self) -> Option<SyntaxToken> {
64        match self {
65            NodeOrToken::Node(it) => it.first_token(),
66            NodeOrToken::Token(it) => Some(it.clone()),
67        }
68    }
69    pub fn last_token(&self) -> Option<SyntaxToken> {
70        match self {
71            NodeOrToken::Node(it) => it.last_token(),
72            NodeOrToken::Token(it) => Some(it.clone()),
73        }
74    }
75
76    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
77        match self {
78            NodeOrToken::Node(it) => it.next_sibling_or_token(),
79            NodeOrToken::Token(it) => it.next_sibling_or_token(),
80        }
81    }
82    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
83        match self {
84            NodeOrToken::Node(it) => it.prev_sibling_or_token(),
85            NodeOrToken::Token(it) => it.prev_sibling_or_token(),
86        }
87    }
88
89    pub(super) fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
90        assert!(self.text_range().start() <= offset && offset <= self.text_range().end());
91        match self {
92            NodeOrToken::Token(token) => TokenAtOffset::Single(token.clone()),
93            NodeOrToken::Node(node) => node.token_at_offset(offset),
94        }
95    }
96
97    #[must_use = "syntax elements are immutable, the result of update methods must be propagated to have any effect"]
98    pub fn detach(self) -> Self {
99        match self {
100            NodeOrToken::Node(it) => Self::Node(it.detach()),
101            NodeOrToken::Token(it) => Self::Token(it.detach()),
102        }
103    }
104
105    pub(crate) fn into_green(self) -> GreenElement {
106        match self {
107            NodeOrToken::Node(it) => it.ptr.into_green(),
108            NodeOrToken::Token(it) => it.into_green(),
109        }
110    }
111}
112
113// region: impls
114
115impl From<SyntaxNode> for SyntaxElement {
116    #[inline]
117    fn from(node: SyntaxNode) -> SyntaxElement {
118        NodeOrToken::Node(node)
119    }
120}
121
122impl From<SyntaxToken> for SyntaxElement {
123    #[inline]
124    fn from(token: SyntaxToken) -> SyntaxElement {
125        NodeOrToken::Token(token)
126    }
127}
128
129// endregion