]> git.lizzy.rs Git - rust.git/commitdiff
Phase out SourceFileEdits in favour of a plain HashMap
authorLukas Wirth <lukastw97@gmail.com>
Thu, 14 Jan 2021 21:43:36 +0000 (22:43 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Thu, 14 Jan 2021 21:43:36 +0000 (22:43 +0100)
15 files changed:
crates/assists/src/assist_context.rs
crates/assists/src/tests.rs
crates/ide/src/diagnostics.rs
crates/ide/src/diagnostics/field_shorthand.rs
crates/ide/src/diagnostics/fixes.rs
crates/ide/src/lib.rs
crates/ide/src/references/rename.rs
crates/ide/src/typing.rs
crates/ide_db/src/source_change.rs
crates/rust-analyzer/src/cli/ssr.rs
crates/rust-analyzer/src/handlers.rs
crates/rust-analyzer/src/to_proto.rs
crates/ssr/src/lib.rs
crates/ssr/src/matching.rs
crates/ssr/src/tests.rs

index de4b32573a57063a16e0afd562a2ac28093d3634..321fe77f37b3a379d3ce1b9d1cd69e42733bd5ad 100644 (file)
@@ -10,7 +10,7 @@
 };
 use ide_db::{
     label::Label,
-    source_change::{FileSystemEdit, SourceChange, SourceFileEdits},
+    source_change::{FileSystemEdit, SourceChange},
     RootDatabase,
 };
 use syntax::{
@@ -180,20 +180,12 @@ fn is_allowed(&self, id: &AssistId) -> bool {
 pub(crate) struct AssistBuilder {
     edit: TextEditBuilder,
     file_id: FileId,
-    is_snippet: bool,
-    source_file_edits: SourceFileEdits,
-    file_system_edits: Vec<FileSystemEdit>,
+    source_change: SourceChange,
 }
 
 impl AssistBuilder {
     pub(crate) fn new(file_id: FileId) -> AssistBuilder {
-        AssistBuilder {
-            edit: TextEdit::builder(),
-            file_id,
-            is_snippet: false,
-            source_file_edits: SourceFileEdits::default(),
-            file_system_edits: Vec::default(),
-        }
+        AssistBuilder { edit: TextEdit::builder(), file_id, source_change: SourceChange::default() }
     }
 
     pub(crate) fn edit_file(&mut self, file_id: FileId) {
@@ -204,7 +196,7 @@ pub(crate) fn edit_file(&mut self, file_id: FileId) {
     fn commit(&mut self) {
         let edit = mem::take(&mut self.edit).finish();
         if !edit.is_empty() {
-            self.source_file_edits.insert(self.file_id, edit);
+            self.source_change.insert_source_edit(self.file_id, edit);
         }
     }
 
@@ -223,7 +215,7 @@ pub(crate) fn insert_snippet(
         offset: TextSize,
         snippet: impl Into<String>,
     ) {
-        self.is_snippet = true;
+        self.source_change.is_snippet = true;
         self.insert(offset, snippet);
     }
     /// Replaces specified `range` of text with a given string.
@@ -237,7 +229,7 @@ pub(crate) fn replace_snippet(
         range: TextRange,
         snippet: impl Into<String>,
     ) {
-        self.is_snippet = true;
+        self.source_change.is_snippet = true;
         self.replace(range, snippet);
     }
     pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
@@ -252,15 +244,11 @@ pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) {
     pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
         let file_system_edit =
             FileSystemEdit::CreateFile { dst: dst.clone(), initial_contents: content.into() };
-        self.file_system_edits.push(file_system_edit);
+        self.source_change.push_file_system_edit(file_system_edit);
     }
 
     fn finish(mut self) -> SourceChange {
         self.commit();
-        SourceChange {
-            source_file_edits: mem::take(&mut self.source_file_edits),
-            file_system_edits: mem::take(&mut self.file_system_edits),
-            is_snippet: self.is_snippet,
-        }
+        mem::take(&mut self.source_change)
     }
 }
index d13d6ad31ee5e7ac242a72f64c59f94def414b7f..71431b4065c7b1d32e3238c156766aea73c340fb 100644 (file)
@@ -80,7 +80,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
     let actual = {
         let source_change = assist.source_change.unwrap();
         let mut actual = before;
-        if let Some(source_file_edit) = source_change.source_file_edits.edits.get(&file_id) {
+        if let Some(source_file_edit) = source_change.get_source_edit(file_id) {
             source_file_edit.apply(&mut actual);
         }
         actual
@@ -120,7 +120,7 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
                 && source_change.file_system_edits.len() == 0;
 
             let mut buf = String::new();
-            for (file_id, edit) in source_change.source_file_edits.edits {
+            for (file_id, edit) in source_change.source_file_edits {
                 let mut text = db.file_text(file_id).as_ref().to_owned();
                 edit.apply(&mut text);
                 if !skip_header {
@@ -132,18 +132,15 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
                 buf.push_str(&text);
             }
 
-            for file_system_edit in source_change.file_system_edits.clone() {
-                match file_system_edit {
-                    FileSystemEdit::CreateFile { dst, initial_contents } => {
-                        let sr = db.file_source_root(dst.anchor);
-                        let sr = db.source_root(sr);
-                        let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
-                        base.pop();
-                        let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
-                        format_to!(buf, "//- {}\n", created_file_path);
-                        buf.push_str(&initial_contents);
-                    }
-                    _ => (),
+            for file_system_edit in source_change.file_system_edits {
+                if let FileSystemEdit::CreateFile { dst, initial_contents } = file_system_edit {
+                    let sr = db.file_source_root(dst.anchor);
+                    let sr = db.source_root(sr);
+                    let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
+                    base.pop();
+                    let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
+                    format_to!(buf, "//- {}\n", created_file_path);
+                    buf.push_str(&initial_contents);
                 }
             }
 
index a43188fb0a4db469f698164d1a95fc6107ba2cd1..2e5395b518cf65540557d4f08f71431543d8392b 100644 (file)
@@ -13,7 +13,7 @@
     diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder},
     Semantics,
 };
-use ide_db::{base_db::SourceDatabase, source_change::SourceFileEdits, RootDatabase};
+use ide_db::{base_db::SourceDatabase, RootDatabase};
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
 use syntax::{
@@ -219,7 +219,7 @@ fn check_unnecessary_braces_in_use_statement(
             Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string())
                 .with_fix(Some(Fix::new(
                     "Remove unnecessary braces",
-                    SourceFileEdits::from_text_edit(file_id, edit).into(),
+                    SourceChange::from_text_edit(file_id, edit),
                     use_range,
                 ))),
         );
@@ -264,10 +264,10 @@ pub(crate) fn check_fix(ra_fixture_before: &str, ra_fixture_after: &str) {
             .unwrap();
         let fix = diagnostic.fix.unwrap();
         let actual = {
-            let file_id = *fix.source_change.source_file_edits.edits.keys().next().unwrap();
+            let file_id = *fix.source_change.source_file_edits.keys().next().unwrap();
             let mut actual = analysis.file_text(file_id).unwrap().to_string();
 
-            for edit in fix.source_change.source_file_edits.edits.values() {
+            for edit in fix.source_change.source_file_edits.values() {
                 edit.apply(&mut actual);
             }
             actual
@@ -613,9 +613,7 @@ fn test_unresolved_module_diagnostic() {
                             Fix {
                                 label: "Create module",
                                 source_change: SourceChange {
-                                    source_file_edits: SourceFileEdits {
-                                        edits: {},
-                                    },
+                                    source_file_edits: {},
                                     file_system_edits: [
                                         CreateFile {
                                             dst: AnchoredPathBuf {
index f4ec51b6442520fdea761e1a680b037a8f9b28c4..5c89e21707e8a85ca651698bac568e89105880c8 100644 (file)
@@ -1,7 +1,7 @@
 //! Suggests shortening `Foo { field: field }` to `Foo { field }` in both
 //! expressions and patterns.
 
-use ide_db::{base_db::FileId, source_change::SourceFileEdits};
+use ide_db::{base_db::FileId, source_change::SourceChange};
 use syntax::{ast, match_ast, AstNode, SyntaxNode};
 use text_edit::TextEdit;
 
@@ -49,7 +49,7 @@ fn check_expr_field_shorthand(
             Diagnostic::hint(field_range, "Shorthand struct initialization".to_string()).with_fix(
                 Some(Fix::new(
                     "Use struct shorthand initialization",
-                    SourceFileEdits::from_text_edit(file_id, edit).into(),
+                    SourceChange::from_text_edit(file_id, edit),
                     field_range,
                 )),
             ),
@@ -88,7 +88,7 @@ fn check_pat_field_shorthand(
         acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fix(
             Some(Fix::new(
                 "Use struct field shorthand",
-                SourceFileEdits::from_text_edit(file_id, edit).into(),
+                SourceChange::from_text_edit(file_id, edit),
                 field_range,
             )),
         ));
index b04964ccd535f03c3a1ce54a17b5ea50671913c2..e4335119bc9e22bb4f0324036882bfcd876d2db2 100644 (file)
@@ -10,7 +10,7 @@
 };
 use ide_db::{
     base_db::{AnchoredPathBuf, FileId},
-    source_change::{FileSystemEdit, SourceFileEdits},
+    source_change::{FileSystemEdit, SourceChange},
     RootDatabase,
 };
 use syntax::{
@@ -88,7 +88,7 @@ fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> {
         };
         Some(Fix::new(
             "Fill struct fields",
-            SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into(),
+            SourceChange::from_text_edit(self.file.original_file(sema.db), edit),
             sema.original_range(&field_list_parent.syntax()).range,
         ))
     }
@@ -101,8 +101,7 @@ fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> {
         let tail_expr_range = tail_expr.syntax().text_range();
         let replacement = format!("{}({})", self.required, tail_expr.syntax());
         let edit = TextEdit::replace(tail_expr_range, replacement);
-        let source_change =
-            SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into();
+        let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit);
         let name = if self.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" };
         Some(Fix::new(name, source_change, tail_expr_range))
     }
@@ -122,8 +121,7 @@ fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> {
             .text_range();
 
         let edit = TextEdit::delete(semicolon);
-        let source_change =
-            SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into();
+        let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit);
 
         Some(Fix::new("Remove this semicolon", source_change, semicolon))
     }
@@ -204,15 +202,11 @@ fn missing_record_expr_field_fix(
         new_field = format!(",{}", new_field);
     }
 
-    let source_change = SourceFileEdits::from_text_edit(
+    let source_change = SourceChange::from_text_edit(
         def_file_id,
         TextEdit::insert(last_field_syntax.text_range().end(), new_field),
     );
-    return Some(Fix::new(
-        "Create field",
-        source_change.into(),
-        record_expr_field.syntax().text_range(),
-    ));
+    return Some(Fix::new("Create field", source_change, record_expr_field.syntax().text_range()));
 
     fn record_field_list(field_def_list: ast::FieldList) -> Option<ast::RecordFieldList> {
         match field_def_list {
index 110920e58df203bdf19f222743a34e5dacb75c7d..afd552008db1431fb829e635304ba5bd53d42022 100644 (file)
@@ -98,7 +98,7 @@ macro_rules! eprintln {
     label::Label,
     line_index::{LineCol, LineIndex},
     search::SearchScope,
-    source_change::{FileSystemEdit, SourceChange, SourceFileEdits},
+    source_change::{FileSystemEdit, SourceChange},
     symbol_index::Query,
     RootDatabase,
 };
index cd9c7c7e5720498f6797582d12575291635604af..039efb26fdf22c888a1791bdab170f565e065cc0 100644 (file)
@@ -21,7 +21,7 @@
 
 use crate::{
     FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange,
-    SourceFileEdits, TextRange, TextSize,
+    TextRange, TextSize,
 };
 
 type RenameResult<T> = Result<T, RenameError>;
@@ -249,8 +249,8 @@ fn rename_mod(
     if IdentifierKind::Ident != check_identifier(new_name)? {
         bail!("Invalid name `{0}`: cannot rename module to {0}", new_name);
     }
-    let mut source_file_edits = SourceFileEdits::default();
-    let mut file_system_edits = Vec::new();
+
+    let mut source_change = SourceChange::default();
 
     let src = module.definition_source(sema.db);
     let file_id = src.file_id.original_file(sema.db);
@@ -264,7 +264,7 @@ fn rename_mod(
             };
             let dst = AnchoredPathBuf { anchor: file_id, path };
             let move_file = FileSystemEdit::MoveFile { src: file_id, dst };
-            file_system_edits.push(move_file);
+            source_change.push_file_system_edit(move_file);
         }
         ModuleSource::Module(..) => {}
     }
@@ -272,17 +272,19 @@ fn rename_mod(
     if let Some(src) = module.declaration_source(sema.db) {
         let file_id = src.file_id.original_file(sema.db);
         let name = src.value.name().unwrap();
-        source_file_edits
-            .insert(file_id, TextEdit::replace(name.syntax().text_range(), new_name.into()));
+        source_change.insert_source_edit(
+            file_id,
+            TextEdit::replace(name.syntax().text_range(), new_name.into()),
+        );
     }
 
     let RangeInfo { range, info: refs } = find_all_refs(sema, position)?;
     let ref_edits = refs.references().iter().map(|(&file_id, references)| {
         source_edit_from_references(sema, file_id, references, new_name)
     });
-    source_file_edits.extend(ref_edits);
+    source_change.extend(ref_edits);
 
-    Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits)))
+    Ok(RangeInfo::new(range, source_change))
 }
 
 fn rename_to_self(
@@ -331,13 +333,16 @@ fn rename_to_self(
 
     let RangeInfo { range, info: refs } = find_all_refs(sema, position)?;
 
-    let mut edits = SourceFileEdits::default();
-    edits.extend(refs.references().iter().map(|(&file_id, references)| {
+    let mut source_change = SourceChange::default();
+    source_change.extend(refs.references().iter().map(|(&file_id, references)| {
         source_edit_from_references(sema, file_id, references, "self")
     }));
-    edits.insert(position.file_id, TextEdit::replace(param_range, String::from(self_param)));
+    source_change.insert_source_edit(
+        position.file_id,
+        TextEdit::replace(param_range, String::from(self_param)),
+    );
 
-    Ok(RangeInfo::new(range, edits.into()))
+    Ok(RangeInfo::new(range, source_change))
 }
 
 fn text_edit_from_self_param(
@@ -391,7 +396,7 @@ fn rename_self_to_param(
         .ok_or_else(|| format_err!("No surrounding method declaration found"))?;
     let search_range = fn_def.syntax().text_range();
 
-    let mut edits = SourceFileEdits::default();
+    let mut source_change = SourceChange::default();
 
     for (idx, _) in text.match_indices("self") {
         let offset: TextSize = idx.try_into().unwrap();
@@ -405,18 +410,18 @@ fn rename_self_to_param(
             } else {
                 TextEdit::replace(usage.text_range(), String::from(new_name))
             };
-            edits.insert(position.file_id, edit);
+            source_change.insert_source_edit(position.file_id, edit);
         }
     }
 
-    if edits.len() > 1 && ident_kind == IdentifierKind::Underscore {
+    if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore {
         bail!("Cannot rename reference to `_` as it is being referenced multiple times");
     }
 
     let range = ast::SelfParam::cast(self_token.parent())
         .map_or(self_token.text_range(), |p| p.syntax().text_range());
 
-    Ok(RangeInfo::new(range, edits.into()))
+    Ok(RangeInfo::new(range, source_change))
 }
 
 fn rename_reference(
@@ -453,12 +458,12 @@ fn rename_reference(
         (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident),
     }
 
-    let mut edits = SourceFileEdits::default();
-    edits.extend(refs.into_iter().map(|(file_id, references)| {
+    let mut source_change = SourceChange::default();
+    source_change.extend(refs.into_iter().map(|(file_id, references)| {
         source_edit_from_references(sema, file_id, &references, new_name)
     }));
 
-    Ok(RangeInfo::new(range, edits.into()))
+    Ok(RangeInfo::new(range, source_change))
 }
 
 #[cfg(test)]
@@ -480,7 +485,7 @@ fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
             Ok(source_change) => {
                 let mut text_edit_builder = TextEdit::builder();
                 let mut file_id: Option<FileId> = None;
-                for edit in source_change.info.source_file_edits.edits {
+                for edit in source_change.info.source_file_edits {
                     file_id = Some(edit.0);
                     for indel in edit.1.into_iter() {
                         text_edit_builder.replace(indel.delete, indel.insert);
@@ -882,18 +887,16 @@ fn test_rename_mod() {
                 RangeInfo {
                     range: 4..7,
                     info: SourceChange {
-                        source_file_edits: SourceFileEdits {
-                            edits: {
-                                FileId(
-                                    1,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "foo2",
-                                            delete: 4..7,
-                                        },
-                                    ],
-                                },
+                        source_file_edits: {
+                            FileId(
+                                1,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "foo2",
+                                        delete: 4..7,
+                                    },
+                                ],
                             },
                         },
                         file_system_edits: [
@@ -936,28 +939,26 @@ fn main() {}
                 RangeInfo {
                     range: 11..14,
                     info: SourceChange {
-                        source_file_edits: SourceFileEdits {
-                            edits: {
-                                FileId(
-                                    0,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "quux",
-                                            delete: 8..11,
-                                        },
-                                    ],
-                                },
-                                FileId(
-                                    2,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "quux",
-                                            delete: 11..14,
-                                        },
-                                    ],
-                                },
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "quux",
+                                        delete: 8..11,
+                                    },
+                                ],
+                            },
+                            FileId(
+                                2,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "quux",
+                                        delete: 11..14,
+                                    },
+                                ],
                             },
                         },
                         file_system_edits: [
@@ -994,18 +995,16 @@ fn test_rename_mod_in_dir() {
                 RangeInfo {
                     range: 4..7,
                     info: SourceChange {
-                        source_file_edits: SourceFileEdits {
-                            edits: {
-                                FileId(
-                                    0,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "foo2",
-                                            delete: 4..7,
-                                        },
-                                    ],
-                                },
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "foo2",
+                                        delete: 4..7,
+                                    },
+                                ],
                             },
                         },
                         file_system_edits: [
@@ -1043,18 +1042,16 @@ fn test_rename_unusually_nested_mod() {
                 RangeInfo {
                     range: 16..19,
                     info: SourceChange {
-                        source_file_edits: SourceFileEdits {
-                            edits: {
-                                FileId(
-                                    0,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "bar",
-                                            delete: 16..19,
-                                        },
-                                    ],
-                                },
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "bar",
+                                        delete: 16..19,
+                                    },
+                                ],
                             },
                         },
                         file_system_edits: [
@@ -1115,28 +1112,26 @@ fn f() {
                 RangeInfo {
                     range: 8..11,
                     info: SourceChange {
-                        source_file_edits: SourceFileEdits {
-                            edits: {
-                                FileId(
-                                    0,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "foo2",
-                                            delete: 27..30,
-                                        },
-                                    ],
-                                },
-                                FileId(
-                                    1,
-                                ): TextEdit {
-                                    indels: [
-                                        Indel {
-                                            insert: "foo2",
-                                            delete: 8..11,
-                                        },
-                                    ],
-                                },
+                        source_file_edits: {
+                            FileId(
+                                0,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "foo2",
+                                        delete: 27..30,
+                                    },
+                                ],
+                            },
+                            FileId(
+                                1,
+                            ): TextEdit {
+                                indels: [
+                                    Indel {
+                                        insert: "foo2",
+                                        delete: 8..11,
+                                    },
+                                ],
                             },
                         },
                         file_system_edits: [
index b3fc326458faa84f0559ec38f0a87eeccf67b717..e3c3aebac2dc8ff6f2dd5ac1175b672fd42959f5 100644 (file)
@@ -17,7 +17,6 @@
 
 use ide_db::{
     base_db::{FilePosition, SourceDatabase},
-    source_change::SourceFileEdits,
     RootDatabase,
 };
 use syntax::{
@@ -59,7 +58,7 @@ pub(crate) fn on_char_typed(
     let file = &db.parse(position.file_id).tree();
     assert_eq!(file.syntax().text().char_at(position.offset), Some(char_typed));
     let edit = on_char_typed_inner(file, position.offset, char_typed)?;
-    Some(SourceFileEdits::from_text_edit(position.file_id, edit).into())
+    Some(SourceChange::from_text_edit(position.file_id, edit))
 }
 
 fn on_char_typed_inner(file: &SourceFile, offset: TextSize, char_typed: char) -> Option<TextEdit> {
index 516d7859a875763620c5b6f281b477d94a0fd3ae..b1f87731bfdf4389b38d3d6eb27b9f6e5288d83f 100644 (file)
 
 use base_db::{AnchoredPathBuf, FileId};
 use rustc_hash::FxHashMap;
+use stdx::assert_never;
 use text_edit::TextEdit;
 
 #[derive(Default, Debug, Clone)]
 pub struct SourceChange {
-    pub source_file_edits: SourceFileEdits,
+    pub source_file_edits: FxHashMap<FileId, TextEdit>,
     pub file_system_edits: Vec<FileSystemEdit>,
     pub is_snippet: bool,
 }
@@ -23,51 +24,50 @@ impl SourceChange {
     /// Creates a new SourceChange with the given label
     /// from the edits.
     pub fn from_edits(
-        source_file_edits: SourceFileEdits,
+        source_file_edits: FxHashMap<FileId, TextEdit>,
         file_system_edits: Vec<FileSystemEdit>,
     ) -> Self {
         SourceChange { source_file_edits, file_system_edits, is_snippet: false }
     }
-}
-
-#[derive(Default, Debug, Clone)]
-pub struct SourceFileEdits {
-    pub edits: FxHashMap<FileId, TextEdit>,
-}
 
-impl SourceFileEdits {
     pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self {
-        SourceFileEdits { edits: FxHashMap::from_iter(iter::once((file_id, edit))) }
-    }
-
-    pub fn len(&self) -> usize {
-        self.edits.len()
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.edits.is_empty()
+        SourceChange {
+            source_file_edits: FxHashMap::from_iter(iter::once((file_id, edit))),
+            ..Default::default()
+        }
     }
 
-    pub fn insert(&mut self, file_id: FileId, edit: TextEdit) {
-        match self.edits.entry(file_id) {
+    pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) {
+        match self.source_file_edits.entry(file_id) {
             Entry::Occupied(mut entry) => {
-                entry.get_mut().union(edit).expect("overlapping edits for same file");
+                assert_never!(
+                    entry.get_mut().union(edit).is_err(),
+                    "overlapping edits for same file"
+                );
             }
             Entry::Vacant(entry) => {
                 entry.insert(edit);
             }
         }
     }
+
+    pub fn push_file_system_edit(&mut self, edit: FileSystemEdit) {
+        self.file_system_edits.push(edit);
+    }
+
+    pub fn get_source_edit(&self, file_id: FileId) -> Option<&TextEdit> {
+        self.source_file_edits.get(&file_id)
+    }
 }
 
-impl Extend<(FileId, TextEdit)> for SourceFileEdits {
+impl Extend<(FileId, TextEdit)> for SourceChange {
     fn extend<T: IntoIterator<Item = (FileId, TextEdit)>>(&mut self, iter: T) {
-        iter.into_iter().for_each(|(file_id, edit)| self.insert(file_id, edit));
+        iter.into_iter().for_each(|(file_id, edit)| self.insert_source_edit(file_id, edit));
     }
 }
 
-impl From<SourceFileEdits> for SourceChange {
-    fn from(source_file_edits: SourceFileEdits) -> SourceChange {
+impl From<FxHashMap<FileId, TextEdit>> for SourceChange {
+    fn from(source_file_edits: FxHashMap<FileId, TextEdit>) -> SourceChange {
         SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false }
     }
 }
index 100331c37388cd5581aefbdb80cbf93b57c6019b..bbb550ec9a5c60730165703b5dcc3b607dab4e1c 100644 (file)
@@ -12,7 +12,7 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
         match_finder.add_rule(rule)?;
     }
     let edits = match_finder.edits();
-    for (file_id, edit) in edits.edits {
+    for (file_id, edit) in edits {
         if let Some(path) = vfs.file_path(file_id).as_path() {
             let mut contents = db.file_text(file_id).to_string();
             edit.apply(&mut contents);
index 839466e4fb2c8ff779dddafbf78d91945650569a..1a4e0dd3283d8cc6612ee1449b4ae9a4bbd10a2f 100644 (file)
@@ -266,7 +266,7 @@ pub(crate) fn handle_on_type_formatting(
     };
 
     // This should be a single-file edit
-    let (_, edit) = edit.source_file_edits.edits.into_iter().next().unwrap();
+    let (_, edit) = edit.source_file_edits.into_iter().next().unwrap();
 
     let change = to_proto::text_edit_vec(&line_index, line_endings, edit);
     Ok(Some(change))
@@ -464,12 +464,10 @@ pub(crate) fn handle_will_rename_files(
 
     // Drop file system edits since we're just renaming things on the same level
     let mut source_changes = source_changes.into_iter();
-    let mut source_file_edits =
-        source_changes.next().map_or_else(Default::default, |it| it.source_file_edits);
+    let mut source_change = source_changes.next().unwrap_or_default();
+    source_change.file_system_edits.clear();
     // no collect here because we want to merge text edits on same file ids
-    source_file_edits.extend(source_changes.map(|it| it.source_file_edits.edits).flatten());
-    let source_change = SourceChange::from_edits(source_file_edits, Vec::new());
-
+    source_change.extend(source_changes.map(|it| it.source_file_edits).flatten());
     let workspace_edit = to_proto::workspace_edit(&snap, source_change)?;
     Ok(Some(workspace_edit))
 }
index 34f510e73d3fe19a6432ae370bbb9f3802d4fe2b..dc67d19a7547ecfd9a05adf33000ca5913f9c1d0 100644 (file)
@@ -698,7 +698,7 @@ pub(crate) fn snippet_workspace_edit(
         let ops = snippet_text_document_ops(snap, op);
         document_changes.extend_from_slice(&ops);
     }
-    for (file_id, edit) in source_change.source_file_edits.edits {
+    for (file_id, edit) in source_change.source_file_edits {
         let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?;
         document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit));
     }
index d99ebefb165bac8df9990368338b4d780d73ac68..a97fc8bcacab263454fc23bfa74ce5bbc6c88c09 100644 (file)
 pub use crate::matching::Match;
 use crate::matching::MatchFailureReason;
 use hir::Semantics;
-use ide_db::{
-    base_db::{FileId, FilePosition, FileRange},
-    source_change::SourceFileEdits,
-};
+use ide_db::base_db::{FileId, FilePosition, FileRange};
 use resolving::ResolvedRule;
 use rustc_hash::FxHashMap;
 use syntax::{ast, AstNode, SyntaxNode, TextRange};
+use text_edit::TextEdit;
 
 // A structured search replace rule. Create by calling `parse` on a str.
 #[derive(Debug)]
@@ -161,7 +159,7 @@ pub fn add_rule(&mut self, rule: SsrRule) -> Result<(), SsrError> {
     }
 
     /// Finds matches for all added rules and returns edits for all found matches.
-    pub fn edits(&self) -> SourceFileEdits {
+    pub fn edits(&self) -> FxHashMap<FileId, TextEdit> {
         use ide_db::base_db::SourceDatabaseExt;
         let mut matches_by_file = FxHashMap::default();
         for m in self.matches().matches {
@@ -171,21 +169,19 @@ pub fn edits(&self) -> SourceFileEdits {
                 .matches
                 .push(m);
         }
-        SourceFileEdits {
-            edits: matches_by_file
-                .into_iter()
-                .map(|(file_id, matches)| {
-                    (
-                        file_id,
-                        replacing::matches_to_edit(
-                            &matches,
-                            &self.sema.db.file_text(file_id),
-                            &self.rules,
-                        ),
-                    )
-                })
-                .collect(),
-        }
+        matches_by_file
+            .into_iter()
+            .map(|(file_id, matches)| {
+                (
+                    file_id,
+                    replacing::matches_to_edit(
+                        &matches,
+                        &self.sema.db.file_text(file_id),
+                        &self.rules,
+                    ),
+                )
+            })
+            .collect()
     }
 
     /// Adds a search pattern. For use if you intend to only call `find_matches_in_file`. If you
index 5888bf8f82a4a25d5e832acac7cdb53223facf2a..42d313f918314984bda0c7fd2ea32ee5ac0f5057 100644 (file)
@@ -810,7 +810,7 @@ fn parse_match_replace() {
 
         let edits = match_finder.edits();
         assert_eq!(edits.len(), 1);
-        let edit = &edits.edits[&position.file_id];
+        let edit = &edits[&position.file_id];
         let mut after = input.to_string();
         edit.apply(&mut after);
         assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }");
index 8ba783526d7b90892ed7eda5cee42625706744a7..a3ea44f23530521739926d782ca0cd88dc463064 100644 (file)
@@ -106,7 +106,7 @@ fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) {
     // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters
     // stuff.
     let mut actual = db.file_text(position.file_id).to_string();
-    edits.edits[&position.file_id].apply(&mut actual);
+    edits[&position.file_id].apply(&mut actual);
     expected.assert_eq(&actual);
 }