Skip to content

Commit 0bf57c2

Browse files
committed
add assist to move arm condition to match guard
1 parent 99ad614 commit 0bf57c2

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

crates/ra_assists/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis
120120
add_missing_impl_members::add_missing_default_members,
121121
inline_local_variable::inline_local_varialbe,
122122
move_guard_to_arm_body_and_back::move_guard_to_arm_body,
123+
move_guard_to_arm_body_and_back::move_arm_cond_to_match_guard,
123124
]
124125
}
125126

crates/ra_assists/src/move_guard_to_arm_body_and_back.rs

+150-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use hir::db::HirDatabase;
22
use ra_syntax::{
33
TextUnit,
44
SyntaxElement,
5-
ast::{MatchArm, AstNode, AstToken},
5+
ast::{MatchArm, AstNode, AstToken, IfExpr},
66
ast,
77
};
88

@@ -39,6 +39,41 @@ pub(crate) fn move_guard_to_arm_body(mut ctx: AssistCtx<impl HirDatabase>) -> Op
3939
ctx.build()
4040
}
4141

42+
pub(crate) fn move_arm_cond_to_match_guard(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
43+
let match_arm: &MatchArm = ctx.node_at_offset::<MatchArm>()?;
44+
let last_match_pat = match_arm.pats().last()?;
45+
46+
let arm_body = match_arm.expr()?;
47+
let if_expr: &IfExpr = IfExpr::cast(arm_body.syntax())?;
48+
let cond = if_expr.condition()?;
49+
let then_block = if_expr.then_branch()?;
50+
51+
// Not support if with else branch
52+
if let Some(_) = if_expr.else_branch() {
53+
return None;
54+
}
55+
56+
let buf = format!(" if {}", cond.syntax().text());
57+
58+
ctx.add_action(
59+
AssistId("move_arm_cond_to_match_guard"),
60+
"move condition to match guard",
61+
|edit| {
62+
edit.target(last_match_pat.syntax().range());
63+
64+
if then_block.statements().next().is_none() && then_block.expr().is_some() {
65+
edit.replace(if_expr.syntax().range(), then_block.expr().unwrap().syntax().text());
66+
} else {
67+
edit.replace(if_expr.syntax().range(), then_block.syntax().text());
68+
}
69+
70+
edit.insert(last_match_pat.syntax().range().end(), buf);
71+
edit.set_cursor(last_match_pat.syntax().range().end() + TextUnit::from(1));
72+
},
73+
);
74+
ctx.build()
75+
}
76+
4277
#[cfg(test)]
4378
mod tests {
4479
use super::*;
@@ -112,4 +147,118 @@ mod tests {
112147
"#,
113148
);
114149
}
150+
151+
#[test]
152+
fn move_arm_cond_to_match_guard_works() {
153+
check_assist(
154+
move_arm_cond_to_match_guard,
155+
r#"
156+
fn f() {
157+
let t = 'a';
158+
let chars = "abcd";
159+
match t {
160+
'\r' => if chars.clone().next() == Some('\n') { <|>false },
161+
_ => true
162+
}
163+
}
164+
"#,
165+
r#"
166+
fn f() {
167+
let t = 'a';
168+
let chars = "abcd";
169+
match t {
170+
'\r' <|>if chars.clone().next() == Some('\n') => false,
171+
_ => true
172+
}
173+
}
174+
"#,
175+
);
176+
}
177+
178+
#[test]
179+
fn move_arm_cond_to_match_guard_if_let_works() {
180+
check_assist(
181+
move_arm_cond_to_match_guard,
182+
r#"
183+
fn f() {
184+
let t = 'a';
185+
let chars = "abcd";
186+
match t {
187+
'\r' => if let Some(_) = chars.clone().next() { <|>false },
188+
_ => true
189+
}
190+
}
191+
"#,
192+
r#"
193+
fn f() {
194+
let t = 'a';
195+
let chars = "abcd";
196+
match t {
197+
'\r' <|>if let Some(_) = chars.clone().next() => false,
198+
_ => true
199+
}
200+
}
201+
"#,
202+
);
203+
}
204+
205+
#[test]
206+
fn move_arm_cond_to_match_guard_if_empty_body_works() {
207+
check_assist(
208+
move_arm_cond_to_match_guard,
209+
r#"
210+
fn f() {
211+
let t = 'a';
212+
let chars = "abcd";
213+
match t {
214+
'\r' => if let Some(_) = chars.clone().next() { <|> },
215+
_ => true
216+
}
217+
}
218+
"#,
219+
r#"
220+
fn f() {
221+
let t = 'a';
222+
let chars = "abcd";
223+
match t {
224+
'\r' <|>if let Some(_) = chars.clone().next() => { },
225+
_ => true
226+
}
227+
}
228+
"#,
229+
);
230+
}
231+
232+
#[test]
233+
fn move_arm_cond_to_match_guard_if_multiline_body_works() {
234+
check_assist(
235+
move_arm_cond_to_match_guard,
236+
r#"
237+
fn f() {
238+
let mut t = 'a';
239+
let chars = "abcd";
240+
match t {
241+
'\r' => if let Some(_) = chars.clone().next() {
242+
t = 'e';<|>
243+
false
244+
},
245+
_ => true
246+
}
247+
}
248+
"#,
249+
r#"
250+
fn f() {
251+
let mut t = 'a';
252+
let chars = "abcd";
253+
match t {
254+
'\r' <|>if let Some(_) = chars.clone().next() => {
255+
t = 'e';
256+
false
257+
},
258+
_ => true
259+
}
260+
}
261+
"#,
262+
);
263+
}
115264
}

0 commit comments

Comments
 (0)