diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 323 | ||||
-rw-r--r-- | crates/syntax/src/ast.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/ast/generated.rs | 6 | ||||
-rw-r--r-- | crates/syntax/src/lib.rs | 11 | ||||
-rw-r--r-- | crates/syntax/src/parsing.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/parsing/text_token_source.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/syntax_node.rs | 6 |
7 files changed, 275 insertions, 79 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 4f9a7a6e8..9dc7182bd 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -137,7 +137,7 @@ impl TreeDiff { | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | /// Finds minimal the diff, which, applied to `from`, will result in `to`. | 140 | /// Finds a (potentially minimal) diff, which, applied to `from`, will result in `to`. |
141 | /// | 141 | /// |
142 | /// Specifically, returns a structure that consists of a replacements, insertions and deletions | 142 | /// Specifically, returns a structure that consists of a replacements, insertions and deletions |
143 | /// such that applying this map on `from` will result in `to`. | 143 | /// such that applying this map on `from` will result in `to`. |
@@ -151,7 +151,6 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { | |||
151 | }; | 151 | }; |
152 | let (from, to) = (from.clone().into(), to.clone().into()); | 152 | let (from, to) = (from.clone().into(), to.clone().into()); |
153 | 153 | ||
154 | // FIXME: this is horrible inefficient. I bet there's a cool algorithm to diff trees properly. | ||
155 | if !syntax_element_eq(&from, &to) { | 154 | if !syntax_element_eq(&from, &to) { |
156 | go(&mut diff, from, to); | 155 | go(&mut diff, from, to); |
157 | } | 156 | } |
@@ -169,6 +168,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { | |||
169 | } | 168 | } |
170 | } | 169 | } |
171 | 170 | ||
171 | // FIXME: this is horrible inefficient. I bet there's a cool algorithm to diff trees properly. | ||
172 | fn go(diff: &mut TreeDiff, lhs: SyntaxElement, rhs: SyntaxElement) { | 172 | fn go(diff: &mut TreeDiff, lhs: SyntaxElement, rhs: SyntaxElement) { |
173 | let (lhs, rhs) = match lhs.as_node().zip(rhs.as_node()) { | 173 | let (lhs, rhs) = match lhs.as_node().zip(rhs.as_node()) { |
174 | Some((lhs, rhs)) => (lhs, rhs), | 174 | Some((lhs, rhs)) => (lhs, rhs), |
@@ -179,6 +179,8 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { | |||
179 | } | 179 | } |
180 | }; | 180 | }; |
181 | 181 | ||
182 | let mut look_ahead_scratch = Vec::default(); | ||
183 | |||
182 | let mut rhs_children = rhs.children_with_tokens(); | 184 | let mut rhs_children = rhs.children_with_tokens(); |
183 | let mut lhs_children = lhs.children_with_tokens(); | 185 | let mut lhs_children = lhs.children_with_tokens(); |
184 | let mut last_lhs = None; | 186 | let mut last_lhs = None; |
@@ -204,7 +206,31 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { | |||
204 | diff.deletions.push(element); | 206 | diff.deletions.push(element); |
205 | } | 207 | } |
206 | (Some(ref lhs_ele), Some(ref rhs_ele)) if syntax_element_eq(lhs_ele, rhs_ele) => {} | 208 | (Some(ref lhs_ele), Some(ref rhs_ele)) if syntax_element_eq(lhs_ele, rhs_ele) => {} |
207 | (Some(lhs_ele), Some(rhs_ele)) => go(diff, lhs_ele, rhs_ele), | 209 | (Some(lhs_ele), Some(rhs_ele)) => { |
210 | // nodes differ, look for lhs_ele in rhs, if its found we can mark everything up | ||
211 | // until that element as insertions. This is important to keep the diff minimal | ||
212 | // in regards to insertions that have been actually done, this is important for | ||
213 | // use insertions as we do not want to replace the entire module node. | ||
214 | look_ahead_scratch.push(rhs_ele.clone()); | ||
215 | let mut rhs_children_clone = rhs_children.clone(); | ||
216 | let mut insert = false; | ||
217 | while let Some(rhs_child) = rhs_children_clone.next() { | ||
218 | if syntax_element_eq(&lhs_ele, &rhs_child) { | ||
219 | mark::hit!(diff_insertions); | ||
220 | insert = true; | ||
221 | break; | ||
222 | } else { | ||
223 | look_ahead_scratch.push(rhs_child); | ||
224 | } | ||
225 | } | ||
226 | let drain = look_ahead_scratch.drain(..); | ||
227 | if let Some(prev) = last_lhs.clone().filter(|_| insert) { | ||
228 | diff.insertions.entry(prev).or_insert_with(Vec::new).extend(drain); | ||
229 | rhs_children = rhs_children_clone; | ||
230 | } else { | ||
231 | go(diff, lhs_ele, rhs_ele) | ||
232 | } | ||
233 | } | ||
208 | } | 234 | } |
209 | last_lhs = lhs_child.or(last_lhs); | 235 | last_lhs = lhs_child.or(last_lhs); |
210 | } | 236 | } |
@@ -289,11 +315,18 @@ fn _replace_children( | |||
289 | with_children(parent, new_children) | 315 | with_children(parent, new_children) |
290 | } | 316 | } |
291 | 317 | ||
318 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
319 | enum InsertPos { | ||
320 | FirstChildOf(SyntaxNode), | ||
321 | After(SyntaxElement), | ||
322 | } | ||
323 | |||
292 | #[derive(Default)] | 324 | #[derive(Default)] |
293 | pub struct SyntaxRewriter<'a> { | 325 | pub struct SyntaxRewriter<'a> { |
294 | f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>, | 326 | f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>, |
295 | //FIXME: add debug_assertions that all elements are in fact from the same file. | 327 | //FIXME: add debug_assertions that all elements are in fact from the same file. |
296 | replacements: FxHashMap<SyntaxElement, Replacement>, | 328 | replacements: FxHashMap<SyntaxElement, Replacement>, |
329 | insertions: IndexMap<InsertPos, Vec<SyntaxElement>>, | ||
297 | } | 330 | } |
298 | 331 | ||
299 | impl fmt::Debug for SyntaxRewriter<'_> { | 332 | impl fmt::Debug for SyntaxRewriter<'_> { |
@@ -304,13 +337,96 @@ impl fmt::Debug for SyntaxRewriter<'_> { | |||
304 | 337 | ||
305 | impl<'a> SyntaxRewriter<'a> { | 338 | impl<'a> SyntaxRewriter<'a> { |
306 | pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> { | 339 | pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> { |
307 | SyntaxRewriter { f: Some(Box::new(f)), replacements: FxHashMap::default() } | 340 | SyntaxRewriter { |
341 | f: Some(Box::new(f)), | ||
342 | replacements: FxHashMap::default(), | ||
343 | insertions: IndexMap::default(), | ||
344 | } | ||
308 | } | 345 | } |
309 | pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) { | 346 | pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) { |
310 | let what = what.clone().into(); | 347 | let what = what.clone().into(); |
311 | let replacement = Replacement::Delete; | 348 | let replacement = Replacement::Delete; |
312 | self.replacements.insert(what, replacement); | 349 | self.replacements.insert(what, replacement); |
313 | } | 350 | } |
351 | pub fn insert_before<T: Clone + Into<SyntaxElement>, U: Clone + Into<SyntaxElement>>( | ||
352 | &mut self, | ||
353 | before: &T, | ||
354 | what: &U, | ||
355 | ) { | ||
356 | let before = before.clone().into(); | ||
357 | let pos = match before.prev_sibling_or_token() { | ||
358 | Some(sibling) => InsertPos::After(sibling), | ||
359 | None => match before.parent() { | ||
360 | Some(parent) => InsertPos::FirstChildOf(parent), | ||
361 | None => return, | ||
362 | }, | ||
363 | }; | ||
364 | self.insertions.entry(pos).or_insert_with(Vec::new).push(what.clone().into()); | ||
365 | } | ||
366 | pub fn insert_after<T: Clone + Into<SyntaxElement>, U: Clone + Into<SyntaxElement>>( | ||
367 | &mut self, | ||
368 | after: &T, | ||
369 | what: &U, | ||
370 | ) { | ||
371 | self.insertions | ||
372 | .entry(InsertPos::After(after.clone().into())) | ||
373 | .or_insert_with(Vec::new) | ||
374 | .push(what.clone().into()); | ||
375 | } | ||
376 | pub fn insert_as_first_child<T: Clone + Into<SyntaxNode>, U: Clone + Into<SyntaxElement>>( | ||
377 | &mut self, | ||
378 | parent: &T, | ||
379 | what: &U, | ||
380 | ) { | ||
381 | self.insertions | ||
382 | .entry(InsertPos::FirstChildOf(parent.clone().into())) | ||
383 | .or_insert_with(Vec::new) | ||
384 | .push(what.clone().into()); | ||
385 | } | ||
386 | pub fn insert_many_before< | ||
387 | T: Clone + Into<SyntaxElement>, | ||
388 | U: IntoIterator<Item = SyntaxElement>, | ||
389 | >( | ||
390 | &mut self, | ||
391 | before: &T, | ||
392 | what: U, | ||
393 | ) { | ||
394 | let before = before.clone().into(); | ||
395 | let pos = match before.prev_sibling_or_token() { | ||
396 | Some(sibling) => InsertPos::After(sibling), | ||
397 | None => match before.parent() { | ||
398 | Some(parent) => InsertPos::FirstChildOf(parent), | ||
399 | None => return, | ||
400 | }, | ||
401 | }; | ||
402 | self.insertions.entry(pos).or_insert_with(Vec::new).extend(what); | ||
403 | } | ||
404 | pub fn insert_many_after< | ||
405 | T: Clone + Into<SyntaxElement>, | ||
406 | U: IntoIterator<Item = SyntaxElement>, | ||
407 | >( | ||
408 | &mut self, | ||
409 | after: &T, | ||
410 | what: U, | ||
411 | ) { | ||
412 | self.insertions | ||
413 | .entry(InsertPos::After(after.clone().into())) | ||
414 | .or_insert_with(Vec::new) | ||
415 | .extend(what); | ||
416 | } | ||
417 | pub fn insert_many_as_first_children< | ||
418 | T: Clone + Into<SyntaxNode>, | ||
419 | U: IntoIterator<Item = SyntaxElement>, | ||
420 | >( | ||
421 | &mut self, | ||
422 | parent: &T, | ||
423 | what: U, | ||
424 | ) { | ||
425 | self.insertions | ||
426 | .entry(InsertPos::FirstChildOf(parent.clone().into())) | ||
427 | .or_insert_with(Vec::new) | ||
428 | .extend(what) | ||
429 | } | ||
314 | pub fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) { | 430 | pub fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) { |
315 | let what = what.clone().into(); | 431 | let what = what.clone().into(); |
316 | let replacement = Replacement::Single(with.clone().into()); | 432 | let replacement = Replacement::Single(with.clone().into()); |
@@ -330,7 +446,7 @@ impl<'a> SyntaxRewriter<'a> { | |||
330 | } | 446 | } |
331 | 447 | ||
332 | pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { | 448 | pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { |
333 | if self.f.is_none() && self.replacements.is_empty() { | 449 | if self.f.is_none() && self.replacements.is_empty() && self.insertions.is_empty() { |
334 | return node.clone(); | 450 | return node.clone(); |
335 | } | 451 | } |
336 | self.rewrite_children(node) | 452 | self.rewrite_children(node) |
@@ -346,14 +462,22 @@ impl<'a> SyntaxRewriter<'a> { | |||
346 | /// | 462 | /// |
347 | /// Returns `None` when there are no replacements. | 463 | /// Returns `None` when there are no replacements. |
348 | pub fn rewrite_root(&self) -> Option<SyntaxNode> { | 464 | pub fn rewrite_root(&self) -> Option<SyntaxNode> { |
465 | fn element_to_node_or_parent(element: &SyntaxElement) -> SyntaxNode { | ||
466 | match element { | ||
467 | SyntaxElement::Node(it) => it.clone(), | ||
468 | SyntaxElement::Token(it) => it.parent(), | ||
469 | } | ||
470 | } | ||
471 | |||
349 | assert!(self.f.is_none()); | 472 | assert!(self.f.is_none()); |
350 | self.replacements | 473 | self.replacements |
351 | .keys() | 474 | .keys() |
352 | .map(|element| match element { | 475 | .map(element_to_node_or_parent) |
353 | SyntaxElement::Node(it) => it.clone(), | 476 | .chain(self.insertions.keys().map(|pos| match pos { |
354 | SyntaxElement::Token(it) => it.parent(), | 477 | InsertPos::FirstChildOf(it) => it.clone(), |
355 | }) | 478 | InsertPos::After(it) => element_to_node_or_parent(it), |
356 | // If we only have one replacement, we must return its parent node, since `rewrite` does | 479 | })) |
480 | // If we only have one replacement/insertion, we must return its parent node, since `rewrite` does | ||
357 | // not replace the node passed to it. | 481 | // not replace the node passed to it. |
358 | .map(|it| it.parent().unwrap_or(it)) | 482 | .map(|it| it.parent().unwrap_or(it)) |
359 | .fold1(|a, b| least_common_ancestor(&a, &b).unwrap()) | 483 | .fold1(|a, b| least_common_ancestor(&a, &b).unwrap()) |
@@ -367,9 +491,16 @@ impl<'a> SyntaxRewriter<'a> { | |||
367 | self.replacements.get(element).cloned() | 491 | self.replacements.get(element).cloned() |
368 | } | 492 | } |
369 | 493 | ||
494 | fn insertions(&self, pos: &InsertPos) -> Option<impl Iterator<Item = SyntaxElement> + '_> { | ||
495 | self.insertions.get(pos).map(|insertions| insertions.iter().cloned()) | ||
496 | } | ||
497 | |||
370 | fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode { | 498 | fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode { |
371 | // FIXME: this could be made much faster. | 499 | // FIXME: this could be made much faster. |
372 | let mut new_children = Vec::new(); | 500 | let mut new_children = Vec::new(); |
501 | if let Some(elements) = self.insertions(&InsertPos::FirstChildOf(node.clone())) { | ||
502 | new_children.extend(elements.map(element_to_green)); | ||
503 | } | ||
373 | for child in node.children_with_tokens() { | 504 | for child in node.children_with_tokens() { |
374 | self.rewrite_self(&mut new_children, &child); | 505 | self.rewrite_self(&mut new_children, &child); |
375 | } | 506 | } |
@@ -383,34 +514,45 @@ impl<'a> SyntaxRewriter<'a> { | |||
383 | ) { | 514 | ) { |
384 | if let Some(replacement) = self.replacement(&element) { | 515 | if let Some(replacement) = self.replacement(&element) { |
385 | match replacement { | 516 | match replacement { |
386 | Replacement::Single(NodeOrToken::Node(it)) => { | 517 | Replacement::Single(element) => acc.push(element_to_green(element)), |
387 | acc.push(NodeOrToken::Node(it.green().clone())) | ||
388 | } | ||
389 | Replacement::Single(NodeOrToken::Token(it)) => { | ||
390 | acc.push(NodeOrToken::Token(it.green().clone())) | ||
391 | } | ||
392 | Replacement::Many(replacements) => { | 518 | Replacement::Many(replacements) => { |
393 | acc.extend(replacements.iter().map(|it| match it { | 519 | acc.extend(replacements.into_iter().map(element_to_green)) |
394 | NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()), | ||
395 | NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), | ||
396 | })) | ||
397 | } | 520 | } |
398 | Replacement::Delete => (), | 521 | Replacement::Delete => (), |
399 | }; | 522 | }; |
400 | return; | 523 | } else { |
524 | match element { | ||
525 | NodeOrToken::Token(it) => acc.push(NodeOrToken::Token(it.green().clone())), | ||
526 | NodeOrToken::Node(it) => { | ||
527 | acc.push(NodeOrToken::Node(self.rewrite_children(it).green().clone())); | ||
528 | } | ||
529 | } | ||
401 | } | 530 | } |
402 | let res = match element { | 531 | if let Some(elements) = self.insertions(&InsertPos::After(element.clone())) { |
403 | NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), | 532 | acc.extend(elements.map(element_to_green)); |
404 | NodeOrToken::Node(it) => NodeOrToken::Node(self.rewrite_children(it).green().clone()), | 533 | } |
405 | }; | 534 | } |
406 | acc.push(res) | 535 | } |
536 | |||
537 | fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { | ||
538 | match element { | ||
539 | NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()), | ||
540 | NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), | ||
407 | } | 541 | } |
408 | } | 542 | } |
409 | 543 | ||
410 | impl ops::AddAssign for SyntaxRewriter<'_> { | 544 | impl ops::AddAssign for SyntaxRewriter<'_> { |
411 | fn add_assign(&mut self, rhs: SyntaxRewriter) { | 545 | fn add_assign(&mut self, rhs: SyntaxRewriter) { |
412 | assert!(rhs.f.is_none()); | 546 | assert!(rhs.f.is_none()); |
413 | self.replacements.extend(rhs.replacements) | 547 | self.replacements.extend(rhs.replacements); |
548 | for (pos, insertions) in rhs.insertions.into_iter() { | ||
549 | match self.insertions.entry(pos) { | ||
550 | indexmap::map::Entry::Occupied(mut occupied) => { | ||
551 | occupied.get_mut().extend(insertions) | ||
552 | } | ||
553 | indexmap::map::Entry::Vacant(vacant) => drop(vacant.insert(insertions)), | ||
554 | } | ||
555 | } | ||
414 | } | 556 | } |
415 | } | 557 | } |
416 | 558 | ||
@@ -486,18 +628,44 @@ mod tests { | |||
486 | } | 628 | } |
487 | 629 | ||
488 | #[test] | 630 | #[test] |
489 | fn insert() { | 631 | fn replace_parent() { |
632 | mark::check!(diff_replace_parent); | ||
633 | check_diff( | ||
634 | r#""#, | ||
635 | r#"use foo::bar;"#, | ||
636 | expect![[r#" | ||
637 | insertions: | ||
638 | |||
639 | |||
640 | |||
641 | replacements: | ||
642 | |||
643 | Line 0: Node([email protected]) -> use foo::bar; | ||
644 | |||
645 | deletions: | ||
646 | |||
647 | |||
648 | "#]], | ||
649 | ); | ||
650 | } | ||
651 | |||
652 | #[test] | ||
653 | fn insert_last() { | ||
490 | mark::check!(diff_insert); | 654 | mark::check!(diff_insert); |
491 | check_diff( | 655 | check_diff( |
492 | r#"use foo;"#, | 656 | r#" |
493 | r#"use foo; | 657 | use foo; |
494 | use bar;"#, | 658 | use bar;"#, |
659 | r#" | ||
660 | use foo; | ||
661 | use bar; | ||
662 | use baz;"#, | ||
495 | expect![[r#" | 663 | expect![[r#" |
496 | insertions: | 664 | insertions: |
497 | 665 | ||
498 | Line 0: Node([email protected]) | 666 | Line 2: Node(USE@10..18) |
499 | -> "\n" | 667 | -> "\n" |
500 | -> use bar; | 668 | -> use baz; |
501 | 669 | ||
502 | replacements: | 670 | replacements: |
503 | 671 | ||
@@ -511,29 +679,63 @@ use bar;"#, | |||
511 | } | 679 | } |
512 | 680 | ||
513 | #[test] | 681 | #[test] |
514 | fn replace_parent() { | 682 | fn insert_middle() { |
515 | mark::check!(diff_replace_parent); | ||
516 | check_diff( | 683 | check_diff( |
517 | r#""#, | 684 | r#" |
518 | r#"use foo::bar;"#, | 685 | use foo; |
686 | use baz;"#, | ||
687 | r#" | ||
688 | use foo; | ||
689 | use bar; | ||
690 | use baz;"#, | ||
519 | expect![[r#" | 691 | expect![[r#" |
520 | insertions: | 692 | insertions: |
521 | 693 | ||
694 | Line 2: Token([email protected] "\n") | ||
695 | -> use bar; | ||
696 | -> "\n" | ||
697 | |||
698 | replacements: | ||
699 | |||
700 | |||
701 | |||
702 | deletions: | ||
703 | |||
522 | 704 | ||
705 | "#]], | ||
706 | ) | ||
707 | } | ||
708 | |||
709 | #[test] | ||
710 | fn insert_first() { | ||
711 | check_diff( | ||
712 | r#" | ||
713 | use bar; | ||
714 | use baz;"#, | ||
715 | r#" | ||
716 | use foo; | ||
717 | use bar; | ||
718 | use baz;"#, | ||
719 | expect![[r#" | ||
720 | insertions: | ||
721 | |||
722 | Line 0: Token([email protected] "\n") | ||
723 | -> use foo; | ||
724 | -> "\n" | ||
523 | 725 | ||
524 | replacements: | 726 | replacements: |
525 | 727 | ||
526 | Line 0: Node([email protected]) -> use foo::bar; | 728 | |
527 | 729 | ||
528 | deletions: | 730 | deletions: |
529 | 731 | ||
530 | 732 | ||
531 | "#]], | 733 | "#]], |
532 | ); | 734 | ) |
533 | } | 735 | } |
534 | 736 | ||
535 | #[test] | 737 | #[test] |
536 | fn delete() { | 738 | fn delete_last() { |
537 | mark::check!(diff_delete); | 739 | mark::check!(diff_delete); |
538 | check_diff( | 740 | check_diff( |
539 | r#"use foo; | 741 | r#"use foo; |
@@ -557,52 +759,50 @@ use bar;"#, | |||
557 | } | 759 | } |
558 | 760 | ||
559 | #[test] | 761 | #[test] |
560 | fn insert_use() { | 762 | fn delete_middle() { |
763 | mark::check!(diff_insertions); | ||
561 | check_diff( | 764 | check_diff( |
562 | r#" | 765 | r#" |
563 | use expect_test::{expect, Expect}; | 766 | use expect_test::{expect, Expect}; |
767 | use text_edit::TextEdit; | ||
564 | 768 | ||
565 | use crate::AstNode; | 769 | use crate::AstNode; |
566 | "#, | 770 | "#, |
567 | r#" | 771 | r#" |
568 | use expect_test::{expect, Expect}; | 772 | use expect_test::{expect, Expect}; |
569 | use text_edit::TextEdit; | ||
570 | 773 | ||
571 | use crate::AstNode; | 774 | use crate::AstNode; |
572 | "#, | 775 | "#, |
573 | expect![[r#" | 776 | expect![[r#" |
574 | insertions: | 777 | insertions: |
575 | 778 | ||
576 | Line 4: Token([email protected] "\n") | 779 | Line 1: Node([email protected]) |
780 | -> "\n\n" | ||
577 | -> use crate::AstNode; | 781 | -> use crate::AstNode; |
578 | -> "\n" | ||
579 | 782 | ||
580 | replacements: | 783 | replacements: |
581 | 784 | ||
582 | Line 2: Token([email protected] "\n\n") -> "\n" | ||
583 | Line 4: Token([email protected] "crate") -> text_edit | ||
584 | Line 4: Token([email protected] "AstNode") -> TextEdit | ||
585 | Line 4: Token([email protected] "\n") -> "\n\n" | ||
586 | 785 | ||
587 | deletions: | ||
588 | 786 | ||
787 | deletions: | ||
589 | 788 | ||
789 | Line 2: use text_edit::TextEdit; | ||
790 | Line 3: "\n\n" | ||
791 | Line 4: use crate::AstNode; | ||
792 | Line 5: "\n" | ||
590 | "#]], | 793 | "#]], |
591 | ) | 794 | ) |
592 | } | 795 | } |
593 | 796 | ||
594 | #[test] | 797 | #[test] |
595 | fn remove_use() { | 798 | fn delete_first() { |
596 | check_diff( | 799 | check_diff( |
597 | r#" | 800 | r#" |
598 | use expect_test::{expect, Expect}; | ||
599 | use text_edit::TextEdit; | 801 | use text_edit::TextEdit; |
600 | 802 | ||
601 | use crate::AstNode; | 803 | use crate::AstNode; |
602 | "#, | 804 | "#, |
603 | r#" | 805 | r#" |
604 | use expect_test::{expect, Expect}; | ||
605 | |||
606 | use crate::AstNode; | 806 | use crate::AstNode; |
607 | "#, | 807 | "#, |
608 | expect![[r#" | 808 | expect![[r#" |
@@ -612,15 +812,14 @@ use crate::AstNode; | |||
612 | 812 | ||
613 | replacements: | 813 | replacements: |
614 | 814 | ||
615 | Line 2: Token([email protected] "\n") -> "\n\n" | 815 | Line 2: Node([email protected]) -> crate |
616 | Line 3: Node([email protected]) -> crate | 816 | Line 2: Token([email protected] "TextEdit") -> AstNode |
617 | Line 3: Token([email protected] "TextEdit") -> AstNode | 817 | Line 2: Token([email protected] "\n\n") -> "\n" |
618 | Line 3: Token([email protected] "\n\n") -> "\n" | ||
619 | 818 | ||
620 | deletions: | 819 | deletions: |
621 | 820 | ||
622 | Line 4: use crate::AstNode; | 821 | Line 3: use crate::AstNode; |
623 | Line 5: "\n" | 822 | Line 4: "\n" |
624 | "#]], | 823 | "#]], |
625 | ) | 824 | ) |
626 | } | 825 | } |
@@ -697,17 +896,15 @@ fn main() { | |||
697 | _ => return, | 896 | _ => return, |
698 | } | 897 | } |
699 | -> ; | 898 | -> ; |
700 | Line 5: Token(R_CURLY@64..65 "}") | 899 | Line 3: Node(IF_EXPR@17..63) |
701 | -> "\n" | 900 | -> "\n " |
702 | -> } | 901 | -> foo(x); |
703 | 902 | ||
704 | replacements: | 903 | replacements: |
705 | 904 | ||
706 | Line 3: Token([email protected] "if") -> let | 905 | Line 3: Token([email protected] "if") -> let |
707 | Line 3: Token([email protected] "let") -> x | 906 | Line 3: Token([email protected] "let") -> x |
708 | Line 3: Node([email protected]) -> = | 907 | Line 3: Node([email protected]) -> = |
709 | Line 5: Token([email protected] "\n") -> "\n " | ||
710 | Line 5: Token([email protected] "}") -> foo(x); | ||
711 | 908 | ||
712 | deletions: | 909 | deletions: |
713 | 910 | ||
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index d536bb1e7..8a0e3d27b 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | 17 | ||
18 | pub use self::{ | 18 | pub use self::{ |
19 | expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, | 19 | expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, |
20 | generated::*, | 20 | generated::{nodes::*, tokens::*}, |
21 | node_ext::{ | 21 | node_ext::{ |
22 | AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, | 22 | AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, |
23 | StructKind, TypeBoundKind, VisibilityKind, | 23 | StructKind, TypeBoundKind, VisibilityKind, |
diff --git a/crates/syntax/src/ast/generated.rs b/crates/syntax/src/ast/generated.rs index 4a6f41ee7..843b43cf0 100644 --- a/crates/syntax/src/ast/generated.rs +++ b/crates/syntax/src/ast/generated.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! This file is actually hand-written, but the submodules are indeed generated. | 1 | //! This file is actually hand-written, but the submodules are indeed generated. |
2 | #[rustfmt::skip] | 2 | #[rustfmt::skip] |
3 | mod nodes; | 3 | pub(crate) mod nodes; |
4 | #[rustfmt::skip] | 4 | #[rustfmt::skip] |
5 | mod tokens; | 5 | pub(crate) mod tokens; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | AstNode, | 8 | AstNode, |
@@ -10,7 +10,7 @@ use crate::{ | |||
10 | SyntaxNode, | 10 | SyntaxNode, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub use {nodes::*, tokens::*}; | 13 | pub(crate) use nodes::*; |
14 | 14 | ||
15 | // Stmt is the only nested enum, so it's easier to just hand-write it | 15 | // Stmt is the only nested enum, so it's easier to just hand-write it |
16 | impl AstNode for Stmt { | 16 | impl AstNode for Stmt { |
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 849a1cdd6..e753b11bb 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs | |||
@@ -46,16 +46,19 @@ use text_edit::Indel; | |||
46 | pub use crate::{ | 46 | pub use crate::{ |
47 | algo::InsertPosition, | 47 | algo::InsertPosition, |
48 | ast::{AstNode, AstToken}, | 48 | ast::{AstNode, AstToken}, |
49 | parsing::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token}, | 49 | parsing::lexer::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token}, |
50 | ptr::{AstPtr, SyntaxNodePtr}, | 50 | ptr::{AstPtr, SyntaxNodePtr}, |
51 | syntax_error::SyntaxError, | 51 | syntax_error::SyntaxError, |
52 | syntax_node::{ | 52 | syntax_node::{ |
53 | Direction, GreenNode, NodeOrToken, SyntaxElement, SyntaxElementChildren, SyntaxNode, | 53 | SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, |
54 | SyntaxNodeChildren, SyntaxToken, SyntaxTreeBuilder, | 54 | SyntaxTreeBuilder, |
55 | }, | 55 | }, |
56 | }; | 56 | }; |
57 | pub use parser::{SyntaxKind, T}; | 57 | pub use parser::{SyntaxKind, T}; |
58 | pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent}; | 58 | pub use rowan::{ |
59 | Direction, GreenNode, NodeOrToken, SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, | ||
60 | WalkEvent, | ||
61 | }; | ||
59 | 62 | ||
60 | /// `Parse` is the result of the parsing: a syntax tree and a collection of | 63 | /// `Parse` is the result of the parsing: a syntax tree and a collection of |
61 | /// errors. | 64 | /// errors. |
diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs index 68a39eb21..333bde54a 100644 --- a/crates/syntax/src/parsing.rs +++ b/crates/syntax/src/parsing.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Lexing, bridging to parser (which does the actual parsing) and | 1 | //! Lexing, bridging to parser (which does the actual parsing) and |
2 | //! incremental reparsing. | 2 | //! incremental reparsing. |
3 | 3 | ||
4 | mod lexer; | 4 | pub(crate) mod lexer; |
5 | mod text_token_source; | 5 | mod text_token_source; |
6 | mod text_tree_sink; | 6 | mod text_tree_sink; |
7 | mod reparsing; | 7 | mod reparsing; |
@@ -10,7 +10,7 @@ use crate::{syntax_node::GreenNode, AstNode, SyntaxError, SyntaxNode}; | |||
10 | use text_token_source::TextTokenSource; | 10 | use text_token_source::TextTokenSource; |
11 | use text_tree_sink::TextTreeSink; | 11 | use text_tree_sink::TextTreeSink; |
12 | 12 | ||
13 | pub use lexer::*; | 13 | pub(crate) use lexer::*; |
14 | 14 | ||
15 | pub(crate) use self::reparsing::incremental_reparse; | 15 | pub(crate) use self::reparsing::incremental_reparse; |
16 | use parser::SyntaxKind; | 16 | use parser::SyntaxKind; |
diff --git a/crates/syntax/src/parsing/text_token_source.rs b/crates/syntax/src/parsing/text_token_source.rs index df866dc2b..0614194a5 100644 --- a/crates/syntax/src/parsing/text_token_source.rs +++ b/crates/syntax/src/parsing/text_token_source.rs | |||
@@ -65,7 +65,7 @@ fn mk_token(pos: usize, token_offset_pairs: &[(Token, TextSize)]) -> parser::Tok | |||
65 | 65 | ||
66 | impl<'t> TextTokenSource<'t> { | 66 | impl<'t> TextTokenSource<'t> { |
67 | /// Generate input from tokens(expect comment and whitespace). | 67 | /// Generate input from tokens(expect comment and whitespace). |
68 | pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> { | 68 | pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> { |
69 | let token_offset_pairs: Vec<_> = raw_tokens | 69 | let token_offset_pairs: Vec<_> = raw_tokens |
70 | .iter() | 70 | .iter() |
71 | .filter_map({ | 71 | .filter_map({ |
diff --git a/crates/syntax/src/syntax_node.rs b/crates/syntax/src/syntax_node.rs index b2abcbfbb..cc30138fa 100644 --- a/crates/syntax/src/syntax_node.rs +++ b/crates/syntax/src/syntax_node.rs | |||
@@ -10,9 +10,7 @@ use rowan::{GreenNodeBuilder, Language}; | |||
10 | 10 | ||
11 | use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; | 11 | use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; |
12 | 12 | ||
13 | pub use rowan::GreenNode; | 13 | pub(crate) use rowan::{GreenNode, GreenToken, NodeOrToken}; |
14 | |||
15 | pub(crate) use rowan::GreenToken; | ||
16 | 14 | ||
17 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
18 | pub enum RustLanguage {} | 16 | pub enum RustLanguage {} |
@@ -34,8 +32,6 @@ pub type SyntaxElement = rowan::SyntaxElement<RustLanguage>; | |||
34 | pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>; | 32 | pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>; |
35 | pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>; | 33 | pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>; |
36 | 34 | ||
37 | pub use rowan::{Direction, NodeOrToken}; | ||
38 | |||
39 | #[derive(Default)] | 35 | #[derive(Default)] |
40 | pub struct SyntaxTreeBuilder { | 36 | pub struct SyntaxTreeBuilder { |
41 | errors: Vec<SyntaxError>, | 37 | errors: Vec<SyntaxError>, |