aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/unwrap_block.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/unwrap_block.rs')
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs518
1 files changed, 0 insertions, 518 deletions
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs
deleted file mode 100644
index 8b38695a9..000000000
--- a/crates/ra_assists/src/handlers/unwrap_block.rs
+++ /dev/null
@@ -1,518 +0,0 @@
1use ra_fmt::unwrap_trivial_block;
2use ra_syntax::{
3 ast::{
4 self,
5 edit::{AstNodeEdit, IndentLevel},
6 },
7 AstNode, TextRange, T,
8};
9
10use crate::{AssistContext, AssistId, AssistKind, Assists};
11
12// Assist: unwrap_block
13//
14// This assist removes if...else, for, while and loop control statements to just keep the body.
15//
16// ```
17// fn foo() {
18// if true {<|>
19// println!("foo");
20// }
21// }
22// ```
23// ->
24// ```
25// fn foo() {
26// println!("foo");
27// }
28// ```
29pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
30 let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
31 let assist_label = "Unwrap block";
32
33 let l_curly_token = ctx.find_token_at_offset(T!['{'])?;
34 let mut block = ast::BlockExpr::cast(l_curly_token.parent())?;
35 let mut parent = block.syntax().parent()?;
36 if ast::MatchArm::can_cast(parent.kind()) {
37 parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
38 }
39
40 let parent = ast::Expr::cast(parent)?;
41
42 match parent.clone() {
43 ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
44 ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
45 ast::Expr::IfExpr(if_expr) => {
46 let then_branch = if_expr.then_branch()?;
47 if then_branch == block {
48 if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
49 // For `else if` blocks
50 let ancestor_then_branch = ancestor.then_branch()?;
51
52 let target = then_branch.syntax().text_range();
53 return acc.add(assist_id, assist_label, target, |edit| {
54 let range_to_del_else_if = TextRange::new(
55 ancestor_then_branch.syntax().text_range().end(),
56 l_curly_token.text_range().start(),
57 );
58 let range_to_del_rest = TextRange::new(
59 then_branch.syntax().text_range().end(),
60 if_expr.syntax().text_range().end(),
61 );
62
63 edit.delete(range_to_del_rest);
64 edit.delete(range_to_del_else_if);
65 edit.replace(
66 target,
67 update_expr_string(then_branch.to_string(), &[' ', '{']),
68 );
69 });
70 }
71 } else {
72 let target = block.syntax().text_range();
73 return acc.add(assist_id, assist_label, target, |edit| {
74 let range_to_del = TextRange::new(
75 then_branch.syntax().text_range().end(),
76 l_curly_token.text_range().start(),
77 );
78
79 edit.delete(range_to_del);
80 edit.replace(target, update_expr_string(block.to_string(), &[' ', '{']));
81 });
82 }
83 }
84 _ => return None,
85 };
86
87 let unwrapped = unwrap_trivial_block(block);
88 let target = unwrapped.syntax().text_range();
89 acc.add(assist_id, assist_label, target, |builder| {
90 builder.replace(
91 parent.syntax().text_range(),
92 update_expr_string(unwrapped.to_string(), &[' ', '{', '\n']),
93 );
94 })
95}
96
97fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String {
98 let expr_string = expr_str.trim_start_matches(trim_start_pat);
99 let mut expr_string_lines: Vec<&str> = expr_string.lines().collect();
100 expr_string_lines.pop(); // Delete last line
101
102 expr_string_lines
103 .into_iter()
104 .map(|line| line.replacen(" ", "", 1)) // Delete indentation
105 .collect::<Vec<String>>()
106 .join("\n")
107}
108
109#[cfg(test)]
110mod tests {
111 use crate::tests::{check_assist, check_assist_not_applicable};
112
113 use super::*;
114
115 #[test]
116 fn simple_if() {
117 check_assist(
118 unwrap_block,
119 r#"
120 fn main() {
121 bar();
122 if true {<|>
123 foo();
124
125 //comment
126 bar();
127 } else {
128 println!("bar");
129 }
130 }
131 "#,
132 r#"
133 fn main() {
134 bar();
135 foo();
136
137 //comment
138 bar();
139 }
140 "#,
141 );
142 }
143
144 #[test]
145 fn simple_if_else() {
146 check_assist(
147 unwrap_block,
148 r#"
149 fn main() {
150 bar();
151 if true {
152 foo();
153
154 //comment
155 bar();
156 } else {<|>
157 println!("bar");
158 }
159 }
160 "#,
161 r#"
162 fn main() {
163 bar();
164 if true {
165 foo();
166
167 //comment
168 bar();
169 }
170 println!("bar");
171 }
172 "#,
173 );
174 }
175
176 #[test]
177 fn simple_if_else_if() {
178 check_assist(
179 unwrap_block,
180 r#"
181 fn main() {
182 //bar();
183 if true {
184 println!("true");
185
186 //comment
187 //bar();
188 } else if false {<|>
189 println!("bar");
190 } else {
191 println!("foo");
192 }
193 }
194 "#,
195 r#"
196 fn main() {
197 //bar();
198 if true {
199 println!("true");
200
201 //comment
202 //bar();
203 }
204 println!("bar");
205 }
206 "#,
207 );
208 }
209
210 #[test]
211 fn simple_if_else_if_nested() {
212 check_assist(
213 unwrap_block,
214 r#"
215 fn main() {
216 //bar();
217 if true {
218 println!("true");
219
220 //comment
221 //bar();
222 } else if false {
223 println!("bar");
224 } else if true {<|>
225 println!("foo");
226 }
227 }
228 "#,
229 r#"
230 fn main() {
231 //bar();
232 if true {
233 println!("true");
234
235 //comment
236 //bar();
237 } else if false {
238 println!("bar");
239 }
240 println!("foo");
241 }
242 "#,
243 );
244 }
245
246 #[test]
247 fn simple_if_else_if_nested_else() {
248 check_assist(
249 unwrap_block,
250 r#"
251 fn main() {
252 //bar();
253 if true {
254 println!("true");
255
256 //comment
257 //bar();
258 } else if false {
259 println!("bar");
260 } else if true {
261 println!("foo");
262 } else {<|>
263 println!("else");
264 }
265 }
266 "#,
267 r#"
268 fn main() {
269 //bar();
270 if true {
271 println!("true");
272
273 //comment
274 //bar();
275 } else if false {
276 println!("bar");
277 } else if true {
278 println!("foo");
279 }
280 println!("else");
281 }
282 "#,
283 );
284 }
285
286 #[test]
287 fn simple_if_else_if_nested_middle() {
288 check_assist(
289 unwrap_block,
290 r#"
291 fn main() {
292 //bar();
293 if true {
294 println!("true");
295
296 //comment
297 //bar();
298 } else if false {
299 println!("bar");
300 } else if true {<|>
301 println!("foo");
302 } else {
303 println!("else");
304 }
305 }
306 "#,
307 r#"
308 fn main() {
309 //bar();
310 if true {
311 println!("true");
312
313 //comment
314 //bar();
315 } else if false {
316 println!("bar");
317 }
318 println!("foo");
319 }
320 "#,
321 );
322 }
323
324 #[test]
325 fn simple_if_bad_cursor_position() {
326 check_assist_not_applicable(
327 unwrap_block,
328 r#"
329 fn main() {
330 bar();<|>
331 if true {
332 foo();
333
334 //comment
335 bar();
336 } else {
337 println!("bar");
338 }
339 }
340 "#,
341 );
342 }
343
344 #[test]
345 fn simple_for() {
346 check_assist(
347 unwrap_block,
348 r#"
349 fn main() {
350 for i in 0..5 {<|>
351 if true {
352 foo();
353
354 //comment
355 bar();
356 } else {
357 println!("bar");
358 }
359 }
360 }
361 "#,
362 r#"
363 fn main() {
364 if true {
365 foo();
366
367 //comment
368 bar();
369 } else {
370 println!("bar");
371 }
372 }
373 "#,
374 );
375 }
376
377 #[test]
378 fn simple_if_in_for() {
379 check_assist(
380 unwrap_block,
381 r#"
382 fn main() {
383 for i in 0..5 {
384 if true {<|>
385 foo();
386
387 //comment
388 bar();
389 } else {
390 println!("bar");
391 }
392 }
393 }
394 "#,
395 r#"
396 fn main() {
397 for i in 0..5 {
398 foo();
399
400 //comment
401 bar();
402 }
403 }
404 "#,
405 );
406 }
407
408 #[test]
409 fn simple_loop() {
410 check_assist(
411 unwrap_block,
412 r#"
413 fn main() {
414 loop {<|>
415 if true {
416 foo();
417
418 //comment
419 bar();
420 } else {
421 println!("bar");
422 }
423 }
424 }
425 "#,
426 r#"
427 fn main() {
428 if true {
429 foo();
430
431 //comment
432 bar();
433 } else {
434 println!("bar");
435 }
436 }
437 "#,
438 );
439 }
440
441 #[test]
442 fn simple_while() {
443 check_assist(
444 unwrap_block,
445 r#"
446 fn main() {
447 while true {<|>
448 if true {
449 foo();
450
451 //comment
452 bar();
453 } else {
454 println!("bar");
455 }
456 }
457 }
458 "#,
459 r#"
460 fn main() {
461 if true {
462 foo();
463
464 //comment
465 bar();
466 } else {
467 println!("bar");
468 }
469 }
470 "#,
471 );
472 }
473
474 #[test]
475 fn unwrap_match_arm() {
476 check_assist(
477 unwrap_block,
478 r#"
479fn main() {
480 match rel_path {
481 Ok(rel_path) => {<|>
482 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
483 Some((*id, rel_path))
484 }
485 Err(_) => None,
486 }
487}
488"#,
489 r#"
490fn main() {
491 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
492 Some((*id, rel_path))
493}
494"#,
495 );
496 }
497
498 #[test]
499 fn simple_if_in_while_bad_cursor_position() {
500 check_assist_not_applicable(
501 unwrap_block,
502 r#"
503 fn main() {
504 while true {
505 if true {
506 foo();<|>
507
508 //comment
509 bar();
510 } else {
511 println!("bar");
512 }
513 }
514 }
515 "#,
516 );
517 }
518}