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