diff options
| author | Aleksey Kladov <[email protected]> | 2020-04-29 09:38:18 +0100 |
|---|---|---|
| committer | Aleksey Kladov <[email protected]> | 2020-04-29 09:38:51 +0100 |
| commit | 73bef854ab854ab1a289944966444453e6f4aadf (patch) | |
| tree | bc136f0d2f5b733ffc54714e4096f35863bfa3f1 /crates | |
| parent | 549ce9a9cf25efa3eba6549f96b2e43bc640faa9 (diff) | |
Move shared assist code to utils
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/ra_assists/src/handlers/replace_let_with_if_let.rs | 16 | ||||
| -rw-r--r-- | crates/ra_assists/src/handlers/replace_unwrap_with_match.rs | 52 | ||||
| -rw-r--r-- | crates/ra_assists/src/utils.rs | 15 |
3 files changed, 35 insertions, 48 deletions
diff --git a/crates/ra_assists/src/handlers/replace_let_with_if_let.rs b/crates/ra_assists/src/handlers/replace_let_with_if_let.rs index bdbaae389..fb134f677 100644 --- a/crates/ra_assists/src/handlers/replace_let_with_if_let.rs +++ b/crates/ra_assists/src/handlers/replace_let_with_if_let.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | use std::iter::once; | 1 | use std::iter::once; |
| 2 | 2 | ||
| 3 | use hir::Adt; | ||
| 4 | use ra_syntax::{ | 3 | use ra_syntax::{ |
| 5 | ast::{ | 4 | ast::{ |
| 6 | self, | 5 | self, |
| @@ -12,6 +11,7 @@ use ra_syntax::{ | |||
| 12 | 11 | ||
| 13 | use crate::{ | 12 | use crate::{ |
| 14 | assist_ctx::{Assist, AssistCtx}, | 13 | assist_ctx::{Assist, AssistCtx}, |
| 14 | utils::happy_try_variant, | ||
| 15 | AssistId, | 15 | AssistId, |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| @@ -45,20 +45,10 @@ pub(crate) fn replace_let_with_if_let(ctx: AssistCtx) -> Option<Assist> { | |||
| 45 | let init = let_stmt.initializer()?; | 45 | let init = let_stmt.initializer()?; |
| 46 | let original_pat = let_stmt.pat()?; | 46 | let original_pat = let_stmt.pat()?; |
| 47 | let ty = ctx.sema.type_of_expr(&init)?; | 47 | let ty = ctx.sema.type_of_expr(&init)?; |
| 48 | let enum_ = match ty.as_adt() { | 48 | let happy_variant = happy_try_variant(ctx.sema, &ty); |
| 49 | Some(Adt::Enum(it)) => it, | ||
| 50 | _ => return None, | ||
| 51 | }; | ||
| 52 | let happy_case = | ||
| 53 | [("Result", "Ok"), ("Option", "Some")].iter().find_map(|(known_type, happy_case)| { | ||
| 54 | if &enum_.name(ctx.db).to_string() == known_type { | ||
| 55 | return Some(happy_case); | ||
| 56 | } | ||
| 57 | None | ||
| 58 | }); | ||
| 59 | 49 | ||
| 60 | ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| { | 50 | ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| { |
| 61 | let with_placeholder: ast::Pat = match happy_case { | 51 | let with_placeholder: ast::Pat = match happy_variant { |
| 62 | None => make::placeholder_pat().into(), | 52 | None => make::placeholder_pat().into(), |
| 63 | Some(var_name) => make::tuple_struct_pat( | 53 | Some(var_name) => make::tuple_struct_pat( |
| 64 | make::path_unqualified(make::path_segment(make::name_ref(var_name))), | 54 | make::path_unqualified(make::path_segment(make::name_ref(var_name))), |
diff --git a/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs index 62cb7a763..89211b44a 100644 --- a/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs +++ b/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs | |||
| @@ -1,12 +1,11 @@ | |||
| 1 | use std::iter; | 1 | use std::iter; |
| 2 | 2 | ||
| 3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
| 4 | ast::{self, make}, | 4 | ast::{self, edit::IndentLevel, make}, |
| 5 | AstNode, | 5 | AstNode, |
| 6 | }; | 6 | }; |
| 7 | 7 | ||
| 8 | use crate::{Assist, AssistCtx, AssistId}; | 8 | use crate::{utils::happy_try_variant, Assist, AssistCtx, AssistId}; |
| 9 | use ast::edit::IndentLevel; | ||
| 10 | 9 | ||
| 11 | // Assist: replace_unwrap_with_match | 10 | // Assist: replace_unwrap_with_match |
| 12 | // | 11 | // |
| @@ -38,42 +37,27 @@ pub(crate) fn replace_unwrap_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
| 38 | } | 37 | } |
| 39 | let caller = method_call.expr()?; | 38 | let caller = method_call.expr()?; |
| 40 | let ty = ctx.sema.type_of_expr(&caller)?; | 39 | let ty = ctx.sema.type_of_expr(&caller)?; |
| 40 | let happy_variant = happy_try_variant(ctx.sema, &ty)?; | ||
| 41 | 41 | ||
| 42 | let type_name = ty.as_adt()?.name(ctx.sema.db).to_string(); | 42 | ctx.add_assist(AssistId("replace_unwrap_with_match"), "Replace unwrap with match", |edit| { |
| 43 | let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant))); | ||
| 44 | let it = make::bind_pat(make::name("a")).into(); | ||
| 45 | let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into(); | ||
| 43 | 46 | ||
| 44 | for (unwrap_type, variant_name) in [("Result", "Ok"), ("Option", "Some")].iter() { | 47 | let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a"))); |
| 45 | if &type_name == unwrap_type { | 48 | let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path)); |
| 46 | return ctx.add_assist( | ||
| 47 | AssistId("replace_unwrap_with_match"), | ||
| 48 | "Replace unwrap with match", | ||
| 49 | |edit| { | ||
| 50 | let ok_path = | ||
| 51 | make::path_unqualified(make::path_segment(make::name_ref(variant_name))); | ||
| 52 | let it = make::bind_pat(make::name("a")).into(); | ||
| 53 | let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into(); | ||
| 54 | 49 | ||
| 55 | let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a"))); | 50 | let unreachable_call = make::unreachable_macro_call().into(); |
| 56 | let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path)); | 51 | let err_arm = make::match_arm(iter::once(make::placeholder_pat().into()), unreachable_call); |
| 57 | 52 | ||
| 58 | let unreachable_call = make::unreachable_macro_call().into(); | 53 | let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]); |
| 59 | let err_arm = make::match_arm( | 54 | let match_expr = make::expr_match(caller.clone(), match_arm_list); |
| 60 | iter::once(make::placeholder_pat().into()), | 55 | let match_expr = IndentLevel::from_node(method_call.syntax()).increase_indent(match_expr); |
| 61 | unreachable_call, | ||
| 62 | ); | ||
| 63 | 56 | ||
| 64 | let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]); | 57 | edit.target(method_call.syntax().text_range()); |
| 65 | let match_expr = make::expr_match(caller.clone(), match_arm_list); | 58 | edit.set_cursor(caller.syntax().text_range().start()); |
| 66 | let match_expr = | 59 | edit.replace_ast::<ast::Expr>(method_call.into(), match_expr); |
| 67 | IndentLevel::from_node(method_call.syntax()).increase_indent(match_expr); | 60 | }) |
| 68 | |||
| 69 | edit.target(method_call.syntax().text_range()); | ||
| 70 | edit.set_cursor(caller.syntax().text_range().start()); | ||
| 71 | edit.replace_ast::<ast::Expr>(method_call.into(), match_expr); | ||
| 72 | }, | ||
| 73 | ); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | None | ||
| 77 | } | 61 | } |
| 78 | 62 | ||
| 79 | #[cfg(test)] | 63 | #[cfg(test)] |
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs index 3d6c59bda..316c8b20f 100644 --- a/crates/ra_assists/src/utils.rs +++ b/crates/ra_assists/src/utils.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | //! Assorted functions shared by several assists. | 1 | //! Assorted functions shared by several assists. |
| 2 | pub(crate) mod insert_use; | 2 | pub(crate) mod insert_use; |
| 3 | 3 | ||
| 4 | use hir::Semantics; | 4 | use hir::{Adt, Semantics, Type}; |
| 5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
| 6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
| 7 | ast::{self, make, NameOwner}, | 7 | ast::{self, make, NameOwner}, |
| @@ -99,3 +99,16 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> { | |||
| 99 | _ => None, | 99 | _ => None, |
| 100 | } | 100 | } |
| 101 | } | 101 | } |
| 102 | |||
| 103 | pub(crate) fn happy_try_variant(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<&'static str> { | ||
| 104 | let enum_ = match ty.as_adt() { | ||
| 105 | Some(Adt::Enum(it)) => it, | ||
| 106 | _ => return None, | ||
| 107 | }; | ||
| 108 | [("Result", "Ok"), ("Option", "Some")].iter().find_map(|(known_type, happy_case)| { | ||
| 109 | if &enum_.name(sema.db).to_string() == known_type { | ||
| 110 | return Some(*happy_case); | ||
| 111 | } | ||
| 112 | None | ||
| 113 | }) | ||
| 114 | } | ||
