diff --git a/crates/ide-assists/src/tests.rs b/crates/ide-assists/src/tests.rs index 7d7012c462..b4042abf5d 100644 --- a/crates/ide-assists/src/tests.rs +++ b/crates/ide-assists/src/tests.rs @@ -710,24 +710,21 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, - annotation: None, }, Indel { insert: "var_name", delete: 48..60, - annotation: None, }, Indel { insert: "=", delete: 61..81, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -845,24 +842,21 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "let", delete: 45..47, - annotation: None, }, Indel { insert: "var_name", delete: 48..60, - annotation: None, }, Indel { insert: "=", delete: 61..81, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = var_name {\n true\n } else {\n false\n }", delete: 82..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -914,29 +908,25 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "const", delete: 45..47, - annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, - annotation: None, }, Indel { insert: "i32", delete: 61..81, - annotation: None, }, Indel { insert: "=", delete: 82..86, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -988,29 +978,25 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "static", delete: 45..47, - annotation: None, }, Indel { insert: "VAR_NAME:", delete: 48..60, - annotation: None, }, Indel { insert: "i32", delete: 61..81, - annotation: None, }, Indel { insert: "=", delete: 82..86, - annotation: None, }, Indel { insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }", delete: 87..108, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( @@ -1062,14 +1048,13 @@ pub fn test_some_range(a: int) -> bool { Indel { insert: "fun_name()", delete: 59..60, - annotation: None, }, Indel { insert: "\n\nfn fun_name() -> i32 {\n 5\n}", delete: 110..110, - annotation: None, }, ], + annotation: None, }, Some( SnippetEdit( diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index c82905edde..0735be38cd 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -2773,14 +2773,13 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } Indel { insert: "(", delete: 107..107, - annotation: None, }, Indel { insert: "qux)()", delete: 109..110, - annotation: None, }, ], + annotation: None, }, kind: SymbolKind( Field, diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index 1633065f65..a7584f67f1 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -367,14 +367,10 @@ fn rename_reference( ) })); - let mut insert_def_edit = |def| { - let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; - source_change.insert_source_edit(file_id, edit); - Ok(()) - }; // This needs to come after the references edits, because we change the annotation of existing edits // if a conflict is detected. - insert_def_edit(def)?; + let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; + source_change.insert_source_edit(file_id, edit); Ok(source_change) } diff --git a/crates/ide-db/src/text_edit.rs b/crates/ide-db/src/text_edit.rs index b59010f2f8..6e9bd7bdcc 100644 --- a/crates/ide-db/src/text_edit.rs +++ b/crates/ide-db/src/text_edit.rs @@ -18,18 +18,19 @@ pub struct Indel { pub insert: String, /// Refers to offsets in the original text pub delete: TextRange, - pub annotation: Option, } #[derive(Default, Debug, Clone)] pub struct TextEdit { /// Invariant: disjoint and sorted by `delete`. indels: Vec, + annotation: Option, } #[derive(Debug, Default, Clone)] pub struct TextEditBuilder { indels: Vec, + annotation: Option, } impl Indel { @@ -40,7 +41,7 @@ impl Indel { Indel::replace(range, String::new()) } pub fn replace(range: TextRange, replace_with: String) -> Indel { - Indel { delete: range, insert: replace_with, annotation: None } + Indel { delete: range, insert: replace_with } } pub fn apply(&self, text: &mut String) { @@ -142,12 +143,12 @@ impl TextEdit { Some(res) } - pub fn set_annotation(&mut self, annotation: Option) { - if annotation.is_some() { - for indel in &mut self.indels { - indel.annotation = annotation; - } - } + pub(crate) fn set_annotation(&mut self, conflict_annotation: Option) { + self.annotation = conflict_annotation; + } + + pub fn change_annotation(&self) -> Option { + self.annotation } } @@ -183,10 +184,10 @@ impl TextEditBuilder { self.indel(Indel::insert(offset, text)); } pub fn finish(self) -> TextEdit { - let mut indels = self.indels; + let TextEditBuilder { mut indels, annotation } = self; assert_disjoint_or_equal(&mut indels); indels = coalesce_indels(indels); - TextEdit { indels } + TextEdit { indels, annotation } } pub fn invalidates_offset(&self, offset: TextSize) -> bool { self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index d0e1c2097a..08e25dde60 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -509,10 +509,9 @@ mod tests { let found_conflicts = source_change .source_file_edits .iter() + .filter(|(_, (edit, _))| edit.change_annotation().is_some()) .flat_map(|(file_id, (edit, _))| { - edit.into_iter() - .filter(|edit| edit.annotation.is_some()) - .map(move |edit| (*file_id, edit.delete)) + edit.into_iter().map(move |edit| (*file_id, edit.delete)) }) .sorted_unstable_by_key(|(file_id, range)| (*file_id, range.start())) .collect_vec(); @@ -1081,7 +1080,6 @@ mod foo$0; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1129,7 +1127,6 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 8..11, - annotation: None, }, ], ), @@ -1141,7 +1138,6 @@ use crate::foo$0::FooContent; Indel { insert: "quux", delete: 11..14, - annotation: None, }, ], ), @@ -1183,7 +1179,6 @@ mod fo$0o; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1232,7 +1227,6 @@ mod outer { mod fo$0o; } Indel { insert: "bar", delete: 16..19, - annotation: None, }, ], ), @@ -1304,7 +1298,6 @@ pub mod foo$0; Indel { insert: "foo2", delete: 27..30, - annotation: None, }, ], ), @@ -1316,7 +1309,6 @@ pub mod foo$0; Indel { insert: "foo2", delete: 8..11, - annotation: None, }, ], ), @@ -1372,7 +1364,6 @@ mod quux; Indel { insert: "foo2", delete: 4..7, - annotation: None, }, ], ), @@ -1506,12 +1497,10 @@ pub fn baz() {} Indel { insert: "r#fn", delete: 4..7, - annotation: None, }, Indel { insert: "r#fn", delete: 22..25, - annotation: None, }, ], ), @@ -1576,12 +1565,10 @@ pub fn baz() {} Indel { insert: "foo", delete: 4..8, - annotation: None, }, Indel { insert: "foo", delete: 23..27, - annotation: None, }, ], ), @@ -1643,7 +1630,6 @@ fn bar() { Indel { insert: "dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1655,7 +1641,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1685,7 +1670,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1697,7 +1681,6 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1727,7 +1710,6 @@ fn bar() { Indel { insert: "r#dyn", delete: 7..10, - annotation: None, }, ], ), @@ -1739,7 +1721,6 @@ fn bar() { Indel { insert: "dyn", delete: 18..21, - annotation: None, }, ], ), @@ -1776,12 +1757,10 @@ fn bar() { Indel { insert: "abc", delete: 7..10, - annotation: None, }, Indel { insert: "abc", delete: 32..35, - annotation: None, }, ], ), @@ -1793,7 +1772,6 @@ fn bar() { Indel { insert: "abc", delete: 18..23, - annotation: None, }, ], ), @@ -1827,12 +1805,10 @@ fn bar() { Indel { insert: "abc", delete: 7..12, - annotation: None, }, Indel { insert: "abc", delete: 34..39, - annotation: None, }, ], ), @@ -1844,7 +1820,6 @@ fn bar() { Indel { insert: "abc", delete: 18..21, - annotation: None, }, ], ), diff --git a/crates/ide/src/ssr.rs b/crates/ide/src/ssr.rs index 90e350949b..5812a92b38 100644 --- a/crates/ide/src/ssr.rs +++ b/crates/ide/src/ssr.rs @@ -139,9 +139,9 @@ mod tests { Indel { insert: "3", delete: 33..34, - annotation: None, }, ], + annotation: None, }, None, ), @@ -182,9 +182,9 @@ mod tests { Indel { insert: "3", delete: 33..34, - annotation: None, }, ], + annotation: None, }, None, ), @@ -196,9 +196,9 @@ mod tests { Indel { insert: "3", delete: 11..12, - annotation: None, }, ], + annotation: None, }, None, ), diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index 6db7bcb111..70e567ec76 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -16,7 +16,7 @@ use ide::{ SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, UpdateTest, }; -use ide_db::{assists, rust_doc::format_docs, FxHasher}; +use ide_db::{assists, rust_doc::format_docs, source_change::ChangeAnnotationId, FxHasher}; use itertools::Itertools; use paths::{Utf8Component, Utf8Prefix}; use semver::VersionReq; @@ -200,10 +200,10 @@ pub(crate) fn snippet_text_edit( line_index: &LineIndex, is_snippet: bool, indel: Indel, + annotation: Option, client_supports_annotations: bool, ) -> lsp_ext::SnippetTextEdit { - let annotation_id = - indel.annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); + let annotation_id = annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); let text_edit = text_edit(line_index, indel); let insert_text_format = if is_snippet { Some(lsp_types::InsertTextFormat::SNIPPET) } else { None }; @@ -228,10 +228,17 @@ pub(crate) fn snippet_text_edit_vec( text_edit: TextEdit, clients_support_annotations: bool, ) -> Vec { + let annotation = text_edit.change_annotation(); text_edit .into_iter() .map(|indel| { - self::snippet_text_edit(line_index, is_snippet, indel, clients_support_annotations) + self::snippet_text_edit( + line_index, + is_snippet, + indel, + annotation, + clients_support_annotations, + ) }) .collect() } @@ -1082,6 +1089,7 @@ fn merge_text_and_snippet_edits( ) -> Vec { let mut edits: Vec = vec![]; let mut snippets = snippet_edit.into_edit_ranges().into_iter().peekable(); + let annotation = edit.change_annotation(); let text_edits = edit.into_iter(); // offset to go from the final source location to the original source location let mut source_text_offset = 0i32; @@ -1127,11 +1135,8 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { - insert: format!("${snippet_index}"), - delete: snippet_range, - annotation: None, - }, + Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + annotation, client_supports_annotations, )) } @@ -1190,11 +1195,8 @@ fn merge_text_and_snippet_edits( edits.push(snippet_text_edit( line_index, true, - Indel { - insert: new_text, - delete: current_indel.delete, - annotation: current_indel.annotation, - }, + Indel { insert: new_text, delete: current_indel.delete }, + annotation, client_supports_annotations, )) } else { @@ -1204,6 +1206,7 @@ fn merge_text_and_snippet_edits( line_index, false, current_indel, + annotation, client_supports_annotations, )); } @@ -1230,7 +1233,8 @@ fn merge_text_and_snippet_edits( snippet_text_edit( line_index, true, - Indel { insert: format!("${snippet_index}"), delete: snippet_range, annotation: None }, + Indel { insert: format!("${snippet_index}"), delete: snippet_range }, + annotation, client_supports_annotations, ) })); @@ -1251,8 +1255,17 @@ pub(crate) fn snippet_text_document_edit( let mut edits = if let Some(snippet_edit) = snippet_edit { merge_text_and_snippet_edits(&line_index, edit, snippet_edit, client_supports_annotations) } else { + let annotation = edit.change_annotation(); edit.into_iter() - .map(|it| snippet_text_edit(&line_index, is_snippet, it, client_supports_annotations)) + .map(|it| { + snippet_text_edit( + &line_index, + is_snippet, + it, + annotation, + client_supports_annotations, + ) + }) .collect() };