diff options
Diffstat (limited to 'crates/ra_syntax/src/syntax_node.rs')
-rw-r--r-- | crates/ra_syntax/src/syntax_node.rs | 296 |
1 files changed, 262 insertions, 34 deletions
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index e5b4cdb11..a88a348ad 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs | |||
@@ -29,6 +29,9 @@ impl Types for RaTypes { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | pub(crate) type GreenNode = rowan::GreenNode<RaTypes>; | 31 | pub(crate) type GreenNode = rowan::GreenNode<RaTypes>; |
32 | pub(crate) type GreenToken = rowan::GreenToken<RaTypes>; | ||
33 | #[allow(unused)] | ||
34 | pub(crate) type GreenElement = rowan::GreenElement<RaTypes>; | ||
32 | 35 | ||
33 | /// Marker trait for CST and AST nodes | 36 | /// Marker trait for CST and AST nodes |
34 | pub trait SyntaxNodeWrapper: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> {} | 37 | pub trait SyntaxNodeWrapper: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> {} |
@@ -113,11 +116,13 @@ impl ToOwned for SyntaxNode { | |||
113 | 116 | ||
114 | impl fmt::Debug for SyntaxNode { | 117 | impl fmt::Debug for SyntaxNode { |
115 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 118 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
116 | write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; | 119 | write!(fmt, "{:?}@{:?}", self.kind(), self.range()) |
117 | if has_short_text(self.kind()) { | 120 | } |
118 | write!(fmt, " \"{}\"", self.text())?; | 121 | } |
119 | } | 122 | |
120 | Ok(()) | 123 | impl fmt::Display for SyntaxNode { |
124 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
125 | fmt::Display::fmt(&self.text(), fmt) | ||
121 | } | 126 | } |
122 | } | 127 | } |
123 | 128 | ||
@@ -145,14 +150,6 @@ impl SyntaxNode { | |||
145 | SyntaxText::new(self) | 150 | SyntaxText::new(self) |
146 | } | 151 | } |
147 | 152 | ||
148 | pub fn is_leaf(&self) -> bool { | ||
149 | self.0.is_leaf() | ||
150 | } | ||
151 | |||
152 | pub fn leaf_text(&self) -> Option<&SmolStr> { | ||
153 | self.0.leaf_text() | ||
154 | } | ||
155 | |||
156 | pub fn parent(&self) -> Option<&SyntaxNode> { | 153 | pub fn parent(&self) -> Option<&SyntaxNode> { |
157 | self.0.parent().map(SyntaxNode::from_repr) | 154 | self.0.parent().map(SyntaxNode::from_repr) |
158 | } | 155 | } |
@@ -161,22 +158,50 @@ impl SyntaxNode { | |||
161 | self.0.first_child().map(SyntaxNode::from_repr) | 158 | self.0.first_child().map(SyntaxNode::from_repr) |
162 | } | 159 | } |
163 | 160 | ||
161 | pub fn first_child_or_token(&self) -> Option<SyntaxElement> { | ||
162 | self.0.first_child_or_token().map(SyntaxElement::from) | ||
163 | } | ||
164 | |||
164 | pub fn last_child(&self) -> Option<&SyntaxNode> { | 165 | pub fn last_child(&self) -> Option<&SyntaxNode> { |
165 | self.0.last_child().map(SyntaxNode::from_repr) | 166 | self.0.last_child().map(SyntaxNode::from_repr) |
166 | } | 167 | } |
167 | 168 | ||
169 | pub fn last_child_or_token(&self) -> Option<SyntaxElement> { | ||
170 | self.0.last_child_or_token().map(SyntaxElement::from) | ||
171 | } | ||
172 | |||
168 | pub fn next_sibling(&self) -> Option<&SyntaxNode> { | 173 | pub fn next_sibling(&self) -> Option<&SyntaxNode> { |
169 | self.0.next_sibling().map(SyntaxNode::from_repr) | 174 | self.0.next_sibling().map(SyntaxNode::from_repr) |
170 | } | 175 | } |
171 | 176 | ||
177 | pub fn next_sibling_or_token(&self) -> Option<SyntaxElement> { | ||
178 | self.0.next_sibling_or_token().map(SyntaxElement::from) | ||
179 | } | ||
180 | |||
172 | pub fn prev_sibling(&self) -> Option<&SyntaxNode> { | 181 | pub fn prev_sibling(&self) -> Option<&SyntaxNode> { |
173 | self.0.prev_sibling().map(SyntaxNode::from_repr) | 182 | self.0.prev_sibling().map(SyntaxNode::from_repr) |
174 | } | 183 | } |
175 | 184 | ||
185 | pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement> { | ||
186 | self.0.prev_sibling_or_token().map(SyntaxElement::from) | ||
187 | } | ||
188 | |||
176 | pub fn children(&self) -> SyntaxNodeChildren { | 189 | pub fn children(&self) -> SyntaxNodeChildren { |
177 | SyntaxNodeChildren(self.0.children()) | 190 | SyntaxNodeChildren(self.0.children()) |
178 | } | 191 | } |
179 | 192 | ||
193 | pub fn children_with_tokens(&self) -> SyntaxElementChildren { | ||
194 | SyntaxElementChildren(self.0.children_with_tokens()) | ||
195 | } | ||
196 | |||
197 | pub fn first_token(&self) -> Option<SyntaxToken> { | ||
198 | self.0.first_token().map(SyntaxToken::from) | ||
199 | } | ||
200 | |||
201 | pub fn last_token(&self) -> Option<SyntaxToken> { | ||
202 | self.0.last_token().map(SyntaxToken::from) | ||
203 | } | ||
204 | |||
180 | pub fn ancestors(&self) -> impl Iterator<Item = &SyntaxNode> { | 205 | pub fn ancestors(&self) -> impl Iterator<Item = &SyntaxNode> { |
181 | crate::algo::generate(Some(self), |&node| node.parent()) | 206 | crate::algo::generate(Some(self), |&node| node.parent()) |
182 | } | 207 | } |
@@ -188,6 +213,13 @@ impl SyntaxNode { | |||
188 | }) | 213 | }) |
189 | } | 214 | } |
190 | 215 | ||
216 | pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> { | ||
217 | self.preorder_with_tokens().filter_map(|event| match event { | ||
218 | WalkEvent::Enter(it) => Some(it), | ||
219 | WalkEvent::Leave(_) => None, | ||
220 | }) | ||
221 | } | ||
222 | |||
191 | pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = &SyntaxNode> { | 223 | pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = &SyntaxNode> { |
192 | crate::algo::generate(Some(self), move |&node| match direction { | 224 | crate::algo::generate(Some(self), move |&node| match direction { |
193 | Direction::Next => node.next_sibling(), | 225 | Direction::Next => node.next_sibling(), |
@@ -195,6 +227,17 @@ impl SyntaxNode { | |||
195 | }) | 227 | }) |
196 | } | 228 | } |
197 | 229 | ||
230 | pub fn siblings_with_tokens( | ||
231 | &self, | ||
232 | direction: Direction, | ||
233 | ) -> impl Iterator<Item = SyntaxElement> { | ||
234 | let me: SyntaxElement = self.into(); | ||
235 | crate::algo::generate(Some(me), move |el| match direction { | ||
236 | Direction::Next => el.next_sibling_or_token(), | ||
237 | Direction::Prev => el.prev_sibling_or_token(), | ||
238 | }) | ||
239 | } | ||
240 | |||
198 | pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<&SyntaxNode>> { | 241 | pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<&SyntaxNode>> { |
199 | self.0.preorder().map(|event| match event { | 242 | self.0.preorder().map(|event| match event { |
200 | WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode::from_repr(n)), | 243 | WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode::from_repr(n)), |
@@ -202,6 +245,13 @@ impl SyntaxNode { | |||
202 | }) | 245 | }) |
203 | } | 246 | } |
204 | 247 | ||
248 | pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement>> { | ||
249 | self.0.preorder_with_tokens().map(|event| match event { | ||
250 | WalkEvent::Enter(n) => WalkEvent::Enter(n.into()), | ||
251 | WalkEvent::Leave(n) => WalkEvent::Leave(n.into()), | ||
252 | }) | ||
253 | } | ||
254 | |||
205 | pub fn memory_size_of_subtree(&self) -> usize { | 255 | pub fn memory_size_of_subtree(&self) -> usize { |
206 | self.0.memory_size_of_subtree() | 256 | self.0.memory_size_of_subtree() |
207 | } | 257 | } |
@@ -223,17 +273,20 @@ impl SyntaxNode { | |||
223 | }; | 273 | }; |
224 | } | 274 | } |
225 | 275 | ||
226 | for event in self.preorder() { | 276 | for event in self.preorder_with_tokens() { |
227 | match event { | 277 | match event { |
228 | WalkEvent::Enter(node) => { | 278 | WalkEvent::Enter(element) => { |
229 | indent!(); | 279 | indent!(); |
230 | writeln!(buf, "{:?}", node).unwrap(); | 280 | match element { |
231 | if node.first_child().is_none() { | 281 | SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(), |
232 | let off = node.range().end(); | 282 | SyntaxElement::Token(token) => { |
233 | while err_pos < errors.len() && errors[err_pos].offset() <= off { | 283 | writeln!(buf, "{:?}", token).unwrap(); |
234 | indent!(); | 284 | let off = token.range().end(); |
235 | writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); | 285 | while err_pos < errors.len() && errors[err_pos].offset() <= off { |
236 | err_pos += 1; | 286 | indent!(); |
287 | writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); | ||
288 | err_pos += 1; | ||
289 | } | ||
237 | } | 290 | } |
238 | } | 291 | } |
239 | level += 1; | 292 | level += 1; |
@@ -255,7 +308,179 @@ impl SyntaxNode { | |||
255 | } | 308 | } |
256 | 309 | ||
257 | pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { | 310 | pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { |
258 | self.0.replace_self(replacement) | 311 | self.0.replace_with(replacement) |
312 | } | ||
313 | } | ||
314 | |||
315 | #[derive(Clone, Copy, PartialEq, Eq, Hash)] | ||
316 | pub struct SyntaxToken<'a>(pub(crate) rowan::SyntaxToken<'a, RaTypes>); | ||
317 | |||
318 | //FIXME: always output text | ||
319 | impl<'a> fmt::Debug for SyntaxToken<'a> { | ||
320 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
321 | write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; | ||
322 | if self.text().len() < 25 { | ||
323 | return write!(fmt, " {:?}", self.text()); | ||
324 | } | ||
325 | let text = self.text().as_str(); | ||
326 | for idx in 21..25 { | ||
327 | if text.is_char_boundary(idx) { | ||
328 | let text = format!("{} ...", &text[..idx]); | ||
329 | return write!(fmt, " {:?}", text); | ||
330 | } | ||
331 | } | ||
332 | unreachable!() | ||
333 | } | ||
334 | } | ||
335 | |||
336 | impl<'a> fmt::Display for SyntaxToken<'a> { | ||
337 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
338 | fmt::Display::fmt(self.text(), fmt) | ||
339 | } | ||
340 | } | ||
341 | |||
342 | impl<'a> From<rowan::SyntaxToken<'a, RaTypes>> for SyntaxToken<'a> { | ||
343 | fn from(t: rowan::SyntaxToken<'a, RaTypes>) -> Self { | ||
344 | SyntaxToken(t) | ||
345 | } | ||
346 | } | ||
347 | |||
348 | impl<'a> SyntaxToken<'a> { | ||
349 | pub fn kind(&self) -> SyntaxKind { | ||
350 | self.0.kind() | ||
351 | } | ||
352 | |||
353 | pub fn text(&self) -> &'a SmolStr { | ||
354 | self.0.text() | ||
355 | } | ||
356 | |||
357 | pub fn range(&self) -> TextRange { | ||
358 | self.0.range() | ||
359 | } | ||
360 | |||
361 | pub fn parent(&self) -> &'a SyntaxNode { | ||
362 | SyntaxNode::from_repr(self.0.parent()) | ||
363 | } | ||
364 | |||
365 | pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<'a>> { | ||
366 | self.0.next_sibling_or_token().map(SyntaxElement::from) | ||
367 | } | ||
368 | |||
369 | pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<'a>> { | ||
370 | self.0.prev_sibling_or_token().map(SyntaxElement::from) | ||
371 | } | ||
372 | |||
373 | pub fn siblings_with_tokens( | ||
374 | &self, | ||
375 | direction: Direction, | ||
376 | ) -> impl Iterator<Item = SyntaxElement<'a>> { | ||
377 | let me: SyntaxElement = (*self).into(); | ||
378 | crate::algo::generate(Some(me), move |el| match direction { | ||
379 | Direction::Next => el.next_sibling_or_token(), | ||
380 | Direction::Prev => el.prev_sibling_or_token(), | ||
381 | }) | ||
382 | } | ||
383 | |||
384 | pub fn next_token(&self) -> Option<SyntaxToken<'a>> { | ||
385 | self.0.next_token().map(SyntaxToken::from) | ||
386 | } | ||
387 | |||
388 | pub fn prev_token(&self) -> Option<SyntaxToken<'a>> { | ||
389 | self.0.prev_token().map(SyntaxToken::from) | ||
390 | } | ||
391 | |||
392 | pub(crate) fn replace_with(&self, new_token: GreenToken) -> GreenNode { | ||
393 | self.0.replace_with(new_token) | ||
394 | } | ||
395 | } | ||
396 | |||
397 | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||
398 | pub enum SyntaxElement<'a> { | ||
399 | Node(&'a SyntaxNode), | ||
400 | Token(SyntaxToken<'a>), | ||
401 | } | ||
402 | |||
403 | impl<'a> fmt::Display for SyntaxElement<'a> { | ||
404 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
405 | match self { | ||
406 | SyntaxElement::Node(it) => fmt::Display::fmt(it, fmt), | ||
407 | SyntaxElement::Token(it) => fmt::Display::fmt(it, fmt), | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | |||
412 | impl<'a> SyntaxElement<'a> { | ||
413 | pub fn kind(&self) -> SyntaxKind { | ||
414 | match self { | ||
415 | SyntaxElement::Node(it) => it.kind(), | ||
416 | SyntaxElement::Token(it) => it.kind(), | ||
417 | } | ||
418 | } | ||
419 | |||
420 | pub fn as_node(&self) -> Option<&'a SyntaxNode> { | ||
421 | match self { | ||
422 | SyntaxElement::Node(node) => Some(*node), | ||
423 | SyntaxElement::Token(_) => None, | ||
424 | } | ||
425 | } | ||
426 | |||
427 | pub fn as_token(&self) -> Option<SyntaxToken<'a>> { | ||
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<'a>> { | ||
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<'a>> { | ||
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 = &'a SyntaxNode> { | ||
449 | match self { | ||
450 | SyntaxElement::Node(it) => it, | ||
451 | SyntaxElement::Token(it) => it.parent(), | ||
452 | } | ||
453 | .ancestors() | ||
454 | } | ||
455 | } | ||
456 | |||
457 | impl<'a> From<rowan::SyntaxElement<'a, RaTypes>> for SyntaxElement<'a> { | ||
458 | fn from(el: rowan::SyntaxElement<'a, RaTypes>) -> Self { | ||
459 | match el { | ||
460 | rowan::SyntaxElement::Node(n) => SyntaxElement::Node(SyntaxNode::from_repr(n)), | ||
461 | rowan::SyntaxElement::Token(t) => SyntaxElement::Token(t.into()), | ||
462 | } | ||
463 | } | ||
464 | } | ||
465 | |||
466 | impl<'a> From<&'a SyntaxNode> for SyntaxElement<'a> { | ||
467 | fn from(node: &'a SyntaxNode) -> SyntaxElement<'a> { | ||
468 | SyntaxElement::Node(node) | ||
469 | } | ||
470 | } | ||
471 | |||
472 | impl<'a> From<SyntaxToken<'a>> for SyntaxElement<'a> { | ||
473 | fn from(token: SyntaxToken<'a>) -> SyntaxElement<'a> { | ||
474 | SyntaxElement::Token(token) | ||
475 | } | ||
476 | } | ||
477 | |||
478 | impl<'a> SyntaxElement<'a> { | ||
479 | pub fn range(&self) -> TextRange { | ||
480 | match self { | ||
481 | SyntaxElement::Node(it) => it.range(), | ||
482 | SyntaxElement::Token(it) => it.range(), | ||
483 | } | ||
259 | } | 484 | } |
260 | } | 485 | } |
261 | 486 | ||
@@ -270,11 +495,14 @@ impl<'a> Iterator for SyntaxNodeChildren<'a> { | |||
270 | } | 495 | } |
271 | } | 496 | } |
272 | 497 | ||
273 | fn has_short_text(kind: SyntaxKind) -> bool { | 498 | #[derive(Debug)] |
274 | use crate::SyntaxKind::*; | 499 | pub struct SyntaxElementChildren<'a>(rowan::SyntaxElementChildren<'a, RaTypes>); |
275 | match kind { | 500 | |
276 | IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, | 501 | impl<'a> Iterator for SyntaxElementChildren<'a> { |
277 | _ => false, | 502 | type Item = SyntaxElement<'a>; |
503 | |||
504 | fn next(&mut self) -> Option<SyntaxElement<'a>> { | ||
505 | self.0.next().map(SyntaxElement::from) | ||
278 | } | 506 | } |
279 | } | 507 | } |
280 | 508 | ||
@@ -304,16 +532,16 @@ impl SyntaxTreeBuilder { | |||
304 | node | 532 | node |
305 | } | 533 | } |
306 | 534 | ||
307 | pub fn leaf(&mut self, kind: SyntaxKind, text: SmolStr) { | 535 | pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { |
308 | self.inner.leaf(kind, text) | 536 | self.inner.token(kind, text) |
309 | } | 537 | } |
310 | 538 | ||
311 | pub fn start_branch(&mut self, kind: SyntaxKind) { | 539 | pub fn start_node(&mut self, kind: SyntaxKind) { |
312 | self.inner.start_internal(kind) | 540 | self.inner.start_node(kind) |
313 | } | 541 | } |
314 | 542 | ||
315 | pub fn finish_branch(&mut self) { | 543 | pub fn finish_node(&mut self) { |
316 | self.inner.finish_internal() | 544 | self.inner.finish_node() |
317 | } | 545 | } |
318 | 546 | ||
319 | pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { | 547 | pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { |