diff options
Diffstat (limited to 'crates/ra_syntax/src/algo.rs')
-rw-r--r-- | crates/ra_syntax/src/algo.rs | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs index e76f542ce..d55534ede 100644 --- a/crates/ra_syntax/src/algo.rs +++ b/crates/ra_syntax/src/algo.rs | |||
@@ -5,6 +5,7 @@ pub mod visit; | |||
5 | use std::ops::RangeInclusive; | 5 | use std::ops::RangeInclusive; |
6 | 6 | ||
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use ra_text_edit::TextEditBuilder; | ||
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
@@ -65,6 +66,18 @@ pub enum InsertPosition<T> { | |||
65 | After(T), | 66 | After(T), |
66 | } | 67 | } |
67 | 68 | ||
69 | pub struct TreeDiff { | ||
70 | replacements: FxHashMap<SyntaxElement, SyntaxElement>, | ||
71 | } | ||
72 | |||
73 | impl TreeDiff { | ||
74 | pub fn into_text_edit(&self, builder: &mut TextEditBuilder) { | ||
75 | for (from, to) in self.replacements.iter() { | ||
76 | builder.replace(from.text_range(), to.to_string()) | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | |||
68 | /// Finds minimal the diff, which, applied to `from`, will result in `to`. | 81 | /// Finds minimal the diff, which, applied to `from`, will result in `to`. |
69 | /// | 82 | /// |
70 | /// Specifically, returns a map whose keys are descendants of `from` and values | 83 | /// Specifically, returns a map whose keys are descendants of `from` and values |
@@ -72,12 +85,12 @@ pub enum InsertPosition<T> { | |||
72 | /// | 85 | /// |
73 | /// A trivial solution is a singletom map `{ from: to }`, but this function | 86 | /// A trivial solution is a singletom map `{ from: to }`, but this function |
74 | /// tries to find a more fine-grained diff. | 87 | /// tries to find a more fine-grained diff. |
75 | pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> FxHashMap<SyntaxElement, SyntaxElement> { | 88 | pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff { |
76 | let mut buf = FxHashMap::default(); | 89 | let mut buf = FxHashMap::default(); |
77 | // FIXME: this is both horrible inefficient and gives larger than | 90 | // FIXME: this is both horrible inefficient and gives larger than |
78 | // necessary diff. I bet there's a cool algorithm to diff trees properly. | 91 | // necessary diff. I bet there's a cool algorithm to diff trees properly. |
79 | go(&mut buf, from.clone().into(), to.clone().into()); | 92 | go(&mut buf, from.clone().into(), to.clone().into()); |
80 | return buf; | 93 | return TreeDiff { replacements: buf }; |
81 | 94 | ||
82 | fn go( | 95 | fn go( |
83 | buf: &mut FxHashMap<SyntaxElement, SyntaxElement>, | 96 | buf: &mut FxHashMap<SyntaxElement, SyntaxElement>, |