1 use std::{
2     fmt::Write,
3     hash::{Hash, Hasher},
4     iter,
5 };
6 
7 use lasso::Resolver;
8 use text_size::{TextRange, TextSize};
9 
10 use super::*;
11 use crate::{Direction, GreenNode, GreenToken, Language, SyntaxKind};
12 
13 /// Syntax tree token.
14 #[derive(Debug)]
15 pub struct SyntaxToken<L: Language, D: 'static = ()> {
16     parent: SyntaxNode<L, D>,
17     index:  u32,
18     offset: TextSize,
19 }
20 
21 impl<L: Language, D> Clone for SyntaxToken<L, D> {
clone(&self) -> Self22     fn clone(&self) -> Self {
23         Self {
24             parent: self.parent.clone(),
25             index:  self.index,
26             offset: self.offset,
27         }
28     }
29 }
30 
31 impl<L: Language, D> Hash for SyntaxToken<L, D> {
hash<H: Hasher>(&self, state: &mut H)32     fn hash<H: Hasher>(&self, state: &mut H) {
33         self.parent.hash(state);
34         self.index.hash(state);
35         self.offset.hash(state);
36     }
37 }
38 
39 impl<L: Language, D> PartialEq for SyntaxToken<L, D> {
eq(&self, other: &SyntaxToken<L, D>) -> bool40     fn eq(&self, other: &SyntaxToken<L, D>) -> bool {
41         self.parent == other.parent && self.index == other.index && self.offset == other.offset
42     }
43 }
44 
45 impl<L: Language, D> Eq for SyntaxToken<L, D> {}
46 
47 impl<L: Language, D> SyntaxToken<L, D> {
48     #[allow(missing_docs)]
debug<R>(&self, resolver: &R) -> String where R: Resolver + ?Sized,49     pub fn debug<R>(&self, resolver: &R) -> String
50     where
51         R: Resolver + ?Sized,
52     {
53         let mut res = String::new();
54         write!(res, "{:?}@{:?}", self.kind(), self.text_range()).unwrap();
55         if self.resolve_text(resolver).len() < 25 {
56             write!(res, " {:?}", self.resolve_text(resolver)).unwrap();
57             return res;
58         }
59         let text = self.resolve_text(resolver);
60         for idx in 21..25 {
61             if text.is_char_boundary(idx) {
62                 let text = format!("{} ...", &text[..idx]);
63                 write!(res, " {:?}", text).unwrap();
64                 return res;
65             }
66         }
67         unreachable!()
68     }
69 
70     #[allow(missing_docs)]
display<R>(&self, resolver: &R) -> String where R: Resolver + ?Sized,71     pub fn display<R>(&self, resolver: &R) -> String
72     where
73         R: Resolver + ?Sized,
74     {
75         self.resolve_text(resolver).to_string()
76     }
77 
78     /// Turns this token into a [`ResolvedToken`], but only if there is a resolver associated with this tree.
79     #[inline]
try_resolved(&self) -> Option<&ResolvedToken<L, D>>80     pub fn try_resolved(&self) -> Option<&ResolvedToken<L, D>> {
81         // safety: we only coerce if `resolver` exists
82         self.parent()
83             .resolver()
84             .map(|_| unsafe { ResolvedToken::coerce_ref(self) })
85     }
86 
87     /// Turns this token into a [`ResolvedToken`].
88     /// # Panics
89     /// If there is no resolver associated with this tree.
90     #[inline]
resolved(&self) -> &ResolvedToken<L, D>91     pub fn resolved(&self) -> &ResolvedToken<L, D> {
92         self.try_resolved().expect("tried to resolve a node without resolver")
93     }
94 }
95 
96 impl<L: Language, D> SyntaxToken<L, D> {
new(parent: &SyntaxNode<L, D>, index: u32, offset: TextSize) -> SyntaxToken<L, D>97     pub(super) fn new(parent: &SyntaxNode<L, D>, index: u32, offset: TextSize) -> SyntaxToken<L, D> {
98         Self {
99             parent: parent.clone_uncounted(),
100             index,
101             offset,
102         }
103     }
104 
105     /// Returns a green tree, equal to the green tree this token
106     /// belongs two, except with this token substitute. The complexity
107     /// of operation is proportional to the depth of the tree
replace_with(&self, replacement: GreenToken) -> GreenNode108     pub fn replace_with(&self, replacement: GreenToken) -> GreenNode {
109         assert_eq!(self.syntax_kind(), replacement.kind());
110         let mut replacement = Some(replacement);
111         let parent = self.parent();
112         let me = self.index;
113 
114         let children = parent.green().children().enumerate().map(|(i, child)| {
115             if i as u32 == me {
116                 replacement.take().unwrap().into()
117             } else {
118                 child.cloned()
119             }
120         });
121         let new_parent = GreenNode::new(parent.syntax_kind(), children);
122         parent.replace_with(new_parent)
123     }
124 
125     /// The internal representation of the kind of this token.
126     #[inline]
syntax_kind(&self) -> SyntaxKind127     pub fn syntax_kind(&self) -> SyntaxKind {
128         self.green().kind()
129     }
130 
131     /// The kind of this token in terms of your language.
132     #[inline]
kind(&self) -> L::Kind133     pub fn kind(&self) -> L::Kind {
134         L::kind_from_raw(self.syntax_kind())
135     }
136 
137     /// The range this token covers in the source text, in bytes.
138     #[inline]
text_range(&self) -> TextRange139     pub fn text_range(&self) -> TextRange {
140         TextRange::at(self.offset, self.green().text_len())
141     }
142 
143     /// Uses the provided resolver to return the source text of this token.
144     #[inline]
resolve_text<'i, I>(&self, resolver: &'i I) -> &'i str where I: Resolver + ?Sized,145     pub fn resolve_text<'i, I>(&self, resolver: &'i I) -> &'i str
146     where
147         I: Resolver + ?Sized,
148     {
149         self.green().text(resolver)
150     }
151 
152     /// Returns the unterlying green tree token of this token.
green(&self) -> &GreenToken153     pub fn green(&self) -> &GreenToken {
154         self.parent
155             .green()
156             .children()
157             .nth(self.index as usize)
158             .unwrap()
159             .as_token()
160             .unwrap()
161     }
162 
163     /// The parent node of this token.
164     #[inline]
parent(&self) -> &SyntaxNode<L, D>165     pub fn parent(&self) -> &SyntaxNode<L, D> {
166         &self.parent
167     }
168 
169     /// Returns an iterator along the chain of parents of this token.
170     #[inline]
ancestors(&self) -> impl Iterator<Item = &SyntaxNode<L, D>>171     pub fn ancestors(&self) -> impl Iterator<Item = &SyntaxNode<L, D>> {
172         self.parent().ancestors()
173     }
174 
175     /// The tree element to the right of this one, i.e. the next child of this token's parent after this token.
176     #[inline]
next_sibling_or_token(&self) -> Option<SyntaxElementRef<'_, L, D>>177     pub fn next_sibling_or_token(&self) -> Option<SyntaxElementRef<'_, L, D>> {
178         self.parent()
179             .next_child_or_token_after(self.index as usize, self.text_range().end())
180     }
181 
182     /// The tree element to the left of this one, i.e. the previous child of this token's parent after this token.
183     #[inline]
prev_sibling_or_token(&self) -> Option<SyntaxElementRef<'_, L, D>>184     pub fn prev_sibling_or_token(&self) -> Option<SyntaxElementRef<'_, L, D>> {
185         self.parent()
186             .prev_child_or_token_before(self.index as usize, self.text_range().start())
187     }
188 
189     /// Returns an iterator over all siblings of this token in the given `direction`, i.e. all of this
190     /// token's parent's children from this token on to the left or the right.
191     /// The first item in the iterator will always be this token.
192     #[inline]
siblings_with_tokens(&self, direction: Direction) -> impl Iterator<Item = SyntaxElementRef<'_, L, D>>193     pub fn siblings_with_tokens(&self, direction: Direction) -> impl Iterator<Item = SyntaxElementRef<'_, L, D>> {
194         let me: SyntaxElementRef<'_, L, D> = self.into();
195         iter::successors(Some(me), move |el| match direction {
196             Direction::Next => el.next_sibling_or_token(),
197             Direction::Prev => el.prev_sibling_or_token(),
198         })
199     }
200 
201     /// Returns the next token in the tree.
202     /// This is not necessary a direct sibling of this token, but will always be further right in the tree.
next_token(&self) -> Option<&SyntaxToken<L, D>>203     pub fn next_token(&self) -> Option<&SyntaxToken<L, D>> {
204         match self.next_sibling_or_token() {
205             Some(element) => element.first_token(),
206             None => self
207                 .parent()
208                 .ancestors()
209                 .find_map(|it| it.next_sibling_or_token())
210                 .and_then(|element| element.first_token()),
211         }
212     }
213 
214     /// Returns the previous token in the tree.
215     /// This is not necessary a direct sibling of this token, but will always be further left in the tree.
prev_token(&self) -> Option<&SyntaxToken<L, D>>216     pub fn prev_token(&self) -> Option<&SyntaxToken<L, D>> {
217         match self.prev_sibling_or_token() {
218             Some(element) => element.last_token(),
219             None => self
220                 .parent()
221                 .ancestors()
222                 .find_map(|it| it.prev_sibling_or_token())
223                 .and_then(|element| element.last_token()),
224         }
225     }
226 }
227