From 27c7ef6d65ffa6a642768377d3f0ba85ac8564bf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 5 May 2020 23:23:29 +0200 Subject: Use more natural signature for Edit::apply --- crates/ra_ide/src/ssr.rs | 24 +++++++++++++++--------- crates/ra_syntax/src/lib.rs | 3 ++- crates/ra_syntax/src/parsing/reparsing.rs | 14 +++++++++----- crates/ra_text_edit/src/lib.rs | 21 ++++++++++++++++----- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index 7b93ff2d2..e213da606 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs @@ -401,16 +401,22 @@ fn render_replace( ignored_comments: &Vec, template: &SsrTemplate, ) -> String { - let mut builder = TextEditBuilder::default(); - for element in template.template.descendants() { - if let Some(var) = template.placeholders.get(&element) { - builder.replace(element.text_range(), binding[var].to_string()) + let edit = { + let mut builder = TextEditBuilder::default(); + for element in template.template.descendants() { + if let Some(var) = template.placeholders.get(&element) { + builder.replace(element.text_range(), binding[var].to_string()) + } } - } - for comment in ignored_comments { - builder.insert(template.template.text_range().end(), comment.syntax().to_string()) - } - builder.finish().apply(&template.template.text().to_string()) + for comment in ignored_comments { + builder.insert(template.template.text_range().end(), comment.syntax().to_string()) + } + builder.finish() + }; + + let mut text = template.template.text().to_string(); + edit.apply(&mut text); + text } #[cfg(test)] diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 1a7348dac..61e686da5 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -142,7 +142,8 @@ impl Parse { } fn full_reparse(&self, indel: &Indel) -> Parse { - let text = indel.apply(self.tree().syntax().text().to_string()); + let mut text = self.tree().syntax().text().to_string(); + indel.apply(&mut text); SourceFile::parse(&text) } } diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 6257e3f33..edbc190f8 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -109,14 +109,14 @@ fn reparse_block<'node>( } fn get_text_after_edit(element: SyntaxElement, edit: &Indel) -> String { - let edit = - Indel::replace(edit.delete - element.text_range().start(), edit.insert.clone()); + let edit = Indel::replace(edit.delete - element.text_range().start(), edit.insert.clone()); - let text = match element { + let mut text = match element { NodeOrToken::Token(token) => token.text().to_string(), NodeOrToken::Node(node) => node.text().to_string(), }; - edit.apply(text) + edit.apply(&mut text); + text } fn is_contextual_kw(text: &str) -> bool { @@ -199,7 +199,11 @@ mod tests { fn do_check(before: &str, replace_with: &str, reparsed_len: u32) { let (range, before) = extract_range(before); let edit = Indel::replace(range, replace_with.to_owned()); - let after = edit.apply(before.clone()); + let after = { + let mut after = before.clone(); + edit.apply(&mut after); + after + }; let fully_reparsed = SourceFile::parse(&after); let incrementally_reparsed: Parse = { diff --git a/crates/ra_text_edit/src/lib.rs b/crates/ra_text_edit/src/lib.rs index c41bf324b..7138bbc65 100644 --- a/crates/ra_text_edit/src/lib.rs +++ b/crates/ra_text_edit/src/lib.rs @@ -37,11 +37,10 @@ impl Indel { Indel { delete: range, insert: replace_with } } - pub fn apply(&self, mut text: String) -> String { + pub fn apply(&self, text: &mut String) { let start: usize = self.delete.start().into(); let end: usize = self.delete.end().into(); text.replace_range(start..end, &self.insert); - text } } @@ -76,8 +75,17 @@ impl TextEdit { &self.indels } - pub fn apply(&self, text: &str) -> String { - let mut total_len = TextSize::of(text); + pub fn apply(&self, text: &mut String) { + match self.indels.len() { + 0 => return, + 1 => { + self.indels[0].apply(text); + return; + } + _ => (), + } + + let mut total_len = TextSize::of(&*text); for indel in self.indels.iter() { total_len += TextSize::of(&indel.insert); total_len -= indel.delete.end() - indel.delete.start(); @@ -95,7 +103,10 @@ impl TextEdit { } buf.push_str(&text[prev..text.len()]); assert_eq!(TextSize::of(&buf), total_len); - buf + + // FIXME: figure out a way to mutate the text in-place or reuse the + // memory in some other way + *text = buf } pub fn apply_to_offset(&self, offset: TextSize) -> Option { -- cgit v1.2.3