aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/syntax_node.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/syntax_node.rs')
-rw-r--r--crates/ra_syntax/src/syntax_node.rs483
1 files changed, 22 insertions, 461 deletions
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs
index c42045d77..689dbefde 100644
--- a/crates/ra_syntax/src/syntax_node.rs
+++ b/crates/ra_syntax/src/syntax_node.rs
@@ -6,15 +6,12 @@
6//! The *real* implementation is in the (language-agnostic) `rowan` crate, this 6//! The *real* implementation is in the (language-agnostic) `rowan` crate, this
7//! modules just wraps its API. 7//! modules just wraps its API.
8 8
9use std::{fmt, iter::successors, ops::RangeInclusive};
10
11use ra_parser::ParseError; 9use ra_parser::ParseError;
12use rowan::GreenNodeBuilder; 10use rowan::{GreenNodeBuilder, Language};
13 11
14use crate::{ 12use crate::{
15 syntax_error::{SyntaxError, SyntaxErrorKind}, 13 syntax_error::{SyntaxError, SyntaxErrorKind},
16 AstNode, Parse, SmolStr, SourceFile, SyntaxKind, SyntaxNodePtr, SyntaxText, TextRange, 14 Parse, SmolStr, SyntaxKind, TextUnit,
17 TextUnit,
18}; 15};
19 16
20pub use rowan::WalkEvent; 17pub use rowan::WalkEvent;
@@ -28,465 +25,27 @@ pub enum InsertPosition<T> {
28 After(T), 25 After(T),
29} 26}
30 27
31#[derive(PartialEq, Eq, Hash, Clone)] 28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub struct SyntaxNode(pub(crate) rowan::cursor::SyntaxNode); 29pub enum RustLanguage {}
33 30impl Language for RustLanguage {
34impl fmt::Debug for SyntaxNode { 31 type Kind = SyntaxKind;
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 if f.alternate() {
37 let mut level = 0;
38 for event in self.preorder_with_tokens() {
39 match event {
40 WalkEvent::Enter(element) => {
41 for _ in 0..level {
42 write!(f, " ")?;
43 }
44 match element {
45 SyntaxElement::Node(node) => writeln!(f, "{:?}", node)?,
46 SyntaxElement::Token(token) => writeln!(f, "{:?}", token)?,
47 }
48 level += 1;
49 }
50 WalkEvent::Leave(_) => level -= 1,
51 }
52 }
53 assert_eq!(level, 0);
54 Ok(())
55 } else {
56 write!(f, "{:?}@{:?}", self.kind(), self.text_range())
57 }
58 }
59}
60
61impl fmt::Display for SyntaxNode {
62 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
63 fmt::Display::fmt(&self.text(), fmt)
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum Direction {
69 Next,
70 Prev,
71}
72
73impl SyntaxNode {
74 pub(crate) fn new(green: GreenNode) -> SyntaxNode {
75 let inner = rowan::cursor::SyntaxNode::new_root(green);
76 SyntaxNode(inner)
77 }
78
79 pub fn kind(&self) -> SyntaxKind {
80 self.0.kind().0.into()
81 }
82
83 pub fn text_range(&self) -> TextRange {
84 self.0.text_range()
85 }
86
87 pub fn text(&self) -> SyntaxText {
88 SyntaxText::new(self.clone())
89 }
90
91 pub fn parent(&self) -> Option<SyntaxNode> {
92 self.0.parent().map(SyntaxNode)
93 }
94
95 pub fn first_child(&self) -> Option<SyntaxNode> {
96 self.0.first_child().map(SyntaxNode)
97 }
98
99 pub fn first_child_or_token(&self) -> Option<SyntaxElement> {
100 self.0.first_child_or_token().map(SyntaxElement::new)
101 }
102
103 pub fn last_child(&self) -> Option<SyntaxNode> {
104 self.0.last_child().map(SyntaxNode)
105 }
106
107 pub fn last_child_or_token(&self) -> Option<SyntaxElement> {
108 self.0.last_child_or_token().map(SyntaxElement::new)
109 }
110
111 pub fn next_sibling(&self) -> Option<SyntaxNode> {
112 self.0.next_sibling().map(SyntaxNode)
113 }
114
115 pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
116 self.0.next_sibling_or_token().map(SyntaxElement::new)
117 }
118
119 pub fn prev_sibling(&self) -> Option<SyntaxNode> {
120 self.0.prev_sibling().map(SyntaxNode)
121 }
122
123 pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
124 self.0.prev_sibling_or_token().map(SyntaxElement::new)
125 }
126
127 pub fn children(&self) -> SyntaxNodeChildren {
128 SyntaxNodeChildren(self.0.children())
129 }
130
131 pub fn children_with_tokens(&self) -> SyntaxElementChildren {
132 SyntaxElementChildren(self.0.children_with_tokens())
133 }
134
135 pub fn first_token(&self) -> Option<SyntaxToken> {
136 self.0.first_token().map(SyntaxToken)
137 }
138
139 pub fn last_token(&self) -> Option<SyntaxToken> {
140 self.0.last_token().map(SyntaxToken)
141 }
142
143 pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
144 successors(Some(self.clone()), |node| node.parent())
145 }
146
147 pub fn descendants(&self) -> impl Iterator<Item = SyntaxNode> {
148 self.preorder().filter_map(|event| match event {
149 WalkEvent::Enter(node) => Some(node),
150 WalkEvent::Leave(_) => None,
151 })
152 }
153
154 pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> {
155 self.preorder_with_tokens().filter_map(|event| match event {
156 WalkEvent::Enter(it) => Some(it),
157 WalkEvent::Leave(_) => None,
158 })
159 }
160
161 pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = SyntaxNode> {
162 successors(Some(self.clone()), move |node| match direction {
163 Direction::Next => node.next_sibling(),
164 Direction::Prev => node.prev_sibling(),
165 })
166 }
167
168 pub fn siblings_with_tokens(
169 &self,
170 direction: Direction,
171 ) -> impl Iterator<Item = SyntaxElement> {
172 let me: SyntaxElement = self.clone().into();
173 successors(Some(me), move |el| match direction {
174 Direction::Next => el.next_sibling_or_token(),
175 Direction::Prev => el.prev_sibling_or_token(),
176 })
177 }
178 32
179 pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode>> { 33 fn kind_from_raw(raw: rowan::cursor::SyntaxKind) -> SyntaxKind {
180 self.0.preorder().map(|event| match event { 34 SyntaxKind::from(raw.0)
181 WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode(n)),
182 WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxNode(n)),
183 })
184 } 35 }
185 36
186 pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement>> { 37 fn kind_to_raw(kind: SyntaxKind) -> rowan::cursor::SyntaxKind {
187 self.0.preorder_with_tokens().map(|event| match event { 38 rowan::cursor::SyntaxKind(kind.into())
188 WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxElement::new(n)),
189 WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxElement::new(n)),
190 })
191 }
192
193 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
194 self.0.replace_with(replacement)
195 }
196
197 /// Adds specified children (tokens or nodes) to the current node at the
198 /// specific position.
199 ///
200 /// This is a type-unsafe low-level editing API, if you need to use it,
201 /// prefer to create a type-safe abstraction on top of it instead.
202 pub fn insert_children(
203 &self,
204 position: InsertPosition<SyntaxElement>,
205 to_insert: impl Iterator<Item = SyntaxElement>,
206 ) -> SyntaxNode {
207 let mut delta = TextUnit::default();
208 let to_insert = to_insert.map(|element| {
209 delta += element.text_len();
210 to_green_element(element)
211 });
212
213 let old_children = self.0.green().children();
214
215 let new_children = match &position {
216 InsertPosition::First => {
217 to_insert.chain(old_children.iter().cloned()).collect::<Box<[_]>>()
218 }
219 InsertPosition::Last => {
220 old_children.iter().cloned().chain(to_insert).collect::<Box<[_]>>()
221 }
222 InsertPosition::Before(anchor) | InsertPosition::After(anchor) => {
223 let take_anchor = if let InsertPosition::After(_) = position { 1 } else { 0 };
224 let split_at = self.position_of_child(anchor.clone()) + take_anchor;
225 let (before, after) = old_children.split_at(split_at);
226 before
227 .iter()
228 .cloned()
229 .chain(to_insert)
230 .chain(after.iter().cloned())
231 .collect::<Box<[_]>>()
232 }
233 };
234
235 self.with_children(new_children)
236 }
237
238 /// Replaces all nodes in `to_delete` with nodes from `to_insert`
239 ///
240 /// This is a type-unsafe low-level editing API, if you need to use it,
241 /// prefer to create a type-safe abstraction on top of it instead.
242 pub fn replace_children(
243 &self,
244 to_delete: RangeInclusive<SyntaxElement>,
245 to_insert: impl Iterator<Item = SyntaxElement>,
246 ) -> SyntaxNode {
247 let start = self.position_of_child(to_delete.start().clone());
248 let end = self.position_of_child(to_delete.end().clone());
249 let old_children = self.0.green().children();
250
251 let new_children = old_children[..start]
252 .iter()
253 .cloned()
254 .chain(to_insert.map(to_green_element))
255 .chain(old_children[end + 1..].iter().cloned())
256 .collect::<Box<[_]>>();
257 self.with_children(new_children)
258 }
259
260 fn with_children(&self, new_children: Box<[rowan::GreenElement]>) -> SyntaxNode {
261 let len = new_children.iter().map(|it| it.text_len()).sum::<TextUnit>();
262 let new_node = GreenNode::new(rowan::SyntaxKind(self.kind() as u16), new_children);
263 let new_file_node = self.replace_with(new_node);
264 let file = SourceFile::new(new_file_node);
265
266 // FIXME: use a more elegant way to re-fetch the node (#1185), make
267 // `range` private afterwards
268 let mut ptr = SyntaxNodePtr::new(self);
269 ptr.range = TextRange::offset_len(ptr.range().start(), len);
270 ptr.to_node(file.syntax()).to_owned()
271 }
272
273 fn position_of_child(&self, child: SyntaxElement) -> usize {
274 self.children_with_tokens()
275 .position(|it| it == child)
276 .expect("element is not a child of current element")
277 } 39 }
278} 40}
279 41
280fn to_green_element(element: SyntaxElement) -> rowan::GreenElement { 42pub type SyntaxNode = rowan::SyntaxNode<RustLanguage>;
281 match element { 43pub type SyntaxToken = rowan::SyntaxToken<RustLanguage>;
282 SyntaxElement::Node(node) => node.0.green().clone().into(), 44pub type SyntaxElement = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;
283 SyntaxElement::Token(tok) => { 45pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>;
284 GreenToken::new(rowan::SyntaxKind(tok.kind() as u16), tok.text().clone()).into() 46pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>;
285 }
286 }
287}
288
289#[derive(Clone, PartialEq, Eq, Hash)]
290pub struct SyntaxToken(pub(crate) rowan::cursor::SyntaxToken);
291
292impl fmt::Debug for SyntaxToken {
293 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
294 write!(fmt, "{:?}@{:?}", self.kind(), self.text_range())?;
295 if self.text().len() < 25 {
296 return write!(fmt, " {:?}", self.text());
297 }
298 let text = self.text().as_str();
299 for idx in 21..25 {
300 if text.is_char_boundary(idx) {
301 let text = format!("{} ...", &text[..idx]);
302 return write!(fmt, " {:?}", text);
303 }
304 }
305 unreachable!()
306 }
307}
308 47
309impl fmt::Display for SyntaxToken { 48pub use rowan::{Direction, NodeOrToken};
310 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
311 fmt::Display::fmt(self.text(), fmt)
312 }
313}
314
315impl SyntaxToken {
316 pub fn kind(&self) -> SyntaxKind {
317 self.0.kind().0.into()
318 }
319
320 pub fn text(&self) -> &SmolStr {
321 self.0.text()
322 }
323
324 pub fn text_range(&self) -> TextRange {
325 self.0.text_range()
326 }
327
328 pub fn parent(&self) -> SyntaxNode {
329 SyntaxNode(self.0.parent())
330 }
331
332 pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
333 self.0.next_sibling_or_token().map(SyntaxElement::new)
334 }
335
336 pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
337 self.0.prev_sibling_or_token().map(SyntaxElement::new)
338 }
339
340 pub fn siblings_with_tokens(
341 &self,
342 direction: Direction,
343 ) -> impl Iterator<Item = SyntaxElement> {
344 let me: SyntaxElement = self.clone().into();
345 successors(Some(me), move |el| match direction {
346 Direction::Next => el.next_sibling_or_token(),
347 Direction::Prev => el.prev_sibling_or_token(),
348 })
349 }
350
351 pub fn next_token(&self) -> Option<SyntaxToken> {
352 self.0.next_token().map(SyntaxToken)
353 }
354
355 pub fn prev_token(&self) -> Option<SyntaxToken> {
356 self.0.prev_token().map(SyntaxToken)
357 }
358
359 pub(crate) fn replace_with(&self, new_token: GreenToken) -> GreenNode {
360 self.0.replace_with(new_token)
361 }
362}
363
364#[derive(Debug, PartialEq, Eq, Hash, Clone)]
365pub enum SyntaxElement {
366 Node(SyntaxNode),
367 Token(SyntaxToken),
368}
369
370impl From<SyntaxNode> for SyntaxElement {
371 fn from(node: SyntaxNode) -> Self {
372 SyntaxElement::Node(node)
373 }
374}
375
376impl From<SyntaxToken> for SyntaxElement {
377 fn from(token: SyntaxToken) -> Self {
378 SyntaxElement::Token(token)
379 }
380}
381
382impl fmt::Display for SyntaxElement {
383 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
384 match self {
385 SyntaxElement::Node(it) => fmt::Display::fmt(it, fmt),
386 SyntaxElement::Token(it) => fmt::Display::fmt(it, fmt),
387 }
388 }
389}
390
391impl SyntaxElement {
392 pub(crate) fn new(el: rowan::cursor::SyntaxElement) -> Self {
393 match el {
394 rowan::cursor::SyntaxElement::Node(it) => SyntaxElement::Node(SyntaxNode(it)),
395 rowan::cursor::SyntaxElement::Token(it) => SyntaxElement::Token(SyntaxToken(it)),
396 }
397 }
398
399 pub fn kind(&self) -> SyntaxKind {
400 match self {
401 SyntaxElement::Node(it) => it.kind(),
402 SyntaxElement::Token(it) => it.kind(),
403 }
404 }
405
406 pub fn as_node(&self) -> Option<&SyntaxNode> {
407 match self {
408 SyntaxElement::Node(node) => Some(node),
409 SyntaxElement::Token(_) => None,
410 }
411 }
412
413 pub fn into_node(self) -> Option<SyntaxNode> {
414 match self {
415 SyntaxElement::Node(node) => Some(node),
416 SyntaxElement::Token(_) => None,
417 }
418 }
419
420 pub fn as_token(&self) -> Option<&SyntaxToken> {
421 match self {
422 SyntaxElement::Node(_) => None,
423 SyntaxElement::Token(token) => Some(token),
424 }
425 }
426
427 pub fn into_token(self) -> Option<SyntaxToken> {
428 match self {
429 SyntaxElement::Node(_) => None,
430 SyntaxElement::Token(token) => Some(token),
431 }
432 }
433
434 pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> {
435 match self {
436 SyntaxElement::Node(it) => it.next_sibling_or_token(),
437 SyntaxElement::Token(it) => it.next_sibling_or_token(),
438 }
439 }
440
441 pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> {
442 match self {
443 SyntaxElement::Node(it) => it.prev_sibling_or_token(),
444 SyntaxElement::Token(it) => it.prev_sibling_or_token(),
445 }
446 }
447
448 pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode> {
449 match self {
450 SyntaxElement::Node(it) => it.clone(),
451 SyntaxElement::Token(it) => it.parent(),
452 }
453 .ancestors()
454 }
455
456 pub fn text_range(&self) -> TextRange {
457 match self {
458 SyntaxElement::Node(it) => it.text_range(),
459 SyntaxElement::Token(it) => it.text_range(),
460 }
461 }
462
463 fn text_len(&self) -> TextUnit {
464 match self {
465 SyntaxElement::Node(node) => node.0.green().text_len(),
466 SyntaxElement::Token(token) => TextUnit::of_str(token.0.text()),
467 }
468 }
469}
470
471#[derive(Clone, Debug)]
472pub struct SyntaxNodeChildren(rowan::cursor::SyntaxNodeChildren);
473
474impl Iterator for SyntaxNodeChildren {
475 type Item = SyntaxNode;
476 fn next(&mut self) -> Option<SyntaxNode> {
477 self.0.next().map(SyntaxNode)
478 }
479}
480
481#[derive(Clone, Debug)]
482pub struct SyntaxElementChildren(rowan::cursor::SyntaxElementChildren);
483
484impl Iterator for SyntaxElementChildren {
485 type Item = SyntaxElement;
486 fn next(&mut self) -> Option<SyntaxElement> {
487 self.0.next().map(SyntaxElement::new)
488 }
489}
490 49
491pub struct SyntaxTreeBuilder { 50pub struct SyntaxTreeBuilder {
492 errors: Vec<SyntaxError>, 51 errors: Vec<SyntaxError>,
@@ -507,19 +66,21 @@ impl SyntaxTreeBuilder {
507 66
508 pub fn finish(self) -> Parse<SyntaxNode> { 67 pub fn finish(self) -> Parse<SyntaxNode> {
509 let (green, errors) = self.finish_raw(); 68 let (green, errors) = self.finish_raw();
510 let node = SyntaxNode::new(green); 69 let node = SyntaxNode::new_root(green);
511 if cfg!(debug_assertions) { 70 if cfg!(debug_assertions) {
512 crate::validation::validate_block_structure(&node); 71 crate::validation::validate_block_structure(&node);
513 } 72 }
514 Parse::new(node.0.green().clone(), errors) 73 Parse::new(node.green().clone(), errors)
515 } 74 }
516 75
517 pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { 76 pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) {
518 self.inner.token(rowan::SyntaxKind(kind.into()), text) 77 let kind = RustLanguage::kind_to_raw(kind);
78 self.inner.token(kind, text)
519 } 79 }
520 80
521 pub fn start_node(&mut self, kind: SyntaxKind) { 81 pub fn start_node(&mut self, kind: SyntaxKind) {
522 self.inner.start_node(rowan::SyntaxKind(kind.into())) 82 let kind = RustLanguage::kind_to_raw(kind);
83 self.inner.start_node(kind)
523 } 84 }
524 85
525 pub fn finish_node(&mut self) { 86 pub fn finish_node(&mut self) {