From 1316422a7c2ef26e9da78fa23f170407b1cb39bb Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Mon, 28 Dec 2020 13:41:15 +0000 Subject: Add diagnostic for filter_map followed by next --- crates/ide/src/diagnostics.rs | 3 +++ crates/ide/src/diagnostics/fixes.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'crates/ide') 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( .on::(|d| { res.borrow_mut().push(warning_with_fix(d, &sema)); }) + .on::(|d| { + res.borrow_mut().push(warning_with_fix(d, &sema)); + }) .on::(|d| { // If there's inactive code somewhere in a macro, don't propagate to the call-site. 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..eafbac43a 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -4,7 +4,7 @@ use hir::{ db::AstDatabase, diagnostics::{ Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, - RemoveThisSemicolon, UnresolvedModule, + RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, UnresolvedModule, }, HasSource, HirDisplay, InFile, Semantics, VariantDef, }; @@ -144,6 +144,37 @@ impl DiagnosticWithFix for IncorrectCase { } } +// Bugs: +// * Action is applicable for both iter() and filter_map() rows +// * Action deletes the entire method chain +impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { + fn fix(&self, sema: &Semantics) -> Option { + let root = sema.db.parse_or_expand(self.file)?; + + let next_expr = self.next_expr.to_node(&root); + let next_expr_range = next_expr.syntax().text_range(); + + let filter_map_expr = self.filter_map_expr.to_node(&root); + let filter_map_expr_range = filter_map_expr.syntax().text_range(); + + let edit = TextEdit::delete(next_expr_range); + + // This is the entire method chain, including the array literal + eprintln!("NEXT EXPR: {:#?}", next_expr); + // This is the entire method chain except for the final next() + eprintln!("FILTER MAP EXPR: {:#?}", filter_map_expr); + + let source_change = + SourceFileEdit { file_id: self.file.original_file(sema.db), edit }.into(); + + Some(Fix::new( + "Replace filter_map(..).next() with find_map()", + source_change, + filter_map_expr_range, + )) + } +} + fn missing_record_expr_field_fix( sema: &Semantics, usage_file_id: FileId, -- cgit v1.2.3 From 1ff860b93c972e0f8d3a8ee582c255fa59e9b284 Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Wed, 30 Dec 2020 15:46:05 +0000 Subject: Implement fix, add tests --- crates/ide/src/diagnostics/fixes.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index eafbac43a..7bbf1d8c7 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -1,5 +1,6 @@ //! Provides a way to attach fixes to the diagnostics. //! The same module also has all curret custom fixes for the diagnostics implemented. +use ast::MethodCallExpr; use hir::{ db::AstDatabase, diagnostics::{ @@ -13,11 +14,7 @@ use ide_db::{ source_change::{FileSystemEdit, SourceChange}, RootDatabase, }; -use syntax::{ - algo, - ast::{self, edit::IndentLevel, make}, - AstNode, -}; +use syntax::{AstNode, TextRange, algo, ast::{self, ArgList, edit::IndentLevel, make}}; use text_edit::TextEdit; use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePosition}; @@ -144,25 +141,21 @@ impl DiagnosticWithFix for IncorrectCase { } } -// Bugs: -// * Action is applicable for both iter() and filter_map() rows -// * Action deletes the entire method chain impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { fn fix(&self, sema: &Semantics) -> Option { let root = sema.db.parse_or_expand(self.file)?; - let next_expr = self.next_expr.to_node(&root); - let next_expr_range = next_expr.syntax().text_range(); + let next_call = MethodCallExpr::cast(next_expr.syntax().clone())?; - let filter_map_expr = self.filter_map_expr.to_node(&root); - let filter_map_expr_range = filter_map_expr.syntax().text_range(); + let filter_map_call = MethodCallExpr::cast(next_call.receiver()?.syntax().clone())?; + let filter_map_name_range = filter_map_call.name_ref()?.ident_token()?.text_range(); + let filter_map_args = filter_map_call.syntax().children().find_map(ArgList::cast)?; - let edit = TextEdit::delete(next_expr_range); + let range_to_replace = TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); + let replacement = format!("find_map{}", filter_map_args.syntax().text()); + let trigger_range = next_expr.syntax().text_range(); - // This is the entire method chain, including the array literal - eprintln!("NEXT EXPR: {:#?}", next_expr); - // This is the entire method chain except for the final next() - eprintln!("FILTER MAP EXPR: {:#?}", filter_map_expr); + let edit = TextEdit::replace(range_to_replace, replacement); let source_change = SourceFileEdit { file_id: self.file.original_file(sema.db), edit }.into(); @@ -170,7 +163,7 @@ impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { Some(Fix::new( "Replace filter_map(..).next() with find_map()", source_change, - filter_map_expr_range, + trigger_range, )) } } -- cgit v1.2.3 From 449ced4d218f413e152785fb81d161a6389974f7 Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Wed, 30 Dec 2020 15:52:36 +0000 Subject: cargo fmt --- crates/ide/src/diagnostics/fixes.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 7bbf1d8c7..a73c0778b 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -14,7 +14,11 @@ use ide_db::{ source_change::{FileSystemEdit, SourceChange}, RootDatabase, }; -use syntax::{AstNode, TextRange, algo, ast::{self, ArgList, edit::IndentLevel, make}}; +use syntax::{ + algo, + ast::{self, edit::IndentLevel, make, ArgList}, + AstNode, TextRange, +}; use text_edit::TextEdit; use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePosition}; @@ -151,7 +155,8 @@ impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { let filter_map_name_range = filter_map_call.name_ref()?.ident_token()?.text_range(); let filter_map_args = filter_map_call.syntax().children().find_map(ArgList::cast)?; - let range_to_replace = TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); + let range_to_replace = + TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); let replacement = format!("find_map{}", filter_map_args.syntax().text()); let trigger_range = next_expr.syntax().text_range(); -- cgit v1.2.3 From e62e4ed148021a80b3a4672dab10b828fbd712ee Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Wed, 30 Dec 2020 16:14:35 +0000 Subject: Address review comments --- crates/ide/src/diagnostics/fixes.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index a73c0778b..5828ea35a 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -1,6 +1,5 @@ //! Provides a way to attach fixes to the diagnostics. //! The same module also has all curret custom fixes for the diagnostics implemented. -use ast::MethodCallExpr; use hir::{ db::AstDatabase, diagnostics::{ @@ -14,11 +13,7 @@ use ide_db::{ source_change::{FileSystemEdit, SourceChange}, RootDatabase, }; -use syntax::{ - algo, - ast::{self, edit::IndentLevel, make, ArgList}, - AstNode, TextRange, -}; +use syntax::{AstNode, TextRange, algo, ast::{self, ArgListOwner, edit::IndentLevel, make}}; use text_edit::TextEdit; use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePosition}; @@ -149,11 +144,11 @@ impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { fn fix(&self, sema: &Semantics) -> Option { let root = sema.db.parse_or_expand(self.file)?; let next_expr = self.next_expr.to_node(&root); - let next_call = MethodCallExpr::cast(next_expr.syntax().clone())?; + let next_call = ast::MethodCallExpr::cast(next_expr.syntax().clone())?; - let filter_map_call = MethodCallExpr::cast(next_call.receiver()?.syntax().clone())?; + let filter_map_call = ast::MethodCallExpr::cast(next_call.receiver()?.syntax().clone())?; let filter_map_name_range = filter_map_call.name_ref()?.ident_token()?.text_range(); - let filter_map_args = filter_map_call.syntax().children().find_map(ArgList::cast)?; + let filter_map_args = filter_map_call.arg_list()?; let range_to_replace = TextRange::new(filter_map_name_range.start(), next_expr.syntax().text_range().end()); -- cgit v1.2.3 From 920e57bd153fdafeddb1dc34a11c6ef05ace2f70 Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Wed, 30 Dec 2020 16:15:00 +0000 Subject: cargo fmt --- crates/ide/src/diagnostics/fixes.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 5828ea35a..1f112c5b8 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -13,7 +13,11 @@ use ide_db::{ source_change::{FileSystemEdit, SourceChange}, RootDatabase, }; -use syntax::{AstNode, TextRange, algo, ast::{self, ArgListOwner, edit::IndentLevel, make}}; +use syntax::{ + algo, + ast::{self, edit::IndentLevel, make, ArgListOwner}, + AstNode, TextRange, +}; use text_edit::TextEdit; use crate::{diagnostics::Fix, references::rename::rename_with_semantics, FilePosition}; -- cgit v1.2.3 From db6dda94a39534bbf20da844a4f221c3d14509c4 Mon Sep 17 00:00:00 2001 From: Phil Ellison Date: Sat, 23 Jan 2021 07:54:45 +0000 Subject: Remove use of SourceFileEdit --- crates/ide/src/diagnostics/fixes.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index 1f112c5b8..cbfc66ab3 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs @@ -161,8 +161,7 @@ impl DiagnosticWithFix for ReplaceFilterMapNextWithFindMap { let edit = TextEdit::replace(range_to_replace, replacement); - let source_change = - SourceFileEdit { file_id: 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( "Replace filter_map(..).next() with find_map()", -- cgit v1.2.3