Use more natural signature for Edit::apply

This commit is contained in:
Aleksey Kladov 2020-05-05 23:23:29 +02:00
parent 4a6fa8f0df
commit 27c7ef6d65
4 changed files with 42 additions and 20 deletions

View file

@ -401,6 +401,7 @@ fn render_replace(
ignored_comments: &Vec<Comment>, ignored_comments: &Vec<Comment>,
template: &SsrTemplate, template: &SsrTemplate,
) -> String { ) -> String {
let edit = {
let mut builder = TextEditBuilder::default(); let mut builder = TextEditBuilder::default();
for element in template.template.descendants() { for element in template.template.descendants() {
if let Some(var) = template.placeholders.get(&element) { if let Some(var) = template.placeholders.get(&element) {
@ -410,7 +411,12 @@ fn render_replace(
for comment in ignored_comments { for comment in ignored_comments {
builder.insert(template.template.text_range().end(), comment.syntax().to_string()) builder.insert(template.template.text_range().end(), comment.syntax().to_string())
} }
builder.finish().apply(&template.template.text().to_string()) builder.finish()
};
let mut text = template.template.text().to_string();
edit.apply(&mut text);
text
} }
#[cfg(test)] #[cfg(test)]

View file

@ -142,7 +142,8 @@ impl Parse<SourceFile> {
} }
fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> { fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> {
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) SourceFile::parse(&text)
} }
} }

View file

@ -109,14 +109,14 @@ fn reparse_block<'node>(
} }
fn get_text_after_edit(element: SyntaxElement, edit: &Indel) -> String { fn get_text_after_edit(element: SyntaxElement, edit: &Indel) -> String {
let edit = let edit = Indel::replace(edit.delete - element.text_range().start(), edit.insert.clone());
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::Token(token) => token.text().to_string(),
NodeOrToken::Node(node) => node.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 { fn is_contextual_kw(text: &str) -> bool {
@ -199,7 +199,11 @@ mod tests {
fn do_check(before: &str, replace_with: &str, reparsed_len: u32) { fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
let (range, before) = extract_range(before); let (range, before) = extract_range(before);
let edit = Indel::replace(range, replace_with.to_owned()); 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 fully_reparsed = SourceFile::parse(&after);
let incrementally_reparsed: Parse<SourceFile> = { let incrementally_reparsed: Parse<SourceFile> = {

View file

@ -37,11 +37,10 @@ impl Indel {
Indel { delete: range, insert: replace_with } 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 start: usize = self.delete.start().into();
let end: usize = self.delete.end().into(); let end: usize = self.delete.end().into();
text.replace_range(start..end, &self.insert); text.replace_range(start..end, &self.insert);
text
} }
} }
@ -76,8 +75,17 @@ impl TextEdit {
&self.indels &self.indels
} }
pub fn apply(&self, text: &str) -> String { pub fn apply(&self, text: &mut String) {
let mut total_len = TextSize::of(text); 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() { for indel in self.indels.iter() {
total_len += TextSize::of(&indel.insert); total_len += TextSize::of(&indel.insert);
total_len -= indel.delete.end() - indel.delete.start(); total_len -= indel.delete.end() - indel.delete.start();
@ -95,7 +103,10 @@ impl TextEdit {
} }
buf.push_str(&text[prev..text.len()]); buf.push_str(&text[prev..text.len()]);
assert_eq!(TextSize::of(&buf), total_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<TextSize> { pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {