diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/fixes.rs | 33 |
2 files changed, 33 insertions, 3 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index b35bc2bae..8607139ba 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -136,6 +136,9 @@ pub(crate) fn diagnostics( | |||
136 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | 136 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { |
137 | res.borrow_mut().push(warning_with_fix(d, &sema)); | 137 | res.borrow_mut().push(warning_with_fix(d, &sema)); |
138 | }) | 138 | }) |
139 | .on::<hir::diagnostics::ReplaceFilterMapNextWithFindMap, _>(|d| { | ||
140 | res.borrow_mut().push(warning_with_fix(d, &sema)); | ||
141 | }) | ||
139 | .on::<hir::diagnostics::InactiveCode, _>(|d| { | 142 | .on::<hir::diagnostics::InactiveCode, _>(|d| { |
140 | // If there's inactive code somewhere in a macro, don't propagate to the call-site. | 143 | // If there's inactive code somewhere in a macro, don't propagate to the call-site. |
141 | if d.display_source().file_id.expansion_info(db).is_some() { | 144 | if d.display_source().file_id.expansion_info(db).is_some() { |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 579d5a308..cbfc66ab3 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -4,7 +4,7 @@ use hir::{ | |||
4 | db::AstDatabase, | 4 | db::AstDatabase, |
5 | diagnostics::{ | 5 | diagnostics::{ |
6 | Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, | 6 | Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, |
7 | RemoveThisSemicolon, UnresolvedModule, | 7 | RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, UnresolvedModule, |
8 | }, | 8 | }, |
9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, | 9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, |
10 | }; | 10 | }; |
@@ -15,8 +15,8 @@ use ide_db::{ | |||
15 | }; | 15 | }; |
16 | use syntax::{ | 16 | use syntax::{ |
17 | algo, | 17 | algo, |
18 | ast::{self, edit::IndentLevel, make}, | 18 | ast::{self, edit::IndentLevel, make, ArgListOwner}, |
19 | AstNode, | 19 | AstNode, TextRange, |
20 | }; | 20 | }; |
21 | use text_edit::TextEdit; | 21 | use text_edit::TextEdit; |
22 | 22 | ||
@@ -144,6 +144,33 @@ impl DiagnosticWithFix for IncorrectCase { | |||
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { | ||
148 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> { | ||
149 | let root = sema.db.parse_or_expand(self.file)?; | ||
150 | let next_expr = self.next_expr.to_node(&root); | ||
151 | let next_call = ast::MethodCallExpr::cast(next_expr.syntax().clone())?; | ||
152 | |||
153 | let filter_map_call = ast::MethodCallExpr::cast(next_call.receiver()?.syntax().clone())?; | ||
154 | let filter_map_name_range = filter_map_call.name_ref()?.ident_token()?.text_range(); | ||
155 | let filter_map_args = filter_map_call.arg_list()?; | ||
156 | |||
157 | let range_to_replace = | ||
158 | TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); | ||
159 | let replacement = format!("find_map{}", filter_map_args.syntax().text()); | ||
160 | let trigger_range = next_expr.syntax().text_range(); | ||
161 | |||
162 | let edit = TextEdit::replace(range_to_replace, replacement); | ||
163 | |||
164 | let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit); | ||
165 | |||
166 | Some(Fix::new( | ||
167 | "Replace filter_map(..).next() with find_map()", | ||
168 | source_change, | ||
169 | trigger_range, | ||
170 | )) | ||
171 | } | ||
172 | } | ||
173 | |||
147 | fn missing_record_expr_field_fix( | 174 | fn missing_record_expr_field_fix( |
148 | sema: &Semantics<RootDatabase>, | 175 | sema: &Semantics<RootDatabase>, |
149 | usage_file_id: FileId, | 176 | usage_file_id: FileId, |