diff options
Diffstat (limited to 'crates/ra_assists/src/handlers/replace_if_let_with_match.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/replace_if_let_with_match.rs | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs index 9841f6980..e016f51c3 100644 --- a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs | |||
@@ -1,10 +1,14 @@ | |||
1 | use ra_fmt::unwrap_trivial_block; | 1 | use ra_fmt::unwrap_trivial_block; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, edit::IndentLevel, make}, | 3 | ast::{ |
4 | self, | ||
5 | edit::{AstNodeEdit, IndentLevel}, | ||
6 | make, | ||
7 | }, | ||
4 | AstNode, | 8 | AstNode, |
5 | }; | 9 | }; |
6 | 10 | ||
7 | use crate::{utils::TryEnum, Assist, AssistCtx, AssistId}; | 11 | use crate::{utils::TryEnum, AssistContext, AssistId, Assists}; |
8 | 12 | ||
9 | // Assist: replace_if_let_with_match | 13 | // Assist: replace_if_let_with_match |
10 | // | 14 | // |
@@ -32,7 +36,7 @@ use crate::{utils::TryEnum, Assist, AssistCtx, AssistId}; | |||
32 | // } | 36 | // } |
33 | // } | 37 | // } |
34 | // ``` | 38 | // ``` |
35 | pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { | 39 | pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
36 | let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; | 40 | let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; |
37 | let cond = if_expr.condition()?; | 41 | let cond = if_expr.condition()?; |
38 | let pat = cond.pat()?; | 42 | let pat = cond.pat()?; |
@@ -43,29 +47,27 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
43 | ast::ElseBranch::IfExpr(_) => return None, | 47 | ast::ElseBranch::IfExpr(_) => return None, |
44 | }; | 48 | }; |
45 | 49 | ||
46 | let sema = ctx.sema; | 50 | let target = if_expr.syntax().text_range(); |
47 | ctx.add_assist(AssistId("replace_if_let_with_match"), "Replace with match", move |edit| { | 51 | acc.add(AssistId("replace_if_let_with_match"), "Replace with match", target, move |edit| { |
48 | let match_expr = { | 52 | let match_expr = { |
49 | let then_arm = { | 53 | let then_arm = { |
50 | let then_expr = unwrap_trivial_block(then_block); | 54 | let then_expr = unwrap_trivial_block(then_block); |
51 | make::match_arm(vec![pat.clone()], then_expr) | 55 | make::match_arm(vec![pat.clone()], then_expr) |
52 | }; | 56 | }; |
53 | let else_arm = { | 57 | let else_arm = { |
54 | let pattern = sema | 58 | let pattern = ctx |
59 | .sema | ||
55 | .type_of_pat(&pat) | 60 | .type_of_pat(&pat) |
56 | .and_then(|ty| TryEnum::from_ty(sema, &ty)) | 61 | .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty)) |
57 | .map(|it| it.sad_pattern()) | 62 | .map(|it| it.sad_pattern()) |
58 | .unwrap_or_else(|| make::placeholder_pat().into()); | 63 | .unwrap_or_else(|| make::placeholder_pat().into()); |
59 | let else_expr = unwrap_trivial_block(else_block); | 64 | let else_expr = unwrap_trivial_block(else_block); |
60 | make::match_arm(vec![pattern], else_expr) | 65 | make::match_arm(vec![pattern], else_expr) |
61 | }; | 66 | }; |
62 | make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])) | 67 | make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])) |
68 | .indent(IndentLevel::from_node(if_expr.syntax())) | ||
63 | }; | 69 | }; |
64 | 70 | ||
65 | let match_expr = IndentLevel::from_node(if_expr.syntax()).increase_indent(match_expr); | ||
66 | |||
67 | edit.target(if_expr.syntax().text_range()); | ||
68 | edit.set_cursor(if_expr.syntax().text_range().start()); | ||
69 | edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr); | 71 | edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr); |
70 | }) | 72 | }) |
71 | } | 73 | } |
@@ -74,13 +76,13 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
74 | mod tests { | 76 | mod tests { |
75 | use super::*; | 77 | use super::*; |
76 | 78 | ||
77 | use crate::helpers::{check_assist, check_assist_target}; | 79 | use crate::tests::{check_assist, check_assist_target}; |
78 | 80 | ||
79 | #[test] | 81 | #[test] |
80 | fn test_replace_if_let_with_match_unwraps_simple_expressions() { | 82 | fn test_replace_if_let_with_match_unwraps_simple_expressions() { |
81 | check_assist( | 83 | check_assist( |
82 | replace_if_let_with_match, | 84 | replace_if_let_with_match, |
83 | " | 85 | r#" |
84 | impl VariantData { | 86 | impl VariantData { |
85 | pub fn is_struct(&self) -> bool { | 87 | pub fn is_struct(&self) -> bool { |
86 | if <|>let VariantData::Struct(..) = *self { | 88 | if <|>let VariantData::Struct(..) = *self { |
@@ -89,16 +91,16 @@ impl VariantData { | |||
89 | false | 91 | false |
90 | } | 92 | } |
91 | } | 93 | } |
92 | } ", | 94 | } "#, |
93 | " | 95 | r#" |
94 | impl VariantData { | 96 | impl VariantData { |
95 | pub fn is_struct(&self) -> bool { | 97 | pub fn is_struct(&self) -> bool { |
96 | <|>match *self { | 98 | match *self { |
97 | VariantData::Struct(..) => true, | 99 | VariantData::Struct(..) => true, |
98 | _ => false, | 100 | _ => false, |
99 | } | 101 | } |
100 | } | 102 | } |
101 | } ", | 103 | } "#, |
102 | ) | 104 | ) |
103 | } | 105 | } |
104 | 106 | ||
@@ -106,7 +108,7 @@ impl VariantData { | |||
106 | fn test_replace_if_let_with_match_doesnt_unwrap_multiline_expressions() { | 108 | fn test_replace_if_let_with_match_doesnt_unwrap_multiline_expressions() { |
107 | check_assist( | 109 | check_assist( |
108 | replace_if_let_with_match, | 110 | replace_if_let_with_match, |
109 | " | 111 | r#" |
110 | fn foo() { | 112 | fn foo() { |
111 | if <|>let VariantData::Struct(..) = a { | 113 | if <|>let VariantData::Struct(..) = a { |
112 | bar( | 114 | bar( |
@@ -115,10 +117,10 @@ fn foo() { | |||
115 | } else { | 117 | } else { |
116 | false | 118 | false |
117 | } | 119 | } |
118 | } ", | 120 | } "#, |
119 | " | 121 | r#" |
120 | fn foo() { | 122 | fn foo() { |
121 | <|>match a { | 123 | match a { |
122 | VariantData::Struct(..) => { | 124 | VariantData::Struct(..) => { |
123 | bar( | 125 | bar( |
124 | 123 | 126 | 123 |
@@ -126,7 +128,7 @@ fn foo() { | |||
126 | } | 128 | } |
127 | _ => false, | 129 | _ => false, |
128 | } | 130 | } |
129 | } ", | 131 | } "#, |
130 | ) | 132 | ) |
131 | } | 133 | } |
132 | 134 | ||
@@ -134,7 +136,7 @@ fn foo() { | |||
134 | fn replace_if_let_with_match_target() { | 136 | fn replace_if_let_with_match_target() { |
135 | check_assist_target( | 137 | check_assist_target( |
136 | replace_if_let_with_match, | 138 | replace_if_let_with_match, |
137 | " | 139 | r#" |
138 | impl VariantData { | 140 | impl VariantData { |
139 | pub fn is_struct(&self) -> bool { | 141 | pub fn is_struct(&self) -> bool { |
140 | if <|>let VariantData::Struct(..) = *self { | 142 | if <|>let VariantData::Struct(..) = *self { |
@@ -143,7 +145,7 @@ impl VariantData { | |||
143 | false | 145 | false |
144 | } | 146 | } |
145 | } | 147 | } |
146 | } ", | 148 | } "#, |
147 | "if let VariantData::Struct(..) = *self { | 149 | "if let VariantData::Struct(..) = *self { |
148 | true | 150 | true |
149 | } else { | 151 | } else { |
@@ -173,7 +175,7 @@ enum Option<T> { Some(T), None } | |||
173 | use Option::*; | 175 | use Option::*; |
174 | 176 | ||
175 | fn foo(x: Option<i32>) { | 177 | fn foo(x: Option<i32>) { |
176 | <|>match x { | 178 | match x { |
177 | Some(x) => println!("{}", x), | 179 | Some(x) => println!("{}", x), |
178 | None => println!("none"), | 180 | None => println!("none"), |
179 | } | 181 | } |
@@ -203,7 +205,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
203 | use Result::*; | 205 | use Result::*; |
204 | 206 | ||
205 | fn foo(x: Result<i32, ()>) { | 207 | fn foo(x: Result<i32, ()>) { |
206 | <|>match x { | 208 | match x { |
207 | Ok(x) => println!("{}", x), | 209 | Ok(x) => println!("{}", x), |
208 | Err(_) => println!("none"), | 210 | Err(_) => println!("none"), |
209 | } | 211 | } |