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