Skip to main content

rslint_rowan/
api.rs

1use std::{fmt, marker::PhantomData};
2
3use crate::{
4    cursor, Direction, GreenNode, GreenToken, NodeOrToken, SmolStr, SyntaxKind, SyntaxText,
5    TextRange, TextSize, TokenAtOffset, WalkEvent,
6};
7
8pub trait Language: Sized + Clone + Copy + fmt::Debug + Eq + Ord + std::hash::Hash {
9    type Kind: fmt::Debug;
10
11    fn kind_from_raw(raw: SyntaxKind) -> Self::Kind;
12    fn kind_to_raw(kind: Self::Kind) -> SyntaxKind;
13}
14
15#[derive(Clone, PartialEq, Eq, Hash)]
16pub struct SyntaxNode<L: Language> {
17    raw: cursor::SyntaxNode,
18    _p: PhantomData<L>,
19}
20
21impl<L: Language> From<cursor::SyntaxNode> for SyntaxNode<L> {
22    fn from(raw: cursor::SyntaxNode) -> SyntaxNode<L> {
23        SyntaxNode { raw, _p: PhantomData }
24    }
25}
26
27impl<L: Language> From<SyntaxNode<L>> for cursor::SyntaxNode {
28    fn from(node: SyntaxNode<L>) -> cursor::SyntaxNode {
29        node.raw
30    }
31}
32
33impl<L: Language> fmt::Debug for SyntaxNode<L> {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        if f.alternate() {
36            let mut level = 0;
37            for event in self.preorder_with_tokens() {
38                match event {
39                    WalkEvent::Enter(element) => {
40                        for _ in 0..level {
41                            write!(f, "  ")?;
42                        }
43                        match element {
44                            NodeOrToken::Node(node) => writeln!(f, "{:?}", node)?,
45                            NodeOrToken::Token(token) => writeln!(f, "{:?}", token)?,
46                        }
47                        level += 1;
48                    }
49                    WalkEvent::Leave(_) => level -= 1,
50                }
51            }
52            assert_eq!(level, 0);
53            Ok(())
54        } else {
55            write!(f, "{:?}@{:?}", self.kind(), self.text_range())
56        }
57    }
58}
59
60impl<L: Language> fmt::Display for SyntaxNode<L> {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        fmt::Display::fmt(&self.raw, f)
63    }
64}
65
66#[derive(Clone, PartialEq, Eq, Hash)]
67pub struct SyntaxToken<L: Language> {
68    raw: cursor::SyntaxToken,
69    _p: PhantomData<L>,
70}
71
72impl<L: Language> From<cursor::SyntaxToken> for SyntaxToken<L> {
73    fn from(raw: cursor::SyntaxToken) -> SyntaxToken<L> {
74        SyntaxToken { raw, _p: PhantomData }
75    }
76}
77
78impl<L: Language> From<SyntaxToken<L>> for cursor::SyntaxToken {
79    fn from(token: SyntaxToken<L>) -> cursor::SyntaxToken {
80        token.raw
81    }
82}
83
84impl<L: Language> fmt::Debug for SyntaxToken<L> {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        write!(f, "{:?}@{:?}", self.kind(), self.text_range())?;
87        if self.text().len() < 25 {
88            return write!(f, " {:?}", self.text());
89        }
90        let text = self.text().as_str();
91        for idx in 21..25 {
92            if text.is_char_boundary(idx) {
93                let text = format!("{} ...", &text[..idx]);
94                return write!(f, " {:?}", text);
95            }
96        }
97        unreachable!()
98    }
99}
100
101impl<L: Language> fmt::Display for SyntaxToken<L> {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        fmt::Display::fmt(&self.raw, f)
104    }
105}
106
107pub type SyntaxElement<L> = NodeOrToken<SyntaxNode<L>, SyntaxToken<L>>;
108
109impl<L: Language> From<cursor::SyntaxElement> for SyntaxElement<L> {
110    fn from(raw: cursor::SyntaxElement) -> SyntaxElement<L> {
111        match raw {
112            NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
113            NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
114        }
115    }
116}
117
118impl<L: Language> From<SyntaxElement<L>> for cursor::SyntaxElement {
119    fn from(element: SyntaxElement<L>) -> cursor::SyntaxElement {
120        match element {
121            NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
122            NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
123        }
124    }
125}
126
127impl<L: Language> From<SyntaxNode<L>> for SyntaxElement<L> {
128    fn from(node: SyntaxNode<L>) -> SyntaxElement<L> {
129        NodeOrToken::Node(node)
130    }
131}
132
133impl<L: Language> From<SyntaxToken<L>> for SyntaxElement<L> {
134    fn from(token: SyntaxToken<L>) -> SyntaxElement<L> {
135        NodeOrToken::Token(token)
136    }
137}
138
139impl<L: Language> fmt::Display for SyntaxElement<L> {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        match self {
142            NodeOrToken::Node(it) => fmt::Display::fmt(it, f),
143            NodeOrToken::Token(it) => fmt::Display::fmt(it, f),
144        }
145    }
146}
147
148impl<L: Language> SyntaxNode<L> {
149    pub fn new_root(green: GreenNode) -> SyntaxNode<L> {
150        SyntaxNode::from(cursor::SyntaxNode::new_root(green))
151    }
152    pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
153        self.raw.replace_with(replacement)
154    }
155
156    pub fn kind(&self) -> L::Kind {
157        L::kind_from_raw(self.raw.kind())
158    }
159
160    pub fn text_range(&self) -> TextRange {
161        self.raw.text_range()
162    }
163
164    pub fn text(&self) -> SyntaxText {
165        self.raw.text()
166    }
167
168    pub fn green(&self) -> &GreenNode {
169        self.raw.green()
170    }
171
172    pub fn parent(&self) -> Option<SyntaxNode<L>> {
173        self.raw.parent().map(Self::from)
174    }
175
176    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> {
177        self.raw.ancestors().map(SyntaxNode::from)
178    }
179
180    pub fn children(&self) -> SyntaxNodeChildren<L> {
181        SyntaxNodeChildren { raw: self.raw.children(), _p: PhantomData }
182    }
183
184    pub fn children_with_tokens(&self) -> SyntaxElementChildren<L> {
185        SyntaxElementChildren { raw: self.raw.children_with_tokens(), _p: PhantomData }
186    }
187
188    pub fn first_child(&self) -> Option<SyntaxNode<L>> {
189        self.raw.first_child().map(Self::from)
190    }
191
192    pub fn first_child_or_token(&self) -> Option<SyntaxElement<L>> {
193        self.raw.first_child_or_token().map(NodeOrToken::from)
194    }
195
196    pub fn last_child(&self) -> Option<SyntaxNode<L>> {
197        self.raw.last_child().map(Self::from)
198    }
199
200    pub fn last_child_or_token(&self) -> Option<SyntaxElement<L>> {
201        self.raw.last_child_or_token().map(NodeOrToken::from)
202    }
203
204    pub fn next_sibling(&self) -> Option<SyntaxNode<L>> {
205        self.raw.next_sibling().map(Self::from)
206    }
207
208    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
209        self.raw.next_sibling_or_token().map(NodeOrToken::from)
210    }
211
212    pub fn prev_sibling(&self) -> Option<SyntaxNode<L>> {
213        self.raw.prev_sibling().map(Self::from)
214    }
215
216    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
217        self.raw.prev_sibling_or_token().map(NodeOrToken::from)
218    }
219
220    pub fn first_token(&self) -> Option<SyntaxToken<L>> {
221        self.raw.first_token().map(SyntaxToken::from)
222    }
223
224    pub fn last_token(&self) -> Option<SyntaxToken<L>> {
225        self.raw.last_token().map(SyntaxToken::from)
226    }
227
228    pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode<L>> {
229        self.raw.siblings(direction).map(SyntaxNode::from)
230    }
231
232    pub fn siblings_with_tokens(
233        &self,
234        direction: Direction,
235    ) -> impl Iterator<Item = SyntaxElement<L>> {
236        self.raw.siblings_with_tokens(direction).map(SyntaxElement::from)
237    }
238
239    pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode<L>> {
240        self.raw.descendants().map(SyntaxNode::from)
241    }
242
243    pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement<L>> {
244        self.raw.descendants_with_tokens().map(NodeOrToken::from)
245    }
246
247    pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode<L>>> {
248        self.raw.preorder().map(|event| event.map(SyntaxNode::from))
249    }
250
251    pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement<L>>> {
252        self.raw.preorder_with_tokens().map(|event| event.map(NodeOrToken::from))
253    }
254
255    pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken<L>> {
256        self.raw.token_at_offset(offset).map(SyntaxToken::from)
257    }
258
259    pub fn covering_element(&self, range: TextRange) -> SyntaxElement<L> {
260        NodeOrToken::from(self.raw.covering_element(range))
261    }
262}
263
264impl<L: Language> SyntaxToken<L> {
265    pub fn replace_with(&self, new_token: GreenToken) -> GreenNode {
266        self.raw.replace_with(new_token)
267    }
268
269    pub fn kind(&self) -> L::Kind {
270        L::kind_from_raw(self.raw.kind())
271    }
272
273    pub fn text_range(&self) -> TextRange {
274        self.raw.text_range()
275    }
276
277    pub fn text(&self) -> &SmolStr {
278        self.raw.text()
279    }
280
281    pub fn green(&self) -> &GreenToken {
282        self.raw.green()
283    }
284
285    pub fn parent(&self) -> SyntaxNode<L> {
286        SyntaxNode::from(self.raw.parent())
287    }
288
289    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> {
290        self.raw.ancestors().map(SyntaxNode::from)
291    }
292
293    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
294        self.raw.next_sibling_or_token().map(NodeOrToken::from)
295    }
296
297    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
298        self.raw.prev_sibling_or_token().map(NodeOrToken::from)
299    }
300
301    pub fn siblings_with_tokens(
302        &self,
303        direction: Direction,
304    ) -> impl Iterator<Item = SyntaxElement<L>> {
305        self.raw.siblings_with_tokens(direction).map(SyntaxElement::from)
306    }
307
308    pub fn next_token(&self) -> Option<SyntaxToken<L>> {
309        self.raw.next_token().map(SyntaxToken::from)
310    }
311
312    pub fn prev_token(&self) -> Option<SyntaxToken<L>> {
313        self.raw.prev_token().map(SyntaxToken::from)
314    }
315}
316
317impl<L: Language> SyntaxElement<L> {
318    pub fn text_range(&self) -> TextRange {
319        match self {
320            NodeOrToken::Node(it) => it.text_range(),
321            NodeOrToken::Token(it) => it.text_range(),
322        }
323    }
324
325    pub fn kind(&self) -> L::Kind {
326        match self {
327            NodeOrToken::Node(it) => it.kind(),
328            NodeOrToken::Token(it) => it.kind(),
329        }
330    }
331
332    pub fn parent(&self) -> Option<SyntaxNode<L>> {
333        match self {
334            NodeOrToken::Node(it) => it.parent(),
335            NodeOrToken::Token(it) => Some(it.parent()),
336        }
337    }
338
339    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> {
340        match self {
341            NodeOrToken::Node(it) => it.ancestors(),
342            NodeOrToken::Token(it) => it.parent().ancestors(),
343        }
344    }
345
346    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
347        match self {
348            NodeOrToken::Node(it) => it.next_sibling_or_token(),
349            NodeOrToken::Token(it) => it.next_sibling_or_token(),
350        }
351    }
352
353    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
354        match self {
355            NodeOrToken::Node(it) => it.prev_sibling_or_token(),
356            NodeOrToken::Token(it) => it.prev_sibling_or_token(),
357        }
358    }
359}
360
361#[derive(Debug, Clone)]
362pub struct SyntaxNodeChildren<L: Language> {
363    raw: cursor::SyntaxNodeChildren,
364    _p: PhantomData<L>,
365}
366
367impl<L: Language> Iterator for SyntaxNodeChildren<L> {
368    type Item = SyntaxNode<L>;
369    fn next(&mut self) -> Option<Self::Item> {
370        self.raw.next().map(SyntaxNode::from)
371    }
372}
373
374#[derive(Debug, Clone)]
375pub struct SyntaxElementChildren<L: Language> {
376    raw: cursor::SyntaxElementChildren,
377    _p: PhantomData<L>,
378}
379
380impl<L: Language> Iterator for SyntaxElementChildren<L> {
381    type Item = SyntaxElement<L>;
382    fn next(&mut self) -> Option<Self::Item> {
383        self.raw.next().map(NodeOrToken::from)
384    }
385}