aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/move_guard.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/move_guard.rs')
-rw-r--r--crates/ra_assists/src/handlers/move_guard.rs54
1 files changed, 22 insertions, 32 deletions
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
index d5ccdd91c..7edcf0748 100644
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ b/crates/ra_assists/src/handlers/move_guard.rs
@@ -1,10 +1,9 @@
1use ra_syntax::{ 1use ra_syntax::{
2 ast, 2 ast::{AstNode, IfExpr, MatchArm},
3 ast::{AstNode, AstToken, IfExpr, MatchArm}, 3 SyntaxKind::WHITESPACE,
4 TextSize,
5}; 4};
6 5
7use crate::{Assist, AssistCtx, AssistId}; 6use crate::{AssistContext, AssistId, Assists};
8 7
9// Assist: move_guard_to_arm_body 8// Assist: move_guard_to_arm_body
10// 9//
@@ -31,7 +30,7 @@ use crate::{Assist, AssistCtx, AssistId};
31// } 30// }
32// } 31// }
33// ``` 32// ```
34pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> { 33pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
35 let match_arm = ctx.find_node_at_offset::<MatchArm>()?; 34 let match_arm = ctx.find_node_at_offset::<MatchArm>()?;
36 let guard = match_arm.guard()?; 35 let guard = match_arm.guard()?;
37 let space_before_guard = guard.syntax().prev_sibling_or_token(); 36 let space_before_guard = guard.syntax().prev_sibling_or_token();
@@ -40,26 +39,17 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> {
40 let arm_expr = match_arm.expr()?; 39 let arm_expr = match_arm.expr()?;
41 let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text()); 40 let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text());
42 41
43 ctx.add_assist(AssistId("move_guard_to_arm_body"), "Move guard to arm body", |edit| { 42 let target = guard.syntax().text_range();
44 edit.target(guard.syntax().text_range()); 43 acc.add(AssistId("move_guard_to_arm_body"), "Move guard to arm body", target, |edit| {
45 let offseting_amount = match space_before_guard.and_then(|it| it.into_token()) { 44 match space_before_guard {
46 Some(tok) => { 45 Some(element) if element.kind() == WHITESPACE => {
47 if ast::Whitespace::cast(tok.clone()).is_some() { 46 edit.delete(element.text_range());
48 let ele = tok.text_range();
49 edit.delete(ele);
50 ele.len()
51 } else {
52 TextSize::from(0)
53 }
54 } 47 }
55 _ => TextSize::from(0), 48 _ => (),
56 }; 49 };
57 50
58 edit.delete(guard.syntax().text_range()); 51 edit.delete(guard.syntax().text_range());
59 edit.replace_node_and_indent(arm_expr.syntax(), buf); 52 edit.replace_node_and_indent(arm_expr.syntax(), buf);
60 edit.set_cursor(
61 arm_expr.syntax().text_range().start() + TextSize::from(3) - offseting_amount,
62 );
63 }) 53 })
64} 54}
65 55
@@ -88,7 +78,7 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> {
88// } 78// }
89// } 79// }
90// ``` 80// ```
91pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> { 81pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
92 let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?; 82 let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?;
93 let match_pat = match_arm.pat()?; 83 let match_pat = match_arm.pat()?;
94 84
@@ -108,14 +98,15 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
108 98
109 let buf = format!(" if {}", cond.syntax().text()); 99 let buf = format!(" if {}", cond.syntax().text());
110 100
111 ctx.add_assist( 101 let target = if_expr.syntax().text_range();
102 acc.add(
112 AssistId("move_arm_cond_to_match_guard"), 103 AssistId("move_arm_cond_to_match_guard"),
113 "Move condition to match guard", 104 "Move condition to match guard",
105 target,
114 |edit| { 106 |edit| {
115 edit.target(if_expr.syntax().text_range()); 107 let then_only_expr = then_block.statements().next().is_none();
116 let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none();
117 108
118 match &then_block.block().and_then(|it| it.expr()) { 109 match &then_block.expr() {
119 Some(then_expr) if then_only_expr => { 110 Some(then_expr) if then_only_expr => {
120 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text()) 111 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text())
121 } 112 }
@@ -123,7 +114,6 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
123 } 114 }
124 115
125 edit.insert(match_pat.syntax().text_range().end(), buf); 116 edit.insert(match_pat.syntax().text_range().end(), buf);
126 edit.set_cursor(match_pat.syntax().text_range().end() + TextSize::from(1));
127 }, 117 },
128 ) 118 )
129} 119}
@@ -132,7 +122,7 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
132mod tests { 122mod tests {
133 use super::*; 123 use super::*;
134 124
135 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target}; 125 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
136 126
137 #[test] 127 #[test]
138 fn move_guard_to_arm_body_target() { 128 fn move_guard_to_arm_body_target() {
@@ -171,7 +161,7 @@ mod tests {
171 let t = 'a'; 161 let t = 'a';
172 let chars = "abcd"; 162 let chars = "abcd";
173 match t { 163 match t {
174 '\r' => if chars.clone().next() == Some('\n') { <|>false }, 164 '\r' => if chars.clone().next() == Some('\n') { false },
175 _ => true 165 _ => true
176 } 166 }
177 } 167 }
@@ -194,7 +184,7 @@ mod tests {
194 r#" 184 r#"
195 fn f() { 185 fn f() {
196 match x { 186 match x {
197 y @ 4 | y @ 5 => if y > 5 { <|>true }, 187 y @ 4 | y @ 5 => if y > 5 { true },
198 _ => false 188 _ => false
199 } 189 }
200 } 190 }
@@ -221,7 +211,7 @@ mod tests {
221 let t = 'a'; 211 let t = 'a';
222 let chars = "abcd"; 212 let chars = "abcd";
223 match t { 213 match t {
224 '\r' <|>if chars.clone().next() == Some('\n') => false, 214 '\r' if chars.clone().next() == Some('\n') => false,
225 _ => true 215 _ => true
226 } 216 }
227 } 217 }
@@ -265,7 +255,7 @@ mod tests {
265 let t = 'a'; 255 let t = 'a';
266 let chars = "abcd"; 256 let chars = "abcd";
267 match t { 257 match t {
268 '\r' <|>if chars.clone().next().is_some() => { }, 258 '\r' if chars.clone().next().is_some() => { },
269 _ => true 259 _ => true
270 } 260 }
271 } 261 }
@@ -295,7 +285,7 @@ mod tests {
295 let mut t = 'a'; 285 let mut t = 'a';
296 let chars = "abcd"; 286 let chars = "abcd";
297 match t { 287 match t {
298 '\r' <|>if chars.clone().next().is_some() => { 288 '\r' if chars.clone().next().is_some() => {
299 t = 'e'; 289 t = 'e';
300 false 290 false
301 }, 291 },