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.rs303
1 files changed, 0 insertions, 303 deletions
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
deleted file mode 100644
index 4060d34c6..000000000
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ /dev/null
@@ -1,303 +0,0 @@
1use ra_syntax::{
2 ast::{AstNode, IfExpr, MatchArm},
3 SyntaxKind::WHITESPACE,
4};
5
6use crate::{AssistContext, AssistId, AssistKind, Assists};
7
8// Assist: move_guard_to_arm_body
9//
10// Moves match guard into match arm body.
11//
12// ```
13// enum Action { Move { distance: u32 }, Stop }
14//
15// fn handle(action: Action) {
16// match action {
17// Action::Move { distance } <|>if distance > 10 => foo(),
18// _ => (),
19// }
20// }
21// ```
22// ->
23// ```
24// enum Action { Move { distance: u32 }, Stop }
25//
26// fn handle(action: Action) {
27// match action {
28// Action::Move { distance } => if distance > 10 { foo() },
29// _ => (),
30// }
31// }
32// ```
33pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
34 let match_arm = ctx.find_node_at_offset::<MatchArm>()?;
35 let guard = match_arm.guard()?;
36 let space_before_guard = guard.syntax().prev_sibling_or_token();
37
38 let guard_conditions = guard.expr()?;
39 let arm_expr = match_arm.expr()?;
40 let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text());
41
42 let target = guard.syntax().text_range();
43 acc.add(
44 AssistId("move_guard_to_arm_body", AssistKind::RefactorRewrite),
45 "Move guard to arm body",
46 target,
47 |edit| {
48 match space_before_guard {
49 Some(element) if element.kind() == WHITESPACE => {
50 edit.delete(element.text_range());
51 }
52 _ => (),
53 };
54
55 edit.delete(guard.syntax().text_range());
56 edit.replace_node_and_indent(arm_expr.syntax(), buf);
57 },
58 )
59}
60
61// Assist: move_arm_cond_to_match_guard
62//
63// Moves if expression from match arm body into a guard.
64//
65// ```
66// enum Action { Move { distance: u32 }, Stop }
67//
68// fn handle(action: Action) {
69// match action {
70// Action::Move { distance } => <|>if distance > 10 { foo() },
71// _ => (),
72// }
73// }
74// ```
75// ->
76// ```
77// enum Action { Move { distance: u32 }, Stop }
78//
79// fn handle(action: Action) {
80// match action {
81// Action::Move { distance } if distance > 10 => foo(),
82// _ => (),
83// }
84// }
85// ```
86pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
87 let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?;
88 let match_pat = match_arm.pat()?;
89
90 let arm_body = match_arm.expr()?;
91 let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone())?;
92 let cond = if_expr.condition()?;
93 let then_block = if_expr.then_branch()?;
94
95 // Not support if with else branch
96 if if_expr.else_branch().is_some() {
97 return None;
98 }
99 // Not support moving if let to arm guard
100 if cond.pat().is_some() {
101 return None;
102 }
103
104 let buf = format!(" if {}", cond.syntax().text());
105
106 let target = if_expr.syntax().text_range();
107 acc.add(
108 AssistId("move_arm_cond_to_match_guard", AssistKind::RefactorRewrite),
109 "Move condition to match guard",
110 target,
111 |edit| {
112 let then_only_expr = then_block.statements().next().is_none();
113
114 match &then_block.expr() {
115 Some(then_expr) if then_only_expr => {
116 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text())
117 }
118 _ => edit.replace(if_expr.syntax().text_range(), then_block.syntax().text()),
119 }
120
121 edit.insert(match_pat.syntax().text_range().end(), buf);
122 },
123 )
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
131
132 #[test]
133 fn move_guard_to_arm_body_target() {
134 check_assist_target(
135 move_guard_to_arm_body,
136 r#"
137 fn f() {
138 let t = 'a';
139 let chars = "abcd";
140 match t {
141 '\r' <|>if chars.clone().next() == Some('\n') => false,
142 _ => true
143 }
144 }
145 "#,
146 r#"if chars.clone().next() == Some('\n')"#,
147 );
148 }
149
150 #[test]
151 fn move_guard_to_arm_body_works() {
152 check_assist(
153 move_guard_to_arm_body,
154 r#"
155 fn f() {
156 let t = 'a';
157 let chars = "abcd";
158 match t {
159 '\r' <|>if chars.clone().next() == Some('\n') => false,
160 _ => true
161 }
162 }
163 "#,
164 r#"
165 fn f() {
166 let t = 'a';
167 let chars = "abcd";
168 match t {
169 '\r' => if chars.clone().next() == Some('\n') { false },
170 _ => true
171 }
172 }
173 "#,
174 );
175 }
176
177 #[test]
178 fn move_guard_to_arm_body_works_complex_match() {
179 check_assist(
180 move_guard_to_arm_body,
181 r#"
182 fn f() {
183 match x {
184 <|>y @ 4 | y @ 5 if y > 5 => true,
185 _ => false
186 }
187 }
188 "#,
189 r#"
190 fn f() {
191 match x {
192 y @ 4 | y @ 5 => if y > 5 { true },
193 _ => false
194 }
195 }
196 "#,
197 );
198 }
199
200 #[test]
201 fn move_arm_cond_to_match_guard_works() {
202 check_assist(
203 move_arm_cond_to_match_guard,
204 r#"
205 fn f() {
206 let t = 'a';
207 let chars = "abcd";
208 match t {
209 '\r' => if chars.clone().next() == Some('\n') { <|>false },
210 _ => true
211 }
212 }
213 "#,
214 r#"
215 fn f() {
216 let t = 'a';
217 let chars = "abcd";
218 match t {
219 '\r' if chars.clone().next() == Some('\n') => false,
220 _ => true
221 }
222 }
223 "#,
224 );
225 }
226
227 #[test]
228 fn move_arm_cond_to_match_guard_if_let_not_works() {
229 check_assist_not_applicable(
230 move_arm_cond_to_match_guard,
231 r#"
232 fn f() {
233 let t = 'a';
234 let chars = "abcd";
235 match t {
236 '\r' => if let Some(_) = chars.clone().next() { <|>false },
237 _ => true
238 }
239 }
240 "#,
241 );
242 }
243
244 #[test]
245 fn move_arm_cond_to_match_guard_if_empty_body_works() {
246 check_assist(
247 move_arm_cond_to_match_guard,
248 r#"
249 fn f() {
250 let t = 'a';
251 let chars = "abcd";
252 match t {
253 '\r' => if chars.clone().next().is_some() { <|> },
254 _ => true
255 }
256 }
257 "#,
258 r#"
259 fn f() {
260 let t = 'a';
261 let chars = "abcd";
262 match t {
263 '\r' if chars.clone().next().is_some() => { },
264 _ => true
265 }
266 }
267 "#,
268 );
269 }
270
271 #[test]
272 fn move_arm_cond_to_match_guard_if_multiline_body_works() {
273 check_assist(
274 move_arm_cond_to_match_guard,
275 r#"
276 fn f() {
277 let mut t = 'a';
278 let chars = "abcd";
279 match t {
280 '\r' => if chars.clone().next().is_some() {
281 t = 'e';<|>
282 false
283 },
284 _ => true
285 }
286 }
287 "#,
288 r#"
289 fn f() {
290 let mut t = 'a';
291 let chars = "abcd";
292 match t {
293 '\r' if chars.clone().next().is_some() => {
294 t = 'e';
295 false
296 },
297 _ => true
298 }
299 }
300 "#,
301 );
302 }
303}