diff options
-rw-r--r-- | crates/assists/src/assist_context.rs | 28 | ||||
-rw-r--r-- | crates/assists/src/tests.rs | 25 | ||||
-rw-r--r-- | crates/ide/src/diagnostics.rs | 12 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/field_shorthand.rs | 6 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/fixes.rs | 18 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/references/rename.rs | 195 | ||||
-rw-r--r-- | crates/ide/src/typing.rs | 3 | ||||
-rw-r--r-- | crates/ide_db/src/source_change.rs | 50 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/ssr.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 10 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 2 | ||||
-rw-r--r-- | crates/ssr/src/lib.rs | 36 | ||||
-rw-r--r-- | crates/ssr/src/matching.rs | 2 | ||||
-rw-r--r-- | crates/ssr/src/tests.rs | 2 |
15 files changed, 179 insertions, 214 deletions
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index de4b32573..321fe77f3 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs | |||
@@ -10,7 +10,7 @@ use ide_db::{ | |||
10 | }; | 10 | }; |
11 | use ide_db::{ | 11 | use ide_db::{ |
12 | label::Label, | 12 | label::Label, |
13 | source_change::{FileSystemEdit, SourceChange, SourceFileEdits}, | 13 | source_change::{FileSystemEdit, SourceChange}, |
14 | RootDatabase, | 14 | RootDatabase, |
15 | }; | 15 | }; |
16 | use syntax::{ | 16 | use syntax::{ |
@@ -180,20 +180,12 @@ impl Assists { | |||
180 | pub(crate) struct AssistBuilder { | 180 | pub(crate) struct AssistBuilder { |
181 | edit: TextEditBuilder, | 181 | edit: TextEditBuilder, |
182 | file_id: FileId, | 182 | file_id: FileId, |
183 | is_snippet: bool, | 183 | source_change: SourceChange, |
184 | source_file_edits: SourceFileEdits, | ||
185 | file_system_edits: Vec<FileSystemEdit>, | ||
186 | } | 184 | } |
187 | 185 | ||
188 | impl AssistBuilder { | 186 | impl AssistBuilder { |
189 | pub(crate) fn new(file_id: FileId) -> AssistBuilder { | 187 | pub(crate) fn new(file_id: FileId) -> AssistBuilder { |
190 | AssistBuilder { | 188 | AssistBuilder { edit: TextEdit::builder(), file_id, source_change: SourceChange::default() } |
191 | edit: TextEdit::builder(), | ||
192 | file_id, | ||
193 | is_snippet: false, | ||
194 | source_file_edits: SourceFileEdits::default(), | ||
195 | file_system_edits: Vec::default(), | ||
196 | } | ||
197 | } | 189 | } |
198 | 190 | ||
199 | pub(crate) fn edit_file(&mut self, file_id: FileId) { | 191 | pub(crate) fn edit_file(&mut self, file_id: FileId) { |
@@ -204,7 +196,7 @@ impl AssistBuilder { | |||
204 | fn commit(&mut self) { | 196 | fn commit(&mut self) { |
205 | let edit = mem::take(&mut self.edit).finish(); | 197 | let edit = mem::take(&mut self.edit).finish(); |
206 | if !edit.is_empty() { | 198 | if !edit.is_empty() { |
207 | self.source_file_edits.insert(self.file_id, edit); | 199 | self.source_change.insert_source_edit(self.file_id, edit); |
208 | } | 200 | } |
209 | } | 201 | } |
210 | 202 | ||
@@ -223,7 +215,7 @@ impl AssistBuilder { | |||
223 | offset: TextSize, | 215 | offset: TextSize, |
224 | snippet: impl Into<String>, | 216 | snippet: impl Into<String>, |
225 | ) { | 217 | ) { |
226 | self.is_snippet = true; | 218 | self.source_change.is_snippet = true; |
227 | self.insert(offset, snippet); | 219 | self.insert(offset, snippet); |
228 | } | 220 | } |
229 | /// Replaces specified `range` of text with a given string. | 221 | /// Replaces specified `range` of text with a given string. |
@@ -237,7 +229,7 @@ impl AssistBuilder { | |||
237 | range: TextRange, | 229 | range: TextRange, |
238 | snippet: impl Into<String>, | 230 | snippet: impl Into<String>, |
239 | ) { | 231 | ) { |
240 | self.is_snippet = true; | 232 | self.source_change.is_snippet = true; |
241 | self.replace(range, snippet); | 233 | self.replace(range, snippet); |
242 | } | 234 | } |
243 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { | 235 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { |
@@ -252,15 +244,11 @@ impl AssistBuilder { | |||
252 | pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) { | 244 | pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) { |
253 | let file_system_edit = | 245 | let file_system_edit = |
254 | FileSystemEdit::CreateFile { dst: dst.clone(), initial_contents: content.into() }; | 246 | FileSystemEdit::CreateFile { dst: dst.clone(), initial_contents: content.into() }; |
255 | self.file_system_edits.push(file_system_edit); | 247 | self.source_change.push_file_system_edit(file_system_edit); |
256 | } | 248 | } |
257 | 249 | ||
258 | fn finish(mut self) -> SourceChange { | 250 | fn finish(mut self) -> SourceChange { |
259 | self.commit(); | 251 | self.commit(); |
260 | SourceChange { | 252 | mem::take(&mut self.source_change) |
261 | source_file_edits: mem::take(&mut self.source_file_edits), | ||
262 | file_system_edits: mem::take(&mut self.file_system_edits), | ||
263 | is_snippet: self.is_snippet, | ||
264 | } | ||
265 | } | 253 | } |
266 | } | 254 | } |
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs index d13d6ad31..71431b406 100644 --- a/crates/assists/src/tests.rs +++ b/crates/assists/src/tests.rs | |||
@@ -80,7 +80,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { | |||
80 | let actual = { | 80 | let actual = { |
81 | let source_change = assist.source_change.unwrap(); | 81 | let source_change = assist.source_change.unwrap(); |
82 | let mut actual = before; | 82 | let mut actual = before; |
83 | if let Some(source_file_edit) = source_change.source_file_edits.edits.get(&file_id) { | 83 | if let Some(source_file_edit) = source_change.get_source_edit(file_id) { |
84 | source_file_edit.apply(&mut actual); | 84 | source_file_edit.apply(&mut actual); |
85 | } | 85 | } |
86 | actual | 86 | actual |
@@ -120,7 +120,7 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
120 | && source_change.file_system_edits.len() == 0; | 120 | && source_change.file_system_edits.len() == 0; |
121 | 121 | ||
122 | let mut buf = String::new(); | 122 | let mut buf = String::new(); |
123 | for (file_id, edit) in source_change.source_file_edits.edits { | 123 | for (file_id, edit) in source_change.source_file_edits { |
124 | let mut text = db.file_text(file_id).as_ref().to_owned(); | 124 | let mut text = db.file_text(file_id).as_ref().to_owned(); |
125 | edit.apply(&mut text); | 125 | edit.apply(&mut text); |
126 | if !skip_header { | 126 | if !skip_header { |
@@ -132,18 +132,15 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
132 | buf.push_str(&text); | 132 | buf.push_str(&text); |
133 | } | 133 | } |
134 | 134 | ||
135 | for file_system_edit in source_change.file_system_edits.clone() { | 135 | for file_system_edit in source_change.file_system_edits { |
136 | match file_system_edit { | 136 | if let FileSystemEdit::CreateFile { dst, initial_contents } = file_system_edit { |
137 | FileSystemEdit::CreateFile { dst, initial_contents } => { | 137 | let sr = db.file_source_root(dst.anchor); |
138 | let sr = db.file_source_root(dst.anchor); | 138 | let sr = db.source_root(sr); |
139 | let sr = db.source_root(sr); | 139 | let mut base = sr.path_for_file(&dst.anchor).unwrap().clone(); |
140 | let mut base = sr.path_for_file(&dst.anchor).unwrap().clone(); | 140 | base.pop(); |
141 | base.pop(); | 141 | let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]); |
142 | let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]); | 142 | format_to!(buf, "//- {}\n", created_file_path); |
143 | format_to!(buf, "//- {}\n", created_file_path); | 143 | buf.push_str(&initial_contents); |
144 | buf.push_str(&initial_contents); | ||
145 | } | ||
146 | _ => (), | ||
147 | } | 144 | } |
148 | } | 145 | } |
149 | 146 | ||
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index a43188fb0..2e5395b51 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -13,7 +13,7 @@ use hir::{ | |||
13 | diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, | 13 | diagnostics::{Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, |
14 | Semantics, | 14 | Semantics, |
15 | }; | 15 | }; |
16 | use ide_db::{base_db::SourceDatabase, source_change::SourceFileEdits, RootDatabase}; | 16 | use ide_db::{base_db::SourceDatabase, RootDatabase}; |
17 | use itertools::Itertools; | 17 | use itertools::Itertools; |
18 | use rustc_hash::FxHashSet; | 18 | use rustc_hash::FxHashSet; |
19 | use syntax::{ | 19 | use syntax::{ |
@@ -219,7 +219,7 @@ fn check_unnecessary_braces_in_use_statement( | |||
219 | Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string()) | 219 | Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string()) |
220 | .with_fix(Some(Fix::new( | 220 | .with_fix(Some(Fix::new( |
221 | "Remove unnecessary braces", | 221 | "Remove unnecessary braces", |
222 | SourceFileEdits::from_text_edit(file_id, edit).into(), | 222 | SourceChange::from_text_edit(file_id, edit), |
223 | use_range, | 223 | use_range, |
224 | ))), | 224 | ))), |
225 | ); | 225 | ); |
@@ -264,10 +264,10 @@ mod tests { | |||
264 | .unwrap(); | 264 | .unwrap(); |
265 | let fix = diagnostic.fix.unwrap(); | 265 | let fix = diagnostic.fix.unwrap(); |
266 | let actual = { | 266 | let actual = { |
267 | let file_id = *fix.source_change.source_file_edits.edits.keys().next().unwrap(); | 267 | let file_id = *fix.source_change.source_file_edits.keys().next().unwrap(); |
268 | let mut actual = analysis.file_text(file_id).unwrap().to_string(); | 268 | let mut actual = analysis.file_text(file_id).unwrap().to_string(); |
269 | 269 | ||
270 | for edit in fix.source_change.source_file_edits.edits.values() { | 270 | for edit in fix.source_change.source_file_edits.values() { |
271 | edit.apply(&mut actual); | 271 | edit.apply(&mut actual); |
272 | } | 272 | } |
273 | actual | 273 | actual |
@@ -613,9 +613,7 @@ fn test_fn() { | |||
613 | Fix { | 613 | Fix { |
614 | label: "Create module", | 614 | label: "Create module", |
615 | source_change: SourceChange { | 615 | source_change: SourceChange { |
616 | source_file_edits: SourceFileEdits { | 616 | source_file_edits: {}, |
617 | edits: {}, | ||
618 | }, | ||
619 | file_system_edits: [ | 617 | file_system_edits: [ |
620 | CreateFile { | 618 | CreateFile { |
621 | dst: AnchoredPathBuf { | 619 | dst: AnchoredPathBuf { |
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs index f4ec51b64..5c89e2170 100644 --- a/crates/ide/src/diagnostics/field_shorthand.rs +++ b/crates/ide/src/diagnostics/field_shorthand.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Suggests shortening `Foo { field: field }` to `Foo { field }` in both | 1 | //! Suggests shortening `Foo { field: field }` to `Foo { field }` in both |
2 | //! expressions and patterns. | 2 | //! expressions and patterns. |
3 | 3 | ||
4 | use ide_db::{base_db::FileId, source_change::SourceFileEdits}; | 4 | use ide_db::{base_db::FileId, source_change::SourceChange}; |
5 | use syntax::{ast, match_ast, AstNode, SyntaxNode}; | 5 | use syntax::{ast, match_ast, AstNode, SyntaxNode}; |
6 | use text_edit::TextEdit; | 6 | use text_edit::TextEdit; |
7 | 7 | ||
@@ -49,7 +49,7 @@ fn check_expr_field_shorthand( | |||
49 | Diagnostic::hint(field_range, "Shorthand struct initialization".to_string()).with_fix( | 49 | Diagnostic::hint(field_range, "Shorthand struct initialization".to_string()).with_fix( |
50 | Some(Fix::new( | 50 | Some(Fix::new( |
51 | "Use struct shorthand initialization", | 51 | "Use struct shorthand initialization", |
52 | SourceFileEdits::from_text_edit(file_id, edit).into(), | 52 | SourceChange::from_text_edit(file_id, edit), |
53 | field_range, | 53 | field_range, |
54 | )), | 54 | )), |
55 | ), | 55 | ), |
@@ -88,7 +88,7 @@ fn check_pat_field_shorthand( | |||
88 | acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fix( | 88 | acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fix( |
89 | Some(Fix::new( | 89 | Some(Fix::new( |
90 | "Use struct field shorthand", | 90 | "Use struct field shorthand", |
91 | SourceFileEdits::from_text_edit(file_id, edit).into(), | 91 | SourceChange::from_text_edit(file_id, edit), |
92 | field_range, | 92 | field_range, |
93 | )), | 93 | )), |
94 | )); | 94 | )); |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index b04964ccd..e4335119b 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -10,7 +10,7 @@ use hir::{ | |||
10 | }; | 10 | }; |
11 | use ide_db::{ | 11 | use ide_db::{ |
12 | base_db::{AnchoredPathBuf, FileId}, | 12 | base_db::{AnchoredPathBuf, FileId}, |
13 | source_change::{FileSystemEdit, SourceFileEdits}, | 13 | source_change::{FileSystemEdit, SourceChange}, |
14 | RootDatabase, | 14 | RootDatabase, |
15 | }; | 15 | }; |
16 | use syntax::{ | 16 | use syntax::{ |
@@ -88,7 +88,7 @@ impl DiagnosticWithFix for MissingFields { | |||
88 | }; | 88 | }; |
89 | Some(Fix::new( | 89 | Some(Fix::new( |
90 | "Fill struct fields", | 90 | "Fill struct fields", |
91 | SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into(), | 91 | SourceChange::from_text_edit(self.file.original_file(sema.db), edit), |
92 | sema.original_range(&field_list_parent.syntax()).range, | 92 | sema.original_range(&field_list_parent.syntax()).range, |
93 | )) | 93 | )) |
94 | } | 94 | } |
@@ -101,8 +101,7 @@ impl DiagnosticWithFix for MissingOkOrSomeInTailExpr { | |||
101 | let tail_expr_range = tail_expr.syntax().text_range(); | 101 | let tail_expr_range = tail_expr.syntax().text_range(); |
102 | let replacement = format!("{}({})", self.required, tail_expr.syntax()); | 102 | let replacement = format!("{}({})", self.required, tail_expr.syntax()); |
103 | let edit = TextEdit::replace(tail_expr_range, replacement); | 103 | let edit = TextEdit::replace(tail_expr_range, replacement); |
104 | let source_change = | 104 | let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit); |
105 | SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into(); | ||
106 | let name = if self.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" }; | 105 | let name = if self.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" }; |
107 | Some(Fix::new(name, source_change, tail_expr_range)) | 106 | Some(Fix::new(name, source_change, tail_expr_range)) |
108 | } | 107 | } |
@@ -122,8 +121,7 @@ impl DiagnosticWithFix for RemoveThisSemicolon { | |||
122 | .text_range(); | 121 | .text_range(); |
123 | 122 | ||
124 | let edit = TextEdit::delete(semicolon); | 123 | let edit = TextEdit::delete(semicolon); |
125 | let source_change = | 124 | let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit); |
126 | SourceFileEdits::from_text_edit(self.file.original_file(sema.db), edit).into(); | ||
127 | 125 | ||
128 | Some(Fix::new("Remove this semicolon", source_change, semicolon)) | 126 | Some(Fix::new("Remove this semicolon", source_change, semicolon)) |
129 | } | 127 | } |
@@ -204,15 +202,11 @@ fn missing_record_expr_field_fix( | |||
204 | new_field = format!(",{}", new_field); | 202 | new_field = format!(",{}", new_field); |
205 | } | 203 | } |
206 | 204 | ||
207 | let source_change = SourceFileEdits::from_text_edit( | 205 | let source_change = SourceChange::from_text_edit( |
208 | def_file_id, | 206 | def_file_id, |
209 | TextEdit::insert(last_field_syntax.text_range().end(), new_field), | 207 | TextEdit::insert(last_field_syntax.text_range().end(), new_field), |
210 | ); | 208 | ); |
211 | return Some(Fix::new( | 209 | return Some(Fix::new("Create field", source_change, record_expr_field.syntax().text_range())); |
212 | "Create field", | ||
213 | source_change.into(), | ||
214 | record_expr_field.syntax().text_range(), | ||
215 | )); | ||
216 | 210 | ||
217 | fn record_field_list(field_def_list: ast::FieldList) -> Option<ast::RecordFieldList> { | 211 | fn record_field_list(field_def_list: ast::FieldList) -> Option<ast::RecordFieldList> { |
218 | match field_def_list { | 212 | match field_def_list { |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 110920e58..afd552008 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -98,7 +98,7 @@ pub use ide_db::{ | |||
98 | label::Label, | 98 | label::Label, |
99 | line_index::{LineCol, LineIndex}, | 99 | line_index::{LineCol, LineIndex}, |
100 | search::SearchScope, | 100 | search::SearchScope, |
101 | source_change::{FileSystemEdit, SourceChange, SourceFileEdits}, | 101 | source_change::{FileSystemEdit, SourceChange}, |
102 | symbol_index::Query, | 102 | symbol_index::Query, |
103 | RootDatabase, | 103 | RootDatabase, |
104 | }; | 104 | }; |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index cd9c7c7e5..039efb26f 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -21,7 +21,7 @@ use text_edit::TextEdit; | |||
21 | 21 | ||
22 | use crate::{ | 22 | use crate::{ |
23 | FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, | 23 | FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, |
24 | SourceFileEdits, TextRange, TextSize, | 24 | TextRange, TextSize, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | type RenameResult<T> = Result<T, RenameError>; | 27 | type RenameResult<T> = Result<T, RenameError>; |
@@ -249,8 +249,8 @@ fn rename_mod( | |||
249 | if IdentifierKind::Ident != check_identifier(new_name)? { | 249 | if IdentifierKind::Ident != check_identifier(new_name)? { |
250 | bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); | 250 | bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); |
251 | } | 251 | } |
252 | let mut source_file_edits = SourceFileEdits::default(); | 252 | |
253 | let mut file_system_edits = Vec::new(); | 253 | let mut source_change = SourceChange::default(); |
254 | 254 | ||
255 | let src = module.definition_source(sema.db); | 255 | let src = module.definition_source(sema.db); |
256 | let file_id = src.file_id.original_file(sema.db); | 256 | let file_id = src.file_id.original_file(sema.db); |
@@ -264,7 +264,7 @@ fn rename_mod( | |||
264 | }; | 264 | }; |
265 | let dst = AnchoredPathBuf { anchor: file_id, path }; | 265 | let dst = AnchoredPathBuf { anchor: file_id, path }; |
266 | let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; | 266 | let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; |
267 | file_system_edits.push(move_file); | 267 | source_change.push_file_system_edit(move_file); |
268 | } | 268 | } |
269 | ModuleSource::Module(..) => {} | 269 | ModuleSource::Module(..) => {} |
270 | } | 270 | } |
@@ -272,17 +272,19 @@ fn rename_mod( | |||
272 | if let Some(src) = module.declaration_source(sema.db) { | 272 | if let Some(src) = module.declaration_source(sema.db) { |
273 | let file_id = src.file_id.original_file(sema.db); | 273 | let file_id = src.file_id.original_file(sema.db); |
274 | let name = src.value.name().unwrap(); | 274 | let name = src.value.name().unwrap(); |
275 | source_file_edits | 275 | source_change.insert_source_edit( |
276 | .insert(file_id, TextEdit::replace(name.syntax().text_range(), new_name.into())); | 276 | file_id, |
277 | TextEdit::replace(name.syntax().text_range(), new_name.into()), | ||
278 | ); | ||
277 | } | 279 | } |
278 | 280 | ||
279 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 281 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; |
280 | let ref_edits = refs.references().iter().map(|(&file_id, references)| { | 282 | let ref_edits = refs.references().iter().map(|(&file_id, references)| { |
281 | source_edit_from_references(sema, file_id, references, new_name) | 283 | source_edit_from_references(sema, file_id, references, new_name) |
282 | }); | 284 | }); |
283 | source_file_edits.extend(ref_edits); | 285 | source_change.extend(ref_edits); |
284 | 286 | ||
285 | Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) | 287 | Ok(RangeInfo::new(range, source_change)) |
286 | } | 288 | } |
287 | 289 | ||
288 | fn rename_to_self( | 290 | fn rename_to_self( |
@@ -331,13 +333,16 @@ fn rename_to_self( | |||
331 | 333 | ||
332 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 334 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; |
333 | 335 | ||
334 | let mut edits = SourceFileEdits::default(); | 336 | let mut source_change = SourceChange::default(); |
335 | edits.extend(refs.references().iter().map(|(&file_id, references)| { | 337 | source_change.extend(refs.references().iter().map(|(&file_id, references)| { |
336 | source_edit_from_references(sema, file_id, references, "self") | 338 | source_edit_from_references(sema, file_id, references, "self") |
337 | })); | 339 | })); |
338 | edits.insert(position.file_id, TextEdit::replace(param_range, String::from(self_param))); | 340 | source_change.insert_source_edit( |
341 | position.file_id, | ||
342 | TextEdit::replace(param_range, String::from(self_param)), | ||
343 | ); | ||
339 | 344 | ||
340 | Ok(RangeInfo::new(range, edits.into())) | 345 | Ok(RangeInfo::new(range, source_change)) |
341 | } | 346 | } |
342 | 347 | ||
343 | fn text_edit_from_self_param( | 348 | fn text_edit_from_self_param( |
@@ -391,7 +396,7 @@ fn rename_self_to_param( | |||
391 | .ok_or_else(|| format_err!("No surrounding method declaration found"))?; | 396 | .ok_or_else(|| format_err!("No surrounding method declaration found"))?; |
392 | let search_range = fn_def.syntax().text_range(); | 397 | let search_range = fn_def.syntax().text_range(); |
393 | 398 | ||
394 | let mut edits = SourceFileEdits::default(); | 399 | let mut source_change = SourceChange::default(); |
395 | 400 | ||
396 | for (idx, _) in text.match_indices("self") { | 401 | for (idx, _) in text.match_indices("self") { |
397 | let offset: TextSize = idx.try_into().unwrap(); | 402 | let offset: TextSize = idx.try_into().unwrap(); |
@@ -405,18 +410,18 @@ fn rename_self_to_param( | |||
405 | } else { | 410 | } else { |
406 | TextEdit::replace(usage.text_range(), String::from(new_name)) | 411 | TextEdit::replace(usage.text_range(), String::from(new_name)) |
407 | }; | 412 | }; |
408 | edits.insert(position.file_id, edit); | 413 | source_change.insert_source_edit(position.file_id, edit); |
409 | } | 414 | } |
410 | } | 415 | } |
411 | 416 | ||
412 | if edits.len() > 1 && ident_kind == IdentifierKind::Underscore { | 417 | if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore { |
413 | bail!("Cannot rename reference to `_` as it is being referenced multiple times"); | 418 | bail!("Cannot rename reference to `_` as it is being referenced multiple times"); |
414 | } | 419 | } |
415 | 420 | ||
416 | let range = ast::SelfParam::cast(self_token.parent()) | 421 | let range = ast::SelfParam::cast(self_token.parent()) |
417 | .map_or(self_token.text_range(), |p| p.syntax().text_range()); | 422 | .map_or(self_token.text_range(), |p| p.syntax().text_range()); |
418 | 423 | ||
419 | Ok(RangeInfo::new(range, edits.into())) | 424 | Ok(RangeInfo::new(range, source_change)) |
420 | } | 425 | } |
421 | 426 | ||
422 | fn rename_reference( | 427 | fn rename_reference( |
@@ -453,12 +458,12 @@ fn rename_reference( | |||
453 | (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), | 458 | (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), |
454 | } | 459 | } |
455 | 460 | ||
456 | let mut edits = SourceFileEdits::default(); | 461 | let mut source_change = SourceChange::default(); |
457 | edits.extend(refs.into_iter().map(|(file_id, references)| { | 462 | source_change.extend(refs.into_iter().map(|(file_id, references)| { |
458 | source_edit_from_references(sema, file_id, &references, new_name) | 463 | source_edit_from_references(sema, file_id, &references, new_name) |
459 | })); | 464 | })); |
460 | 465 | ||
461 | Ok(RangeInfo::new(range, edits.into())) | 466 | Ok(RangeInfo::new(range, source_change)) |
462 | } | 467 | } |
463 | 468 | ||
464 | #[cfg(test)] | 469 | #[cfg(test)] |
@@ -480,7 +485,7 @@ mod tests { | |||
480 | Ok(source_change) => { | 485 | Ok(source_change) => { |
481 | let mut text_edit_builder = TextEdit::builder(); | 486 | let mut text_edit_builder = TextEdit::builder(); |
482 | let mut file_id: Option<FileId> = None; | 487 | let mut file_id: Option<FileId> = None; |
483 | for edit in source_change.info.source_file_edits.edits { | 488 | for edit in source_change.info.source_file_edits { |
484 | file_id = Some(edit.0); | 489 | file_id = Some(edit.0); |
485 | for indel in edit.1.into_iter() { | 490 | for indel in edit.1.into_iter() { |
486 | text_edit_builder.replace(indel.delete, indel.insert); | 491 | text_edit_builder.replace(indel.delete, indel.insert); |
@@ -882,18 +887,16 @@ mod foo$0; | |||
882 | RangeInfo { | 887 | RangeInfo { |
883 | range: 4..7, | 888 | range: 4..7, |
884 | info: SourceChange { | 889 | info: SourceChange { |
885 | source_file_edits: SourceFileEdits { | 890 | source_file_edits: { |
886 | edits: { | 891 | FileId( |
887 | FileId( | 892 | 1, |
888 | 1, | 893 | ): TextEdit { |
889 | ): TextEdit { | 894 | indels: [ |
890 | indels: [ | 895 | Indel { |
891 | Indel { | 896 | insert: "foo2", |
892 | insert: "foo2", | 897 | delete: 4..7, |
893 | delete: 4..7, | 898 | }, |
894 | }, | 899 | ], |
895 | ], | ||
896 | }, | ||
897 | }, | 900 | }, |
898 | }, | 901 | }, |
899 | file_system_edits: [ | 902 | file_system_edits: [ |
@@ -936,28 +939,26 @@ use crate::foo$0::FooContent; | |||
936 | RangeInfo { | 939 | RangeInfo { |
937 | range: 11..14, | 940 | range: 11..14, |
938 | info: SourceChange { | 941 | info: SourceChange { |
939 | source_file_edits: SourceFileEdits { | 942 | source_file_edits: { |
940 | edits: { | 943 | FileId( |
941 | FileId( | 944 | 0, |
942 | 0, | 945 | ): TextEdit { |
943 | ): TextEdit { | 946 | indels: [ |
944 | indels: [ | 947 | Indel { |
945 | Indel { | 948 | insert: "quux", |
946 | insert: "quux", | 949 | delete: 8..11, |
947 | delete: 8..11, | 950 | }, |
948 | }, | 951 | ], |
949 | ], | 952 | }, |
950 | }, | 953 | FileId( |
951 | FileId( | 954 | 2, |
952 | 2, | 955 | ): TextEdit { |
953 | ): TextEdit { | 956 | indels: [ |
954 | indels: [ | 957 | Indel { |
955 | Indel { | 958 | insert: "quux", |
956 | insert: "quux", | 959 | delete: 11..14, |
957 | delete: 11..14, | 960 | }, |
958 | }, | 961 | ], |
959 | ], | ||
960 | }, | ||
961 | }, | 962 | }, |
962 | }, | 963 | }, |
963 | file_system_edits: [ | 964 | file_system_edits: [ |
@@ -994,18 +995,16 @@ mod fo$0o; | |||
994 | RangeInfo { | 995 | RangeInfo { |
995 | range: 4..7, | 996 | range: 4..7, |
996 | info: SourceChange { | 997 | info: SourceChange { |
997 | source_file_edits: SourceFileEdits { | 998 | source_file_edits: { |
998 | edits: { | 999 | FileId( |
999 | FileId( | 1000 | 0, |
1000 | 0, | 1001 | ): TextEdit { |
1001 | ): TextEdit { | 1002 | indels: [ |
1002 | indels: [ | 1003 | Indel { |
1003 | Indel { | 1004 | insert: "foo2", |
1004 | insert: "foo2", | 1005 | delete: 4..7, |
1005 | delete: 4..7, | 1006 | }, |
1006 | }, | 1007 | ], |
1007 | ], | ||
1008 | }, | ||
1009 | }, | 1008 | }, |
1010 | }, | 1009 | }, |
1011 | file_system_edits: [ | 1010 | file_system_edits: [ |
@@ -1043,18 +1042,16 @@ mod outer { mod fo$0o; } | |||
1043 | RangeInfo { | 1042 | RangeInfo { |
1044 | range: 16..19, | 1043 | range: 16..19, |
1045 | info: SourceChange { | 1044 | info: SourceChange { |
1046 | source_file_edits: SourceFileEdits { | 1045 | source_file_edits: { |
1047 | edits: { | 1046 | FileId( |
1048 | FileId( | 1047 | 0, |
1049 | 0, | 1048 | ): TextEdit { |
1050 | ): TextEdit { | 1049 | indels: [ |
1051 | indels: [ | 1050 | Indel { |
1052 | Indel { | 1051 | insert: "bar", |
1053 | insert: "bar", | 1052 | delete: 16..19, |
1054 | delete: 16..19, | 1053 | }, |
1055 | }, | 1054 | ], |
1056 | ], | ||
1057 | }, | ||
1058 | }, | 1055 | }, |
1059 | }, | 1056 | }, |
1060 | file_system_edits: [ | 1057 | file_system_edits: [ |
@@ -1115,28 +1112,26 @@ pub mod foo$0; | |||
1115 | RangeInfo { | 1112 | RangeInfo { |
1116 | range: 8..11, | 1113 | range: 8..11, |
1117 | info: SourceChange { | 1114 | info: SourceChange { |
1118 | source_file_edits: SourceFileEdits { | 1115 | source_file_edits: { |
1119 | edits: { | 1116 | FileId( |
1120 | FileId( | 1117 | 0, |
1121 | 0, | 1118 | ): TextEdit { |
1122 | ): TextEdit { | 1119 | indels: [ |
1123 | indels: [ | 1120 | Indel { |
1124 | Indel { | 1121 | insert: "foo2", |
1125 | insert: "foo2", | 1122 | delete: 27..30, |
1126 | delete: 27..30, | 1123 | }, |
1127 | }, | 1124 | ], |
1128 | ], | 1125 | }, |
1129 | }, | 1126 | FileId( |
1130 | FileId( | 1127 | 1, |
1131 | 1, | 1128 | ): TextEdit { |
1132 | ): TextEdit { | 1129 | indels: [ |
1133 | indels: [ | 1130 | Indel { |
1134 | Indel { | 1131 | insert: "foo2", |
1135 | insert: "foo2", | 1132 | delete: 8..11, |
1136 | delete: 8..11, | 1133 | }, |
1137 | }, | 1134 | ], |
1138 | ], | ||
1139 | }, | ||
1140 | }, | 1135 | }, |
1141 | }, | 1136 | }, |
1142 | file_system_edits: [ | 1137 | file_system_edits: [ |
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index b3fc32645..e3c3aebac 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs | |||
@@ -17,7 +17,6 @@ mod on_enter; | |||
17 | 17 | ||
18 | use ide_db::{ | 18 | use ide_db::{ |
19 | base_db::{FilePosition, SourceDatabase}, | 19 | base_db::{FilePosition, SourceDatabase}, |
20 | source_change::SourceFileEdits, | ||
21 | RootDatabase, | 20 | RootDatabase, |
22 | }; | 21 | }; |
23 | use syntax::{ | 22 | use syntax::{ |
@@ -59,7 +58,7 @@ pub(crate) fn on_char_typed( | |||
59 | let file = &db.parse(position.file_id).tree(); | 58 | let file = &db.parse(position.file_id).tree(); |
60 | assert_eq!(file.syntax().text().char_at(position.offset), Some(char_typed)); | 59 | assert_eq!(file.syntax().text().char_at(position.offset), Some(char_typed)); |
61 | let edit = on_char_typed_inner(file, position.offset, char_typed)?; | 60 | let edit = on_char_typed_inner(file, position.offset, char_typed)?; |
62 | Some(SourceFileEdits::from_text_edit(position.file_id, edit).into()) | 61 | Some(SourceChange::from_text_edit(position.file_id, edit)) |
63 | } | 62 | } |
64 | 63 | ||
65 | fn on_char_typed_inner(file: &SourceFile, offset: TextSize, char_typed: char) -> Option<TextEdit> { | 64 | fn on_char_typed_inner(file: &SourceFile, offset: TextSize, char_typed: char) -> Option<TextEdit> { |
diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index 516d7859a..b1f87731b 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs | |||
@@ -10,11 +10,12 @@ use std::{ | |||
10 | 10 | ||
11 | use base_db::{AnchoredPathBuf, FileId}; | 11 | use base_db::{AnchoredPathBuf, FileId}; |
12 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
13 | use stdx::assert_never; | ||
13 | use text_edit::TextEdit; | 14 | use text_edit::TextEdit; |
14 | 15 | ||
15 | #[derive(Default, Debug, Clone)] | 16 | #[derive(Default, Debug, Clone)] |
16 | pub struct SourceChange { | 17 | pub struct SourceChange { |
17 | pub source_file_edits: SourceFileEdits, | 18 | pub source_file_edits: FxHashMap<FileId, TextEdit>, |
18 | pub file_system_edits: Vec<FileSystemEdit>, | 19 | pub file_system_edits: Vec<FileSystemEdit>, |
19 | pub is_snippet: bool, | 20 | pub is_snippet: bool, |
20 | } | 21 | } |
@@ -23,51 +24,50 @@ impl SourceChange { | |||
23 | /// Creates a new SourceChange with the given label | 24 | /// Creates a new SourceChange with the given label |
24 | /// from the edits. | 25 | /// from the edits. |
25 | pub fn from_edits( | 26 | pub fn from_edits( |
26 | source_file_edits: SourceFileEdits, | 27 | source_file_edits: FxHashMap<FileId, TextEdit>, |
27 | file_system_edits: Vec<FileSystemEdit>, | 28 | file_system_edits: Vec<FileSystemEdit>, |
28 | ) -> Self { | 29 | ) -> Self { |
29 | SourceChange { source_file_edits, file_system_edits, is_snippet: false } | 30 | SourceChange { source_file_edits, file_system_edits, is_snippet: false } |
30 | } | 31 | } |
31 | } | ||
32 | |||
33 | #[derive(Default, Debug, Clone)] | ||
34 | pub struct SourceFileEdits { | ||
35 | pub edits: FxHashMap<FileId, TextEdit>, | ||
36 | } | ||
37 | 32 | ||
38 | impl SourceFileEdits { | ||
39 | pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { | 33 | pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { |
40 | SourceFileEdits { edits: FxHashMap::from_iter(iter::once((file_id, edit))) } | 34 | SourceChange { |
41 | } | 35 | source_file_edits: FxHashMap::from_iter(iter::once((file_id, edit))), |
42 | 36 | ..Default::default() | |
43 | pub fn len(&self) -> usize { | 37 | } |
44 | self.edits.len() | ||
45 | } | ||
46 | |||
47 | pub fn is_empty(&self) -> bool { | ||
48 | self.edits.is_empty() | ||
49 | } | 38 | } |
50 | 39 | ||
51 | pub fn insert(&mut self, file_id: FileId, edit: TextEdit) { | 40 | pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) { |
52 | match self.edits.entry(file_id) { | 41 | match self.source_file_edits.entry(file_id) { |
53 | Entry::Occupied(mut entry) => { | 42 | Entry::Occupied(mut entry) => { |
54 | entry.get_mut().union(edit).expect("overlapping edits for same file"); | 43 | assert_never!( |
44 | entry.get_mut().union(edit).is_err(), | ||
45 | "overlapping edits for same file" | ||
46 | ); | ||
55 | } | 47 | } |
56 | Entry::Vacant(entry) => { | 48 | Entry::Vacant(entry) => { |
57 | entry.insert(edit); | 49 | entry.insert(edit); |
58 | } | 50 | } |
59 | } | 51 | } |
60 | } | 52 | } |
53 | |||
54 | pub fn push_file_system_edit(&mut self, edit: FileSystemEdit) { | ||
55 | self.file_system_edits.push(edit); | ||
56 | } | ||
57 | |||
58 | pub fn get_source_edit(&self, file_id: FileId) -> Option<&TextEdit> { | ||
59 | self.source_file_edits.get(&file_id) | ||
60 | } | ||
61 | } | 61 | } |
62 | 62 | ||
63 | impl Extend<(FileId, TextEdit)> for SourceFileEdits { | 63 | impl Extend<(FileId, TextEdit)> for SourceChange { |
64 | fn extend<T: IntoIterator<Item = (FileId, TextEdit)>>(&mut self, iter: T) { | 64 | fn extend<T: IntoIterator<Item = (FileId, TextEdit)>>(&mut self, iter: T) { |
65 | iter.into_iter().for_each(|(file_id, edit)| self.insert(file_id, edit)); | 65 | iter.into_iter().for_each(|(file_id, edit)| self.insert_source_edit(file_id, edit)); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | impl From<SourceFileEdits> for SourceChange { | 69 | impl From<FxHashMap<FileId, TextEdit>> for SourceChange { |
70 | fn from(source_file_edits: SourceFileEdits) -> SourceChange { | 70 | fn from(source_file_edits: FxHashMap<FileId, TextEdit>) -> SourceChange { |
71 | SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } | 71 | SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } |
72 | } | 72 | } |
73 | } | 73 | } |
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs index 100331c37..bbb550ec9 100644 --- a/crates/rust-analyzer/src/cli/ssr.rs +++ b/crates/rust-analyzer/src/cli/ssr.rs | |||
@@ -12,7 +12,7 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> { | |||
12 | match_finder.add_rule(rule)?; | 12 | match_finder.add_rule(rule)?; |
13 | } | 13 | } |
14 | let edits = match_finder.edits(); | 14 | let edits = match_finder.edits(); |
15 | for (file_id, edit) in edits.edits { | 15 | for (file_id, edit) in edits { |
16 | if let Some(path) = vfs.file_path(file_id).as_path() { | 16 | if let Some(path) = vfs.file_path(file_id).as_path() { |
17 | let mut contents = db.file_text(file_id).to_string(); | 17 | let mut contents = db.file_text(file_id).to_string(); |
18 | edit.apply(&mut contents); | 18 | edit.apply(&mut contents); |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 839466e4f..1a4e0dd32 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -266,7 +266,7 @@ pub(crate) fn handle_on_type_formatting( | |||
266 | }; | 266 | }; |
267 | 267 | ||
268 | // This should be a single-file edit | 268 | // This should be a single-file edit |
269 | let (_, edit) = edit.source_file_edits.edits.into_iter().next().unwrap(); | 269 | let (_, edit) = edit.source_file_edits.into_iter().next().unwrap(); |
270 | 270 | ||
271 | let change = to_proto::text_edit_vec(&line_index, line_endings, edit); | 271 | let change = to_proto::text_edit_vec(&line_index, line_endings, edit); |
272 | Ok(Some(change)) | 272 | Ok(Some(change)) |
@@ -464,12 +464,10 @@ pub(crate) fn handle_will_rename_files( | |||
464 | 464 | ||
465 | // Drop file system edits since we're just renaming things on the same level | 465 | // Drop file system edits since we're just renaming things on the same level |
466 | let mut source_changes = source_changes.into_iter(); | 466 | let mut source_changes = source_changes.into_iter(); |
467 | let mut source_file_edits = | 467 | let mut source_change = source_changes.next().unwrap_or_default(); |
468 | source_changes.next().map_or_else(Default::default, |it| it.source_file_edits); | 468 | source_change.file_system_edits.clear(); |
469 | // no collect here because we want to merge text edits on same file ids | 469 | // no collect here because we want to merge text edits on same file ids |
470 | source_file_edits.extend(source_changes.map(|it| it.source_file_edits.edits).flatten()); | 470 | source_change.extend(source_changes.map(|it| it.source_file_edits).flatten()); |
471 | let source_change = SourceChange::from_edits(source_file_edits, Vec::new()); | ||
472 | |||
473 | let workspace_edit = to_proto::workspace_edit(&snap, source_change)?; | 471 | let workspace_edit = to_proto::workspace_edit(&snap, source_change)?; |
474 | Ok(Some(workspace_edit)) | 472 | Ok(Some(workspace_edit)) |
475 | } | 473 | } |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 34f510e73..dc67d19a7 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -698,7 +698,7 @@ pub(crate) fn snippet_workspace_edit( | |||
698 | let ops = snippet_text_document_ops(snap, op); | 698 | let ops = snippet_text_document_ops(snap, op); |
699 | document_changes.extend_from_slice(&ops); | 699 | document_changes.extend_from_slice(&ops); |
700 | } | 700 | } |
701 | for (file_id, edit) in source_change.source_file_edits.edits { | 701 | for (file_id, edit) in source_change.source_file_edits { |
702 | let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?; | 702 | let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?; |
703 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); | 703 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); |
704 | } | 704 | } |
diff --git a/crates/ssr/src/lib.rs b/crates/ssr/src/lib.rs index d99ebefb1..a97fc8bca 100644 --- a/crates/ssr/src/lib.rs +++ b/crates/ssr/src/lib.rs | |||
@@ -74,13 +74,11 @@ pub use crate::errors::SsrError; | |||
74 | pub use crate::matching::Match; | 74 | pub use crate::matching::Match; |
75 | use crate::matching::MatchFailureReason; | 75 | use crate::matching::MatchFailureReason; |
76 | use hir::Semantics; | 76 | use hir::Semantics; |
77 | use ide_db::{ | 77 | use ide_db::base_db::{FileId, FilePosition, FileRange}; |
78 | base_db::{FileId, FilePosition, FileRange}, | ||
79 | source_change::SourceFileEdits, | ||
80 | }; | ||
81 | use resolving::ResolvedRule; | 78 | use resolving::ResolvedRule; |
82 | use rustc_hash::FxHashMap; | 79 | use rustc_hash::FxHashMap; |
83 | use syntax::{ast, AstNode, SyntaxNode, TextRange}; | 80 | use syntax::{ast, AstNode, SyntaxNode, TextRange}; |
81 | use text_edit::TextEdit; | ||
84 | 82 | ||
85 | // A structured search replace rule. Create by calling `parse` on a str. | 83 | // A structured search replace rule. Create by calling `parse` on a str. |
86 | #[derive(Debug)] | 84 | #[derive(Debug)] |
@@ -161,7 +159,7 @@ impl<'db> MatchFinder<'db> { | |||
161 | } | 159 | } |
162 | 160 | ||
163 | /// Finds matches for all added rules and returns edits for all found matches. | 161 | /// Finds matches for all added rules and returns edits for all found matches. |
164 | pub fn edits(&self) -> SourceFileEdits { | 162 | pub fn edits(&self) -> FxHashMap<FileId, TextEdit> { |
165 | use ide_db::base_db::SourceDatabaseExt; | 163 | use ide_db::base_db::SourceDatabaseExt; |
166 | let mut matches_by_file = FxHashMap::default(); | 164 | let mut matches_by_file = FxHashMap::default(); |
167 | for m in self.matches().matches { | 165 | for m in self.matches().matches { |
@@ -171,21 +169,19 @@ impl<'db> MatchFinder<'db> { | |||
171 | .matches | 169 | .matches |
172 | .push(m); | 170 | .push(m); |
173 | } | 171 | } |
174 | SourceFileEdits { | 172 | matches_by_file |
175 | edits: matches_by_file | 173 | .into_iter() |
176 | .into_iter() | 174 | .map(|(file_id, matches)| { |
177 | .map(|(file_id, matches)| { | 175 | ( |
178 | ( | 176 | file_id, |
179 | file_id, | 177 | replacing::matches_to_edit( |
180 | replacing::matches_to_edit( | 178 | &matches, |
181 | &matches, | 179 | &self.sema.db.file_text(file_id), |
182 | &self.sema.db.file_text(file_id), | 180 | &self.rules, |
183 | &self.rules, | 181 | ), |
184 | ), | 182 | ) |
185 | ) | 183 | }) |
186 | }) | 184 | .collect() |
187 | .collect(), | ||
188 | } | ||
189 | } | 185 | } |
190 | 186 | ||
191 | /// Adds a search pattern. For use if you intend to only call `find_matches_in_file`. If you | 187 | /// Adds a search pattern. For use if you intend to only call `find_matches_in_file`. If you |
diff --git a/crates/ssr/src/matching.rs b/crates/ssr/src/matching.rs index 5888bf8f8..42d313f91 100644 --- a/crates/ssr/src/matching.rs +++ b/crates/ssr/src/matching.rs | |||
@@ -810,7 +810,7 @@ mod tests { | |||
810 | 810 | ||
811 | let edits = match_finder.edits(); | 811 | let edits = match_finder.edits(); |
812 | assert_eq!(edits.len(), 1); | 812 | assert_eq!(edits.len(), 1); |
813 | let edit = &edits.edits[&position.file_id]; | 813 | let edit = &edits[&position.file_id]; |
814 | let mut after = input.to_string(); | 814 | let mut after = input.to_string(); |
815 | edit.apply(&mut after); | 815 | edit.apply(&mut after); |
816 | assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }"); | 816 | assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }"); |
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs index 8ba783526..a3ea44f23 100644 --- a/crates/ssr/src/tests.rs +++ b/crates/ssr/src/tests.rs | |||
@@ -106,7 +106,7 @@ fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) { | |||
106 | // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters | 106 | // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters |
107 | // stuff. | 107 | // stuff. |
108 | let mut actual = db.file_text(position.file_id).to_string(); | 108 | let mut actual = db.file_text(position.file_id).to_string(); |
109 | edits.edits[&position.file_id].apply(&mut actual); | 109 | edits[&position.file_id].apply(&mut actual); |
110 | expected.assert_eq(&actual); | 110 | expected.assert_eq(&actual); |
111 | } | 111 | } |
112 | 112 | ||