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