Skip to main content

miden_rowan/
api.rs

1use alloc::borrow::Cow;
2use core::{fmt, hash::Hash, iter, marker::PhantomData, ops::Range};
3
4use crate::{
5    Direction, GreenNode, GreenNodeData, GreenToken, NodeOrToken, SyntaxKind, SyntaxText,
6    TextRange, TextSize, TokenAtOffset, WalkEvent, cursor, green::GreenTokenData,
7};
8
9pub trait Language: Sized + Copy + fmt::Debug + Eq + Ord + Hash {
10    type Kind: Sized + Copy + fmt::Debug + Eq + Ord + Hash;
11
12    fn kind_from_raw(raw: SyntaxKind) -> Self::Kind;
13    fn kind_to_raw(kind: Self::Kind) -> SyntaxKind;
14}
15
16#[derive(Clone, PartialEq, Eq, Hash)]
17pub struct SyntaxNode<L: Language> {
18    raw: cursor::SyntaxNode,
19    _p: PhantomData<L>,
20}
21
22#[derive(Clone, PartialEq, Eq, Hash)]
23pub struct SyntaxToken<L: Language> {
24    raw: cursor::SyntaxToken,
25    _p: PhantomData<L>,
26}
27
28pub type SyntaxElement<L> = NodeOrToken<SyntaxNode<L>, SyntaxToken<L>>;
29
30impl<L: Language> fmt::Debug for SyntaxNode<L> {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        if f.alternate() {
33            let mut level = 0;
34            for event in self.preorder_with_tokens() {
35                match event {
36                    WalkEvent::Enter(element) => {
37                        for _ in 0..level {
38                            write!(f, "  ")?;
39                        }
40                        match element {
41                            NodeOrToken::Node(node) => writeln!(f, "{:?}", node)?,
42                            NodeOrToken::Token(token) => writeln!(f, "{:?}", token)?,
43                        }
44                        level += 1;
45                    }
46                    WalkEvent::Leave(_) => level -= 1,
47                }
48            }
49            assert_eq!(level, 0);
50            Ok(())
51        } else {
52            write!(f, "{:?}@{:?}", self.kind(), self.text_range())
53        }
54    }
55}
56
57impl<L: Language> fmt::Display for SyntaxNode<L> {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        fmt::Display::fmt(&self.raw, f)
60    }
61}
62
63impl<L: Language> fmt::Debug for SyntaxToken<L> {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        write!(f, "{:?}@{:?}", self.kind(), self.text_range())?;
66        if self.text().len() < 25 {
67            return write!(f, " {:?}", self.text());
68        }
69        let text = self.text();
70        for idx in 21..25 {
71            if text.is_char_boundary(idx) {
72                let text = alloc::format!("{} ...", &text[..idx]);
73                return write!(f, " {:?}", text);
74            }
75        }
76        unreachable!()
77    }
78}
79
80impl<L: Language> fmt::Display for SyntaxToken<L> {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        fmt::Display::fmt(&self.raw, f)
83    }
84}
85
86impl<L: Language> From<SyntaxNode<L>> for SyntaxElement<L> {
87    fn from(node: SyntaxNode<L>) -> SyntaxElement<L> {
88        NodeOrToken::Node(node)
89    }
90}
91
92impl<L: Language> From<SyntaxToken<L>> for SyntaxElement<L> {
93    fn from(token: SyntaxToken<L>) -> SyntaxElement<L> {
94        NodeOrToken::Token(token)
95    }
96}
97
98impl<L: Language> SyntaxNode<L> {
99    pub fn new_root(green: GreenNode) -> SyntaxNode<L> {
100        SyntaxNode::from(cursor::SyntaxNode::new_root(green))
101    }
102    pub fn new_root_mut(green: GreenNode) -> SyntaxNode<L> {
103        SyntaxNode::from(cursor::SyntaxNode::new_root_mut(green))
104    }
105
106    /// Returns a green tree, equal to the green tree this node
107    /// belongs to, except with this node substituted. The complexity
108    /// of the operation is proportional to the depth of the tree.
109    pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
110        self.raw.replace_with(replacement)
111    }
112
113    pub fn kind(&self) -> L::Kind {
114        L::kind_from_raw(self.raw.kind())
115    }
116
117    pub fn text_range(&self) -> TextRange {
118        self.raw.text_range()
119    }
120
121    pub fn index(&self) -> usize {
122        self.raw.index()
123    }
124
125    pub fn text(&self) -> SyntaxText {
126        self.raw.text()
127    }
128
129    pub fn green(&self) -> Cow<'_, GreenNodeData> {
130        self.raw.green()
131    }
132
133    pub fn parent(&self) -> Option<SyntaxNode<L>> {
134        self.raw.parent().map(Self::from)
135    }
136
137    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
138        self.raw.ancestors().map(SyntaxNode::from)
139    }
140
141    pub fn children(&self) -> SyntaxNodeChildren<L> {
142        SyntaxNodeChildren { raw: self.raw.children(), _p: PhantomData }
143    }
144
145    pub fn children_with_tokens(&self) -> SyntaxElementChildren<L> {
146        SyntaxElementChildren { raw: self.raw.children_with_tokens(), _p: PhantomData }
147    }
148
149    pub fn first_child(&self) -> Option<SyntaxNode<L>> {
150        self.raw.first_child().map(Self::from)
151    }
152
153    pub fn first_child_by_kind(&self, matcher: &impl Fn(L::Kind) -> bool) -> Option<SyntaxNode<L>> {
154        self.raw
155            .first_child_by_kind(&|raw_kind| matcher(L::kind_from_raw(raw_kind)))
156            .map(Self::from)
157    }
158
159    pub fn last_child(&self) -> Option<SyntaxNode<L>> {
160        self.raw.last_child().map(Self::from)
161    }
162
163    pub fn first_child_or_token(&self) -> Option<SyntaxElement<L>> {
164        self.raw.first_child_or_token().map(NodeOrToken::from)
165    }
166
167    pub fn first_child_or_token_by_kind(
168        &self,
169        matcher: &impl Fn(L::Kind) -> bool,
170    ) -> Option<SyntaxElement<L>> {
171        self.raw
172            .first_child_or_token_by_kind(&|raw_kind| matcher(L::kind_from_raw(raw_kind)))
173            .map(NodeOrToken::from)
174    }
175
176    pub fn last_child_or_token(&self) -> Option<SyntaxElement<L>> {
177        self.raw.last_child_or_token().map(NodeOrToken::from)
178    }
179
180    pub fn next_sibling(&self) -> Option<SyntaxNode<L>> {
181        self.raw.next_sibling().map(Self::from)
182    }
183
184    pub fn next_sibling_by_kind(
185        &self,
186        matcher: &impl Fn(L::Kind) -> bool,
187    ) -> Option<SyntaxNode<L>> {
188        self.raw
189            .next_sibling_by_kind(&|raw_kind| matcher(L::kind_from_raw(raw_kind)))
190            .map(Self::from)
191    }
192
193    pub fn prev_sibling(&self) -> Option<SyntaxNode<L>> {
194        self.raw.prev_sibling().map(Self::from)
195    }
196
197    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
198        self.raw.next_sibling_or_token().map(NodeOrToken::from)
199    }
200
201    pub fn next_sibling_or_token_by_kind(
202        &self,
203        matcher: &impl Fn(L::Kind) -> bool,
204    ) -> Option<SyntaxElement<L>> {
205        self.raw
206            .next_sibling_or_token_by_kind(&|raw_kind| matcher(L::kind_from_raw(raw_kind)))
207            .map(NodeOrToken::from)
208    }
209
210    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
211        self.raw.prev_sibling_or_token().map(NodeOrToken::from)
212    }
213
214    /// Return the leftmost token in the subtree of this node.
215    pub fn first_token(&self) -> Option<SyntaxToken<L>> {
216        self.raw.first_token().map(SyntaxToken::from)
217    }
218    /// Return the rightmost token in the subtree of this node.
219    pub fn last_token(&self) -> Option<SyntaxToken<L>> {
220        self.raw.last_token().map(SyntaxToken::from)
221    }
222
223    pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
224        self.raw.siblings(direction).map(SyntaxNode::from)
225    }
226
227    pub fn siblings_with_tokens(
228        &self,
229        direction: Direction,
230    ) -> impl Iterator<Item = SyntaxElement<L>> {
231        self.raw.siblings_with_tokens(direction).map(SyntaxElement::from)
232    }
233
234    pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
235        self.raw.descendants().map(SyntaxNode::from)
236    }
237
238    pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement<L>> + use<L> {
239        self.raw.descendants_with_tokens().map(NodeOrToken::from)
240    }
241
242    /// Traverse the subtree rooted at the current node (including the current
243    /// node) in preorder, excluding tokens.
244    pub fn preorder(&self) -> Preorder<L> {
245        Preorder { raw: self.raw.preorder(), _p: PhantomData }
246    }
247
248    /// Traverse the subtree rooted at the current node (including the current
249    /// node) in preorder, including tokens.
250    pub fn preorder_with_tokens(&self) -> PreorderWithTokens<L> {
251        PreorderWithTokens { raw: self.raw.preorder_with_tokens(), _p: PhantomData }
252    }
253
254    /// Find a token in the subtree corresponding to this node, which covers the offset.
255    /// Precondition: offset must be within node's range.
256    pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken<L>> {
257        self.raw.token_at_offset(offset).map(SyntaxToken::from)
258    }
259
260    /// Return the deepest node or token in the current subtree that fully
261    /// contains the range. If the range is empty and is contained in two leaf
262    /// nodes, either one can be returned. Precondition: range must be contained
263    /// within the current node
264    pub fn covering_element(&self, range: TextRange) -> SyntaxElement<L> {
265        NodeOrToken::from(self.raw.covering_element(range))
266    }
267
268    /// Finds a [`SyntaxElement`] which intersects with a given `range`. If
269    /// there are several intersecting elements, any one can be returned.
270    ///
271    /// The method uses binary search internally, so it's complexity is
272    /// `O(log(N))` where `N = self.children_with_tokens().count()`.
273    pub fn child_or_token_at_range(&self, range: TextRange) -> Option<SyntaxElement<L>> {
274        self.raw.child_or_token_at_range(range).map(SyntaxElement::from)
275    }
276
277    /// Returns an independent copy of the subtree rooted at this node.
278    ///
279    /// The parent of the returned node will be `None`, the start offset will be
280    /// zero, but, otherwise, it'll be equivalent to the source node.
281    pub fn clone_subtree(&self) -> SyntaxNode<L> {
282        SyntaxNode::from(self.raw.clone_subtree())
283    }
284
285    pub fn clone_for_update(&self) -> SyntaxNode<L> {
286        SyntaxNode::from(self.raw.clone_for_update())
287    }
288
289    pub fn is_mutable(&self) -> bool {
290        self.raw.is_mutable()
291    }
292
293    pub fn detach(&self) {
294        self.raw.detach()
295    }
296
297    pub fn splice_children<I: IntoIterator<Item = SyntaxElement<L>>>(
298        &self,
299        to_delete: Range<usize>,
300        to_insert: I,
301    ) {
302        let to_insert = to_insert.into_iter().map(cursor::SyntaxElement::from);
303        self.raw.splice_children(to_delete, to_insert)
304    }
305}
306
307impl<L: Language> SyntaxToken<L> {
308    /// Returns a green tree, equal to the green tree this token
309    /// belongs to, except with this token substituted. The complexity
310    /// of the operation is proportional to the depth of the tree.
311    pub fn replace_with(&self, new_token: GreenToken) -> GreenNode {
312        self.raw.replace_with(new_token)
313    }
314
315    pub fn kind(&self) -> L::Kind {
316        L::kind_from_raw(self.raw.kind())
317    }
318
319    pub fn text_range(&self) -> TextRange {
320        self.raw.text_range()
321    }
322
323    pub fn index(&self) -> usize {
324        self.raw.index()
325    }
326
327    pub fn text(&self) -> &str {
328        self.raw.text()
329    }
330
331    pub fn green(&self) -> &GreenTokenData {
332        self.raw.green()
333    }
334
335    pub fn parent(&self) -> Option<SyntaxNode<L>> {
336        self.raw.parent().map(SyntaxNode::from)
337    }
338
339    /// Iterator over all the ancestors of this token excluding itself.
340    #[deprecated = "use `SyntaxToken::parent_ancestors` instead"]
341    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
342        self.parent_ancestors()
343    }
344
345    /// Iterator over all the ancestors of this token excluding itself.
346    pub fn parent_ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
347        self.raw.ancestors().map(SyntaxNode::from)
348    }
349
350    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
351        self.raw.next_sibling_or_token().map(NodeOrToken::from)
352    }
353    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
354        self.raw.prev_sibling_or_token().map(NodeOrToken::from)
355    }
356
357    pub fn siblings_with_tokens(
358        &self,
359        direction: Direction,
360    ) -> impl Iterator<Item = SyntaxElement<L>> + use<L> {
361        self.raw.siblings_with_tokens(direction).map(SyntaxElement::from)
362    }
363
364    /// Next token in the tree (i.e, not necessary a sibling).
365    pub fn next_token(&self) -> Option<SyntaxToken<L>> {
366        self.raw.next_token().map(SyntaxToken::from)
367    }
368    /// Previous token in the tree (i.e, not necessary a sibling).
369    pub fn prev_token(&self) -> Option<SyntaxToken<L>> {
370        self.raw.prev_token().map(SyntaxToken::from)
371    }
372
373    pub fn detach(&self) {
374        self.raw.detach()
375    }
376}
377
378impl<L: Language> SyntaxElement<L> {
379    pub fn text_range(&self) -> TextRange {
380        match self {
381            NodeOrToken::Node(it) => it.text_range(),
382            NodeOrToken::Token(it) => it.text_range(),
383        }
384    }
385
386    pub fn index(&self) -> usize {
387        match self {
388            NodeOrToken::Node(it) => it.index(),
389            NodeOrToken::Token(it) => it.index(),
390        }
391    }
392
393    pub fn kind(&self) -> L::Kind {
394        match self {
395            NodeOrToken::Node(it) => it.kind(),
396            NodeOrToken::Token(it) => it.kind(),
397        }
398    }
399
400    pub fn parent(&self) -> Option<SyntaxNode<L>> {
401        match self {
402            NodeOrToken::Node(it) => it.parent(),
403            NodeOrToken::Token(it) => it.parent(),
404        }
405    }
406
407    pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> + use<L> {
408        let first = match self {
409            NodeOrToken::Node(it) => Some(it.clone()),
410            NodeOrToken::Token(it) => it.parent(),
411        };
412        iter::successors(first, SyntaxNode::parent)
413    }
414
415    pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
416        match self {
417            NodeOrToken::Node(it) => it.next_sibling_or_token(),
418            NodeOrToken::Token(it) => it.next_sibling_or_token(),
419        }
420    }
421    pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
422        match self {
423            NodeOrToken::Node(it) => it.prev_sibling_or_token(),
424            NodeOrToken::Token(it) => it.prev_sibling_or_token(),
425        }
426    }
427    pub fn detach(&self) {
428        match self {
429            NodeOrToken::Node(it) => it.detach(),
430            NodeOrToken::Token(it) => it.detach(),
431        }
432    }
433}
434
435#[derive(Debug, Clone)]
436pub struct SyntaxNodeChildren<L: Language> {
437    raw: cursor::SyntaxNodeChildren,
438    _p: PhantomData<L>,
439}
440
441impl<L: Language> Iterator for SyntaxNodeChildren<L> {
442    type Item = SyntaxNode<L>;
443    fn next(&mut self) -> Option<Self::Item> {
444        self.raw.next().map(SyntaxNode::from)
445    }
446}
447
448impl<L: Language> SyntaxNodeChildren<L> {
449    pub fn by_kind(self, matcher: impl Fn(L::Kind) -> bool) -> impl Iterator<Item = SyntaxNode<L>> {
450        self.raw.by_kind(move |raw_kind| matcher(L::kind_from_raw(raw_kind))).map(SyntaxNode::from)
451    }
452}
453
454#[derive(Debug, Clone)]
455pub struct SyntaxElementChildren<L: Language> {
456    raw: cursor::SyntaxElementChildren,
457    _p: PhantomData<L>,
458}
459
460impl<L: Language> Iterator for SyntaxElementChildren<L> {
461    type Item = SyntaxElement<L>;
462    fn next(&mut self) -> Option<Self::Item> {
463        self.raw.next().map(NodeOrToken::from)
464    }
465}
466
467impl<L: Language> SyntaxElementChildren<L> {
468    pub fn by_kind(
469        self,
470        matcher: impl Fn(L::Kind) -> bool,
471    ) -> impl Iterator<Item = SyntaxElement<L>> {
472        self.raw.by_kind(move |raw_kind| matcher(L::kind_from_raw(raw_kind))).map(NodeOrToken::from)
473    }
474}
475
476#[derive(Debug, Clone)]
477pub struct Preorder<L: Language> {
478    raw: cursor::Preorder,
479    _p: PhantomData<L>,
480}
481
482impl<L: Language> Preorder<L> {
483    pub fn skip_subtree(&mut self) {
484        self.raw.skip_subtree()
485    }
486}
487
488impl<L: Language> Iterator for Preorder<L> {
489    type Item = WalkEvent<SyntaxNode<L>>;
490    fn next(&mut self) -> Option<Self::Item> {
491        self.raw.next().map(|it| it.map(SyntaxNode::from))
492    }
493}
494
495#[derive(Debug, Clone)]
496pub struct PreorderWithTokens<L: Language> {
497    raw: cursor::PreorderWithTokens,
498    _p: PhantomData<L>,
499}
500
501impl<L: Language> PreorderWithTokens<L> {
502    pub fn skip_subtree(&mut self) {
503        self.raw.skip_subtree()
504    }
505}
506
507impl<L: Language> Iterator for PreorderWithTokens<L> {
508    type Item = WalkEvent<SyntaxElement<L>>;
509    fn next(&mut self) -> Option<Self::Item> {
510        self.raw.next().map(|it| it.map(SyntaxElement::from))
511    }
512}
513
514impl<L: Language> From<cursor::SyntaxNode> for SyntaxNode<L> {
515    fn from(raw: cursor::SyntaxNode) -> SyntaxNode<L> {
516        SyntaxNode { raw, _p: PhantomData }
517    }
518}
519
520impl<L: Language> From<SyntaxNode<L>> for cursor::SyntaxNode {
521    fn from(node: SyntaxNode<L>) -> cursor::SyntaxNode {
522        node.raw
523    }
524}
525
526impl<L: Language> From<cursor::SyntaxToken> for SyntaxToken<L> {
527    fn from(raw: cursor::SyntaxToken) -> SyntaxToken<L> {
528        SyntaxToken { raw, _p: PhantomData }
529    }
530}
531
532impl<L: Language> From<SyntaxToken<L>> for cursor::SyntaxToken {
533    fn from(token: SyntaxToken<L>) -> cursor::SyntaxToken {
534        token.raw
535    }
536}
537
538impl<L: Language> From<cursor::SyntaxElement> for SyntaxElement<L> {
539    fn from(raw: cursor::SyntaxElement) -> SyntaxElement<L> {
540        match raw {
541            NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
542            NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
543        }
544    }
545}
546
547impl<L: Language> From<SyntaxElement<L>> for cursor::SyntaxElement {
548    fn from(element: SyntaxElement<L>) -> cursor::SyntaxElement {
549        match element {
550            NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
551            NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
552        }
553    }
554}