]> git.lizzy.rs Git - rust.git/commitdiff
Rename AtomTextEdit -> Indel
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 5 May 2020 21:15:49 +0000 (23:15 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 5 May 2020 21:15:49 +0000 (23:15 +0200)
crates/ra_assists/src/assist_ctx.rs
crates/ra_ide/src/completion/completion_context.rs
crates/ra_ide/src/completion/completion_item.rs
crates/ra_ide_db/src/line_index_utils.rs
crates/ra_syntax/src/fuzz.rs
crates/ra_syntax/src/lib.rs
crates/ra_syntax/src/parsing/reparsing.rs
crates/ra_text_edit/src/lib.rs
crates/ra_text_edit/src/text_edit.rs [deleted file]
crates/rust-analyzer/src/conv.rs
xtask/tests/tidy-tests/main.rs

index 89547ce035bc54960b2a76b2c5d611ee839a89e0..83dd270c6cec7f2d0e6113820054aeef01a24a8e 100644 (file)
@@ -4,14 +4,13 @@
 use ra_fmt::{leading_indent, reindent};
 use ra_ide_db::RootDatabase;
 use ra_syntax::{
-    algo::{self, find_covering_element, find_node_at_offset},
+    algo::{self, find_covering_element, find_node_at_offset, SyntaxRewriter},
     AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
     TokenAtOffset,
 };
 use ra_text_edit::TextEditBuilder;
 
 use crate::{AssistAction, AssistFile, AssistId, AssistLabel, GroupLabel, ResolvedAssist};
-use algo::SyntaxRewriter;
 
 #[derive(Clone, Debug)]
 pub(crate) struct Assist(pub(crate) Vec<AssistInfo>);
@@ -42,7 +41,6 @@ pub(crate) fn into_resolved(self) -> Option<ResolvedAssist> {
     }
 }
 
-
 /// `AssistCtx` allows to apply an assist or check if it could be applied.
 ///
 /// Assists use a somewhat over-engineered approach, given the current needs. The
index dd87bd119e1973317e53ff2d57046767a544c2a1..b6b9627deab555269a6f89a3ab5f487ae910e11d 100644 (file)
@@ -9,7 +9,7 @@
     SyntaxKind::*,
     SyntaxNode, SyntaxToken, TextRange, TextSize,
 };
-use ra_text_edit::AtomTextEdit;
+use ra_text_edit::Indel;
 
 use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
 
@@ -76,7 +76,7 @@ pub(super) fn new(
         // actual completion.
         let file_with_fake_ident = {
             let parse = db.parse(position.file_id);
-            let edit = AtomTextEdit::insert(position.offset, "intellijRulezz".to_string());
+            let edit = Indel::insert(position.offset, "intellijRulezz".to_string());
             parse.reparse(&edit).tree()
         };
         let fake_ident_token =
index 5936fb8f7c23d4d81e5388e7f32d2ae35a0abda4..383b23ac44e91ab63ea783836d296808c11c7b10 100644 (file)
@@ -62,8 +62,8 @@ impl fmt::Debug for CompletionItem {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut s = f.debug_struct("CompletionItem");
         s.field("label", &self.label()).field("source_range", &self.source_range());
-        if self.text_edit().as_atoms().len() == 1 {
-            let atom = &self.text_edit().as_atoms()[0];
+        if self.text_edit().as_indels().len() == 1 {
+            let atom = &self.text_edit().as_indels()[0];
             s.field("delete", &atom.delete);
             s.field("insert", &atom.insert);
         } else {
index 039a12c0d84823005e16b6246e176ce4aae6a9ab..7fa6fc448e0e88c441c1493a5c4d152ffad6feb0 100644 (file)
@@ -10,7 +10,7 @@
 use std::convert::TryInto;
 
 use ra_syntax::{TextRange, TextSize};
-use ra_text_edit::{AtomTextEdit, TextEdit};
+use ra_text_edit::{Indel, TextEdit};
 
 use crate::line_index::{LineCol, LineIndex, Utf16Char};
 
@@ -182,14 +182,14 @@ struct TranslatedEdit<'a> {
 }
 
 struct Edits<'a> {
-    edits: &'a [AtomTextEdit],
+    edits: &'a [Indel],
     current: Option<TranslatedEdit<'a>>,
     acc_diff: i64,
 }
 
 impl<'a> Edits<'a> {
     fn from_text_edit(text_edit: &'a TextEdit) -> Edits<'a> {
-        let mut x = Edits { edits: text_edit.as_atoms(), current: None, acc_diff: 0 };
+        let mut x = Edits { edits: text_edit.as_indels(), current: None, acc_diff: 0 };
         x.advance_edit();
         x
     }
index 10fbe31768cbda7677daafe2e9e6fc5851da20c7..39f9b12ab20b916e1760129ce5940f5e6665537b 100644 (file)
@@ -5,7 +5,7 @@
     str::{self, FromStr},
 };
 
-use ra_text_edit::AtomTextEdit;
+use ra_text_edit::Indel;
 
 use crate::{validation, AstNode, SourceFile, TextRange};
 
@@ -22,7 +22,7 @@ pub fn check_parser(text: &str) {
 #[derive(Debug, Clone)]
 pub struct CheckReparse {
     text: String,
-    edit: AtomTextEdit,
+    edit: Indel,
     edited_text: String,
 }
 
@@ -43,7 +43,7 @@ pub fn from_data(data: &[u8]) -> Option<Self> {
             TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap());
         let edited_text =
             format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]);
-        let edit = AtomTextEdit { delete, insert };
+        let edit = Indel { delete, insert };
         Some(CheckReparse { text, edit, edited_text })
     }
 
index d0234cadaf4e5554fce34af29346c8bcb19d207d..1a7348dacdc5a5b955182745c3e71f54998ed639 100644 (file)
@@ -39,7 +39,7 @@ macro_rules! eprintln {
 
 use std::{marker::PhantomData, sync::Arc};
 
-use ra_text_edit::AtomTextEdit;
+use ra_text_edit::Indel;
 use stdx::format_to;
 
 use crate::syntax_node::GreenNode;
@@ -126,13 +126,13 @@ pub fn debug_dump(&self) -> String {
         buf
     }
 
-    pub fn reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> {
-        self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
+    pub fn reparse(&self, indel: &Indel) -> Parse<SourceFile> {
+        self.incremental_reparse(indel).unwrap_or_else(|| self.full_reparse(indel))
     }
 
-    fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse<SourceFile>> {
+    fn incremental_reparse(&self, indel: &Indel) -> Option<Parse<SourceFile>> {
         // FIXME: validation errors are not handled here
-        parsing::incremental_reparse(self.tree().syntax(), edit, self.errors.to_vec()).map(
+        parsing::incremental_reparse(self.tree().syntax(), indel, self.errors.to_vec()).map(
             |(green_node, errors, _reparsed_range)| Parse {
                 green: green_node,
                 errors: Arc::new(errors),
@@ -141,8 +141,8 @@ fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse<SourceFile>>
         )
     }
 
-    fn full_reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> {
-        let text = edit.apply(self.tree().syntax().text().to_string());
+    fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> {
+        let text = indel.apply(self.tree().syntax().text().to_string());
         SourceFile::parse(&text)
     }
 }
index ffff0a7b2026a42a5c17492f49a8e2a10e99b5ee..6257e3f33888791c2001f398ec3353505eea0785 100644 (file)
@@ -7,7 +7,7 @@
 //!     and try to parse only this block.
 
 use ra_parser::Reparser;
-use ra_text_edit::AtomTextEdit;
+use ra_text_edit::Indel;
 
 use crate::{
     algo,
@@ -24,7 +24,7 @@
 
 pub(crate) fn incremental_reparse(
     node: &SyntaxNode,
-    edit: &AtomTextEdit,
+    edit: &Indel,
     errors: Vec<SyntaxError>,
 ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
     if let Some((green, new_errors, old_range)) = reparse_token(node, &edit) {
@@ -39,7 +39,7 @@ pub(crate) fn incremental_reparse(
 
 fn reparse_token<'node>(
     root: &'node SyntaxNode,
-    edit: &AtomTextEdit,
+    edit: &Indel,
 ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
     let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone();
     let prev_token_kind = prev_token.kind();
@@ -88,7 +88,7 @@ fn reparse_token<'node>(
 
 fn reparse_block<'node>(
     root: &'node SyntaxNode,
-    edit: &AtomTextEdit,
+    edit: &Indel,
 ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
     let (node, reparser) = find_reparsable_node(root, edit.delete)?;
     let text = get_text_after_edit(node.clone().into(), edit);
@@ -108,9 +108,9 @@ fn reparse_block<'node>(
     Some((node.replace_with(green), new_parser_errors, node.text_range()))
 }
 
-fn get_text_after_edit(element: SyntaxElement, edit: &AtomTextEdit) -> String {
+fn get_text_after_edit(element: SyntaxElement, edit: &Indel) -> String {
     let edit =
-        AtomTextEdit::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 {
         NodeOrToken::Token(token) => token.text().to_string(),
@@ -167,7 +167,7 @@ fn merge_errors(
     old_errors: Vec<SyntaxError>,
     new_errors: Vec<SyntaxError>,
     range_before_reparse: TextRange,
-    edit: &AtomTextEdit,
+    edit: &Indel,
 ) -> Vec<SyntaxError> {
     let mut res = Vec::new();
 
@@ -198,7 +198,7 @@ mod tests {
 
     fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
         let (range, before) = extract_range(before);
-        let edit = AtomTextEdit::replace(range, replace_with.to_owned());
+        let edit = Indel::replace(range, replace_with.to_owned());
         let after = edit.apply(before.clone());
 
         let fully_reparsed = SourceFile::parse(&after);
index e656260c73d587eeb4bf07108cceb05c9089f699..c41bf324b6a7bccf16e8abbced65745635594e3a 100644 (file)
@@ -1,30 +1,40 @@
-//! FIXME: write short doc here
-
-mod text_edit;
+//! Representation of a `TextEdit`.
+//!
+//! `rust-analyzer` never mutates text itself and only sends diffs to clients,
+//! so `TextEdit` is the ultimate representation of the work done by
+//! rust-analyzer.
 
 use text_size::{TextRange, TextSize};
 
-pub use crate::text_edit::{TextEdit, TextEditBuilder};
-
-/// Must not overlap with other `AtomTextEdit`s
+/// `InsertDelete` -- a single "atomic" change to text
+///
+/// Must not overlap with other `InDel`s
 #[derive(Debug, Clone)]
-pub struct AtomTextEdit {
+pub struct Indel {
+    pub insert: String,
     /// Refers to offsets in the original text
     pub delete: TextRange,
-    pub insert: String,
 }
 
-impl AtomTextEdit {
-    pub fn replace(range: TextRange, replace_with: String) -> AtomTextEdit {
-        AtomTextEdit { delete: range, insert: replace_with }
-    }
+#[derive(Debug, Clone)]
+pub struct TextEdit {
+    indels: Vec<Indel>,
+}
 
-    pub fn delete(range: TextRange) -> AtomTextEdit {
-        AtomTextEdit::replace(range, String::new())
-    }
+#[derive(Debug, Default)]
+pub struct TextEditBuilder {
+    indels: Vec<Indel>,
+}
 
-    pub fn insert(offset: TextSize, text: String) -> AtomTextEdit {
-        AtomTextEdit::replace(TextRange::empty(offset), text)
+impl Indel {
+    pub fn insert(offset: TextSize, text: String) -> Indel {
+        Indel::replace(TextRange::empty(offset), text)
+    }
+    pub fn delete(range: TextRange) -> Indel {
+        Indel::replace(range, String::new())
+    }
+    pub fn replace(range: TextRange, replace_with: String) -> Indel {
+        Indel { delete: range, insert: replace_with }
     }
 
     pub fn apply(&self, mut text: String) -> String {
@@ -34,3 +44,90 @@ pub fn apply(&self, mut text: String) -> String {
         text
     }
 }
+
+impl TextEdit {
+    pub fn insert(offset: TextSize, text: String) -> TextEdit {
+        let mut builder = TextEditBuilder::default();
+        builder.insert(offset, text);
+        builder.finish()
+    }
+
+    pub fn delete(range: TextRange) -> TextEdit {
+        let mut builder = TextEditBuilder::default();
+        builder.delete(range);
+        builder.finish()
+    }
+
+    pub fn replace(range: TextRange, replace_with: String) -> TextEdit {
+        let mut builder = TextEditBuilder::default();
+        builder.replace(range, replace_with);
+        builder.finish()
+    }
+
+    pub(crate) fn from_indels(mut indels: Vec<Indel>) -> TextEdit {
+        indels.sort_by_key(|a| (a.delete.start(), a.delete.end()));
+        for (a1, a2) in indels.iter().zip(indels.iter().skip(1)) {
+            assert!(a1.delete.end() <= a2.delete.start())
+        }
+        TextEdit { indels }
+    }
+
+    pub fn as_indels(&self) -> &[Indel] {
+        &self.indels
+    }
+
+    pub fn apply(&self, text: &str) -> String {
+        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();
+        }
+        let mut buf = String::with_capacity(total_len.into());
+        let mut prev = 0;
+        for indel in self.indels.iter() {
+            let start: usize = indel.delete.start().into();
+            let end: usize = indel.delete.end().into();
+            if start > prev {
+                buf.push_str(&text[prev..start]);
+            }
+            buf.push_str(&indel.insert);
+            prev = end;
+        }
+        buf.push_str(&text[prev..text.len()]);
+        assert_eq!(TextSize::of(&buf), total_len);
+        buf
+    }
+
+    pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
+        let mut res = offset;
+        for indel in self.indels.iter() {
+            if indel.delete.start() >= offset {
+                break;
+            }
+            if offset < indel.delete.end() {
+                return None;
+            }
+            res += TextSize::of(&indel.insert);
+            res -= indel.delete.len();
+        }
+        Some(res)
+    }
+}
+
+impl TextEditBuilder {
+    pub fn replace(&mut self, range: TextRange, replace_with: String) {
+        self.indels.push(Indel::replace(range, replace_with))
+    }
+    pub fn delete(&mut self, range: TextRange) {
+        self.indels.push(Indel::delete(range))
+    }
+    pub fn insert(&mut self, offset: TextSize, text: String) {
+        self.indels.push(Indel::insert(offset, text))
+    }
+    pub fn finish(self) -> TextEdit {
+        TextEdit::from_indels(self.indels)
+    }
+    pub fn invalidates_offset(&self, offset: TextSize) -> bool {
+        self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset))
+    }
+}
diff --git a/crates/ra_text_edit/src/text_edit.rs b/crates/ra_text_edit/src/text_edit.rs
deleted file mode 100644 (file)
index eabab4b..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-//! FIXME: write short doc here
-
-use crate::AtomTextEdit;
-
-use text_size::{TextRange, TextSize};
-
-#[derive(Debug, Clone)]
-pub struct TextEdit {
-    atoms: Vec<AtomTextEdit>,
-}
-
-#[derive(Debug, Default)]
-pub struct TextEditBuilder {
-    atoms: Vec<AtomTextEdit>,
-}
-
-impl TextEditBuilder {
-    pub fn replace(&mut self, range: TextRange, replace_with: String) {
-        self.atoms.push(AtomTextEdit::replace(range, replace_with))
-    }
-    pub fn delete(&mut self, range: TextRange) {
-        self.atoms.push(AtomTextEdit::delete(range))
-    }
-    pub fn insert(&mut self, offset: TextSize, text: String) {
-        self.atoms.push(AtomTextEdit::insert(offset, text))
-    }
-    pub fn finish(self) -> TextEdit {
-        TextEdit::from_atoms(self.atoms)
-    }
-    pub fn invalidates_offset(&self, offset: TextSize) -> bool {
-        self.atoms.iter().any(|atom| atom.delete.contains_inclusive(offset))
-    }
-}
-
-impl TextEdit {
-    pub fn insert(offset: TextSize, text: String) -> TextEdit {
-        let mut builder = TextEditBuilder::default();
-        builder.insert(offset, text);
-        builder.finish()
-    }
-
-    pub fn delete(range: TextRange) -> TextEdit {
-        let mut builder = TextEditBuilder::default();
-        builder.delete(range);
-        builder.finish()
-    }
-
-    pub fn replace(range: TextRange, replace_with: String) -> TextEdit {
-        let mut builder = TextEditBuilder::default();
-        builder.replace(range, replace_with);
-        builder.finish()
-    }
-
-    pub(crate) fn from_atoms(mut atoms: Vec<AtomTextEdit>) -> TextEdit {
-        atoms.sort_by_key(|a| (a.delete.start(), a.delete.end()));
-        for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) {
-            assert!(a1.delete.end() <= a2.delete.start())
-        }
-        TextEdit { atoms }
-    }
-
-    pub fn as_atoms(&self) -> &[AtomTextEdit] {
-        &self.atoms
-    }
-
-    pub fn apply(&self, text: &str) -> String {
-        let mut total_len = TextSize::of(text);
-        for atom in self.atoms.iter() {
-            total_len += TextSize::of(&atom.insert);
-            total_len -= atom.delete.end() - atom.delete.start();
-        }
-        let mut buf = String::with_capacity(total_len.into());
-        let mut prev = 0;
-        for atom in self.atoms.iter() {
-            let start: usize = atom.delete.start().into();
-            let end: usize = atom.delete.end().into();
-            if start > prev {
-                buf.push_str(&text[prev..start]);
-            }
-            buf.push_str(&atom.insert);
-            prev = end;
-        }
-        buf.push_str(&text[prev..text.len()]);
-        assert_eq!(TextSize::of(&buf), total_len);
-        buf
-    }
-
-    pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
-        let mut res = offset;
-        for atom in self.atoms.iter() {
-            if atom.delete.start() >= offset {
-                break;
-            }
-            if offset < atom.delete.end() {
-                return None;
-            }
-            res += TextSize::of(&atom.insert);
-            res -= atom.delete.len();
-        }
-        Some(res)
-    }
-}
index 7be5ebcdb5a0d13599cc5a8d628c48186cc46936..f64c90b5b17ad2bbbccdbdd92f5e44f4dbacc35d 100644 (file)
@@ -15,7 +15,7 @@
     ReferenceAccess, Severity, SourceChange, SourceFileEdit,
 };
 use ra_syntax::{SyntaxKind, TextRange, TextSize};
-use ra_text_edit::{AtomTextEdit, TextEdit};
+use ra_text_edit::{Indel, TextEdit};
 use ra_vfs::LineEndings;
 
 use crate::{
@@ -124,23 +124,22 @@ fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> ::lsp_types::CompletionIte
         let mut text_edit = None;
         // LSP does not allow arbitrary edits in completion, so we have to do a
         // non-trivial mapping here.
-        for atom_edit in self.text_edit().as_atoms() {
-            if atom_edit.delete.contains_range(self.source_range()) {
-                text_edit = Some(if atom_edit.delete == self.source_range() {
-                    atom_edit.conv_with((ctx.0, ctx.1))
+        for indel in self.text_edit().as_indels() {
+            if indel.delete.contains_range(self.source_range()) {
+                text_edit = Some(if indel.delete == self.source_range() {
+                    indel.conv_with((ctx.0, ctx.1))
                 } else {
-                    assert!(self.source_range().end() == atom_edit.delete.end());
-                    let range1 =
-                        TextRange::new(atom_edit.delete.start(), self.source_range().start());
+                    assert!(self.source_range().end() == indel.delete.end());
+                    let range1 = TextRange::new(indel.delete.start(), self.source_range().start());
                     let range2 = self.source_range();
-                    let edit1 = AtomTextEdit::replace(range1, String::new());
-                    let edit2 = AtomTextEdit::replace(range2, atom_edit.insert.clone());
+                    let edit1 = Indel::replace(range1, String::new());
+                    let edit2 = Indel::replace(range2, indel.insert.clone());
                     additional_text_edits.push(edit1.conv_with((ctx.0, ctx.1)));
                     edit2.conv_with((ctx.0, ctx.1))
                 })
             } else {
-                assert!(self.source_range().intersect(atom_edit.delete).is_none());
-                additional_text_edits.push(atom_edit.conv_with((ctx.0, ctx.1)));
+                assert!(self.source_range().intersect(indel.delete).is_none());
+                additional_text_edits.push(indel.conv_with((ctx.0, ctx.1)));
             }
         }
         let text_edit = text_edit.unwrap();
@@ -257,11 +256,11 @@ impl ConvWith<(&LineIndex, LineEndings)> for TextEdit {
     type Output = Vec<lsp_types::TextEdit>;
 
     fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> Vec<lsp_types::TextEdit> {
-        self.as_atoms().iter().map_conv_with(ctx).collect()
+        self.as_indels().iter().map_conv_with(ctx).collect()
     }
 }
 
-impl ConvWith<(&LineIndex, LineEndings)> for &AtomTextEdit {
+impl ConvWith<(&LineIndex, LineEndings)> for &Indel {
     type Output = lsp_types::TextEdit;
 
     fn conv_with(
@@ -522,7 +521,7 @@ fn try_conv_with(self, world: &WorldSnapshot) -> Result<TextDocumentEdit> {
         let line_index = world.analysis().file_line_index(self.file_id)?;
         let line_endings = world.file_line_endings(self.file_id);
         let edits =
-            self.edit.as_atoms().iter().map_conv_with((&line_index, line_endings)).collect();
+            self.edit.as_indels().iter().map_conv_with((&line_index, line_endings)).collect();
         Ok(TextDocumentEdit { text_document, edits })
     }
 }
index ead642acc6db0a71fc59eac730b8d69d15ba1b39..3213c4dfa3c3833a7c80bbcb8ac456cd9e41bf20 100644 (file)
@@ -115,7 +115,6 @@ fn finish(self) {
             "ra_prof",
             "ra_project_model",
             "ra_syntax",
-            "ra_text_edit",
             "ra_tt",
             "ra_hir_ty",
         ];