aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
diff options
context:
space:
mode:
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.rs54
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 @@
1use ra_fmt::unwrap_trivial_block; 1use ra_fmt::unwrap_trivial_block;
2use ra_syntax::{ 2use 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
7use crate::{utils::TryEnum, Assist, AssistCtx, AssistId}; 11use 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// ```
35pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { 39pub(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> {
74mod tests { 76mod 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#"
84impl VariantData { 86impl 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#"
94impl VariantData { 96impl 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#"
110fn foo() { 112fn 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#"
120fn foo() { 122fn 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#"
138impl VariantData { 140impl 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 }
173use Option::*; 175use Option::*;
174 176
175fn foo(x: Option<i32>) { 177fn 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) }
203use Result::*; 205use Result::*;
204 206
205fn foo(x: Result<i32, ()>) { 207fn 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 }