biome_rowan/cursor/
element.rs1use 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
113impl 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