diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-22 20:28:17 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-22 20:28:17 +0000 |
commit | 27ed1ebf8997cea55fb446ce249b390607b84105 (patch) | |
tree | a49a763fee848041fd607f449ad13a0b1040636e /crates/ide_assists/src/handlers/unwrap_block.rs | |
parent | 8687053b118f47ce1a4962d0baa19b22d40d2758 (diff) | |
parent | eb6cfa7f157690480fca5d55c69dba3fae87ad4f (diff) |
Merge #7759
7759: 7526: Rename ide related crates r=Veykril a=chetankhilosiya
renamed assists -> ide_assists and ssr -> ide_ssr.
the completion crate is already renamed.
Co-authored-by: Chetan Khilosiya <[email protected]>
Diffstat (limited to 'crates/ide_assists/src/handlers/unwrap_block.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/unwrap_block.rs | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/crates/ide_assists/src/handlers/unwrap_block.rs b/crates/ide_assists/src/handlers/unwrap_block.rs new file mode 100644 index 000000000..ed6f6177d --- /dev/null +++ b/crates/ide_assists/src/handlers/unwrap_block.rs | |||
@@ -0,0 +1,582 @@ | |||
1 | use syntax::{ | ||
2 | ast::{ | ||
3 | self, | ||
4 | edit::{AstNodeEdit, IndentLevel}, | ||
5 | }, | ||
6 | AstNode, SyntaxKind, TextRange, T, | ||
7 | }; | ||
8 | |||
9 | use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists}; | ||
10 | |||
11 | // Assist: unwrap_block | ||
12 | // | ||
13 | // This assist removes if...else, for, while and loop control statements to just keep the body. | ||
14 | // | ||
15 | // ``` | ||
16 | // fn foo() { | ||
17 | // if true {$0 | ||
18 | // println!("foo"); | ||
19 | // } | ||
20 | // } | ||
21 | // ``` | ||
22 | // -> | ||
23 | // ``` | ||
24 | // fn foo() { | ||
25 | // println!("foo"); | ||
26 | // } | ||
27 | // ``` | ||
28 | pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
29 | let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite); | ||
30 | let assist_label = "Unwrap block"; | ||
31 | |||
32 | let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?; | ||
33 | let mut block = ast::BlockExpr::cast(l_curly_token.parent())?; | ||
34 | let target = block.syntax().text_range(); | ||
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 | if matches!(parent.kind(), SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT) { | ||
41 | return acc.add(assist_id, assist_label, target, |builder| { | ||
42 | builder.replace( | ||
43 | block.syntax().text_range(), | ||
44 | update_expr_string(block.to_string(), &[' ', '{', '\n']), | ||
45 | ); | ||
46 | }); | ||
47 | } | ||
48 | |||
49 | let parent = ast::Expr::cast(parent)?; | ||
50 | |||
51 | match parent.clone() { | ||
52 | ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (), | ||
53 | ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)), | ||
54 | ast::Expr::IfExpr(if_expr) => { | ||
55 | let then_branch = if_expr.then_branch()?; | ||
56 | if then_branch == block { | ||
57 | if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) { | ||
58 | // For `else if` blocks | ||
59 | let ancestor_then_branch = ancestor.then_branch()?; | ||
60 | |||
61 | return acc.add(assist_id, assist_label, target, |edit| { | ||
62 | let range_to_del_else_if = TextRange::new( | ||
63 | ancestor_then_branch.syntax().text_range().end(), | ||
64 | l_curly_token.text_range().start(), | ||
65 | ); | ||
66 | let range_to_del_rest = TextRange::new( | ||
67 | then_branch.syntax().text_range().end(), | ||
68 | if_expr.syntax().text_range().end(), | ||
69 | ); | ||
70 | |||
71 | edit.delete(range_to_del_rest); | ||
72 | edit.delete(range_to_del_else_if); | ||
73 | edit.replace( | ||
74 | target, | ||
75 | update_expr_string(then_branch.to_string(), &[' ', '{']), | ||
76 | ); | ||
77 | }); | ||
78 | } | ||
79 | } else { | ||
80 | return acc.add(assist_id, assist_label, target, |edit| { | ||
81 | let range_to_del = TextRange::new( | ||
82 | then_branch.syntax().text_range().end(), | ||
83 | l_curly_token.text_range().start(), | ||
84 | ); | ||
85 | |||
86 | edit.delete(range_to_del); | ||
87 | edit.replace(target, update_expr_string(block.to_string(), &[' ', '{'])); | ||
88 | }); | ||
89 | } | ||
90 | } | ||
91 | _ => return None, | ||
92 | }; | ||
93 | |||
94 | let unwrapped = unwrap_trivial_block(block); | ||
95 | acc.add(assist_id, assist_label, target, |builder| { | ||
96 | builder.replace( | ||
97 | parent.syntax().text_range(), | ||
98 | update_expr_string(unwrapped.to_string(), &[' ', '{', '\n']), | ||
99 | ); | ||
100 | }) | ||
101 | } | ||
102 | |||
103 | fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String { | ||
104 | let expr_string = expr_str.trim_start_matches(trim_start_pat); | ||
105 | let mut expr_string_lines: Vec<&str> = expr_string.lines().collect(); | ||
106 | expr_string_lines.pop(); // Delete last line | ||
107 | |||
108 | expr_string_lines | ||
109 | .into_iter() | ||
110 | .map(|line| line.replacen(" ", "", 1)) // Delete indentation | ||
111 | .collect::<Vec<String>>() | ||
112 | .join("\n") | ||
113 | } | ||
114 | |||
115 | #[cfg(test)] | ||
116 | mod tests { | ||
117 | use crate::tests::{check_assist, check_assist_not_applicable}; | ||
118 | |||
119 | use super::*; | ||
120 | |||
121 | #[test] | ||
122 | fn unwrap_tail_expr_block() { | ||
123 | check_assist( | ||
124 | unwrap_block, | ||
125 | r#" | ||
126 | fn main() { | ||
127 | $0{ | ||
128 | 92 | ||
129 | } | ||
130 | } | ||
131 | "#, | ||
132 | r#" | ||
133 | fn main() { | ||
134 | 92 | ||
135 | } | ||
136 | "#, | ||
137 | ) | ||
138 | } | ||
139 | |||
140 | #[test] | ||
141 | fn unwrap_stmt_expr_block() { | ||
142 | check_assist( | ||
143 | unwrap_block, | ||
144 | r#" | ||
145 | fn main() { | ||
146 | $0{ | ||
147 | 92; | ||
148 | } | ||
149 | () | ||
150 | } | ||
151 | "#, | ||
152 | r#" | ||
153 | fn main() { | ||
154 | 92; | ||
155 | () | ||
156 | } | ||
157 | "#, | ||
158 | ); | ||
159 | // Pedantically, we should add an `;` here... | ||
160 | check_assist( | ||
161 | unwrap_block, | ||
162 | r#" | ||
163 | fn main() { | ||
164 | $0{ | ||
165 | 92 | ||
166 | } | ||
167 | () | ||
168 | } | ||
169 | "#, | ||
170 | r#" | ||
171 | fn main() { | ||
172 | 92 | ||
173 | () | ||
174 | } | ||
175 | "#, | ||
176 | ); | ||
177 | } | ||
178 | |||
179 | #[test] | ||
180 | fn simple_if() { | ||
181 | check_assist( | ||
182 | unwrap_block, | ||
183 | r#" | ||
184 | fn main() { | ||
185 | bar(); | ||
186 | if true {$0 | ||
187 | foo(); | ||
188 | |||
189 | //comment | ||
190 | bar(); | ||
191 | } else { | ||
192 | println!("bar"); | ||
193 | } | ||
194 | } | ||
195 | "#, | ||
196 | r#" | ||
197 | fn main() { | ||
198 | bar(); | ||
199 | foo(); | ||
200 | |||
201 | //comment | ||
202 | bar(); | ||
203 | } | ||
204 | "#, | ||
205 | ); | ||
206 | } | ||
207 | |||
208 | #[test] | ||
209 | fn simple_if_else() { | ||
210 | check_assist( | ||
211 | unwrap_block, | ||
212 | r#" | ||
213 | fn main() { | ||
214 | bar(); | ||
215 | if true { | ||
216 | foo(); | ||
217 | |||
218 | //comment | ||
219 | bar(); | ||
220 | } else {$0 | ||
221 | println!("bar"); | ||
222 | } | ||
223 | } | ||
224 | "#, | ||
225 | r#" | ||
226 | fn main() { | ||
227 | bar(); | ||
228 | if true { | ||
229 | foo(); | ||
230 | |||
231 | //comment | ||
232 | bar(); | ||
233 | } | ||
234 | println!("bar"); | ||
235 | } | ||
236 | "#, | ||
237 | ); | ||
238 | } | ||
239 | |||
240 | #[test] | ||
241 | fn simple_if_else_if() { | ||
242 | check_assist( | ||
243 | unwrap_block, | ||
244 | r#" | ||
245 | fn main() { | ||
246 | //bar(); | ||
247 | if true { | ||
248 | println!("true"); | ||
249 | |||
250 | //comment | ||
251 | //bar(); | ||
252 | } else if false {$0 | ||
253 | println!("bar"); | ||
254 | } else { | ||
255 | println!("foo"); | ||
256 | } | ||
257 | } | ||
258 | "#, | ||
259 | r#" | ||
260 | fn main() { | ||
261 | //bar(); | ||
262 | if true { | ||
263 | println!("true"); | ||
264 | |||
265 | //comment | ||
266 | //bar(); | ||
267 | } | ||
268 | println!("bar"); | ||
269 | } | ||
270 | "#, | ||
271 | ); | ||
272 | } | ||
273 | |||
274 | #[test] | ||
275 | fn simple_if_else_if_nested() { | ||
276 | check_assist( | ||
277 | unwrap_block, | ||
278 | r#" | ||
279 | fn main() { | ||
280 | //bar(); | ||
281 | if true { | ||
282 | println!("true"); | ||
283 | |||
284 | //comment | ||
285 | //bar(); | ||
286 | } else if false { | ||
287 | println!("bar"); | ||
288 | } else if true {$0 | ||
289 | println!("foo"); | ||
290 | } | ||
291 | } | ||
292 | "#, | ||
293 | r#" | ||
294 | fn main() { | ||
295 | //bar(); | ||
296 | if true { | ||
297 | println!("true"); | ||
298 | |||
299 | //comment | ||
300 | //bar(); | ||
301 | } else if false { | ||
302 | println!("bar"); | ||
303 | } | ||
304 | println!("foo"); | ||
305 | } | ||
306 | "#, | ||
307 | ); | ||
308 | } | ||
309 | |||
310 | #[test] | ||
311 | fn simple_if_else_if_nested_else() { | ||
312 | check_assist( | ||
313 | unwrap_block, | ||
314 | r#" | ||
315 | fn main() { | ||
316 | //bar(); | ||
317 | if true { | ||
318 | println!("true"); | ||
319 | |||
320 | //comment | ||
321 | //bar(); | ||
322 | } else if false { | ||
323 | println!("bar"); | ||
324 | } else if true { | ||
325 | println!("foo"); | ||
326 | } else {$0 | ||
327 | println!("else"); | ||
328 | } | ||
329 | } | ||
330 | "#, | ||
331 | r#" | ||
332 | fn main() { | ||
333 | //bar(); | ||
334 | if true { | ||
335 | println!("true"); | ||
336 | |||
337 | //comment | ||
338 | //bar(); | ||
339 | } else if false { | ||
340 | println!("bar"); | ||
341 | } else if true { | ||
342 | println!("foo"); | ||
343 | } | ||
344 | println!("else"); | ||
345 | } | ||
346 | "#, | ||
347 | ); | ||
348 | } | ||
349 | |||
350 | #[test] | ||
351 | fn simple_if_else_if_nested_middle() { | ||
352 | check_assist( | ||
353 | unwrap_block, | ||
354 | r#" | ||
355 | fn main() { | ||
356 | //bar(); | ||
357 | if true { | ||
358 | println!("true"); | ||
359 | |||
360 | //comment | ||
361 | //bar(); | ||
362 | } else if false { | ||
363 | println!("bar"); | ||
364 | } else if true {$0 | ||
365 | println!("foo"); | ||
366 | } else { | ||
367 | println!("else"); | ||
368 | } | ||
369 | } | ||
370 | "#, | ||
371 | r#" | ||
372 | fn main() { | ||
373 | //bar(); | ||
374 | if true { | ||
375 | println!("true"); | ||
376 | |||
377 | //comment | ||
378 | //bar(); | ||
379 | } else if false { | ||
380 | println!("bar"); | ||
381 | } | ||
382 | println!("foo"); | ||
383 | } | ||
384 | "#, | ||
385 | ); | ||
386 | } | ||
387 | |||
388 | #[test] | ||
389 | fn simple_if_bad_cursor_position() { | ||
390 | check_assist_not_applicable( | ||
391 | unwrap_block, | ||
392 | r#" | ||
393 | fn main() { | ||
394 | bar();$0 | ||
395 | if true { | ||
396 | foo(); | ||
397 | |||
398 | //comment | ||
399 | bar(); | ||
400 | } else { | ||
401 | println!("bar"); | ||
402 | } | ||
403 | } | ||
404 | "#, | ||
405 | ); | ||
406 | } | ||
407 | |||
408 | #[test] | ||
409 | fn simple_for() { | ||
410 | check_assist( | ||
411 | unwrap_block, | ||
412 | r#" | ||
413 | fn main() { | ||
414 | for i in 0..5 {$0 | ||
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_if_in_for() { | ||
443 | check_assist( | ||
444 | unwrap_block, | ||
445 | r#" | ||
446 | fn main() { | ||
447 | for i in 0..5 { | ||
448 | if true {$0 | ||
449 | foo(); | ||
450 | |||
451 | //comment | ||
452 | bar(); | ||
453 | } else { | ||
454 | println!("bar"); | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | "#, | ||
459 | r#" | ||
460 | fn main() { | ||
461 | for i in 0..5 { | ||
462 | foo(); | ||
463 | |||
464 | //comment | ||
465 | bar(); | ||
466 | } | ||
467 | } | ||
468 | "#, | ||
469 | ); | ||
470 | } | ||
471 | |||
472 | #[test] | ||
473 | fn simple_loop() { | ||
474 | check_assist( | ||
475 | unwrap_block, | ||
476 | r#" | ||
477 | fn main() { | ||
478 | loop {$0 | ||
479 | if true { | ||
480 | foo(); | ||
481 | |||
482 | //comment | ||
483 | bar(); | ||
484 | } else { | ||
485 | println!("bar"); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | "#, | ||
490 | r#" | ||
491 | fn main() { | ||
492 | if true { | ||
493 | foo(); | ||
494 | |||
495 | //comment | ||
496 | bar(); | ||
497 | } else { | ||
498 | println!("bar"); | ||
499 | } | ||
500 | } | ||
501 | "#, | ||
502 | ); | ||
503 | } | ||
504 | |||
505 | #[test] | ||
506 | fn simple_while() { | ||
507 | check_assist( | ||
508 | unwrap_block, | ||
509 | r#" | ||
510 | fn main() { | ||
511 | while true {$0 | ||
512 | if true { | ||
513 | foo(); | ||
514 | |||
515 | //comment | ||
516 | bar(); | ||
517 | } else { | ||
518 | println!("bar"); | ||
519 | } | ||
520 | } | ||
521 | } | ||
522 | "#, | ||
523 | r#" | ||
524 | fn main() { | ||
525 | if true { | ||
526 | foo(); | ||
527 | |||
528 | //comment | ||
529 | bar(); | ||
530 | } else { | ||
531 | println!("bar"); | ||
532 | } | ||
533 | } | ||
534 | "#, | ||
535 | ); | ||
536 | } | ||
537 | |||
538 | #[test] | ||
539 | fn unwrap_match_arm() { | ||
540 | check_assist( | ||
541 | unwrap_block, | ||
542 | r#" | ||
543 | fn main() { | ||
544 | match rel_path { | ||
545 | Ok(rel_path) => {$0 | ||
546 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
547 | Some((*id, rel_path)) | ||
548 | } | ||
549 | Err(_) => None, | ||
550 | } | ||
551 | } | ||
552 | "#, | ||
553 | r#" | ||
554 | fn main() { | ||
555 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
556 | Some((*id, rel_path)) | ||
557 | } | ||
558 | "#, | ||
559 | ); | ||
560 | } | ||
561 | |||
562 | #[test] | ||
563 | fn simple_if_in_while_bad_cursor_position() { | ||
564 | check_assist_not_applicable( | ||
565 | unwrap_block, | ||
566 | r#" | ||
567 | fn main() { | ||
568 | while true { | ||
569 | if true { | ||
570 | foo();$0 | ||
571 | |||
572 | //comment | ||
573 | bar(); | ||
574 | } else { | ||
575 | println!("bar"); | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | "#, | ||
580 | ); | ||
581 | } | ||
582 | } | ||