diff options
author | Benjamin Coenen <[email protected]> | 2020-05-01 15:41:29 +0100 |
---|---|---|
committer | Benjamin Coenen <[email protected]> | 2020-05-01 15:41:29 +0100 |
commit | df7899e47a83fb5544d09d2db9405762d3ce29b7 (patch) | |
tree | 3a9ad151b5ce6688ae617071bc2a04dd68a9078b | |
parent | dc34162450797f5756ce2b44f1a3fe73d8e2dce4 (diff) |
Add unwrap block assist #4156
Signed-off-by: Benjamin Coenen <[email protected]>
-rw-r--r-- | crates/ra_assists/src/handlers/unwrap_block.rs | 69 |
1 files changed, 23 insertions, 46 deletions
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs index 35d87bc9e..71d6d462b 100644 --- a/crates/ra_assists/src/handlers/unwrap_block.rs +++ b/crates/ra_assists/src/handlers/unwrap_block.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | use crate::{Assist, AssistCtx, AssistId}; | 1 | use crate::{Assist, AssistCtx, AssistId}; |
2 | 2 | ||
3 | use ast::LoopBodyOwner; | 3 | use ast::{BlockExpr, Expr, LoopBodyOwner}; |
4 | use ra_fmt::unwrap_trivial_block; | 4 | use ra_fmt::unwrap_trivial_block; |
5 | use ra_syntax::{ast, AstNode}; | 5 | use ra_syntax::{ast, AstNode, TextRange}; |
6 | 6 | ||
7 | // Assist: unwrap_block | 7 | // Assist: unwrap_block |
8 | // | 8 | // |
@@ -26,24 +26,14 @@ pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { | |||
26 | // if expression | 26 | // if expression |
27 | let mut expr_to_unwrap: Option<ast::Expr> = None; | 27 | let mut expr_to_unwrap: Option<ast::Expr> = None; |
28 | for block_expr in if_expr.blocks() { | 28 | for block_expr in if_expr.blocks() { |
29 | if let Some(block) = block_expr.block() { | 29 | if let Some(expr) = excract_expr(ctx.frange.range, block_expr) { |
30 | let cursor_in_range = | 30 | expr_to_unwrap = Some(expr); |
31 | block.l_curly_token()?.text_range().contains_range(ctx.frange.range); | 31 | break; |
32 | |||
33 | if cursor_in_range { | ||
34 | let exprto = unwrap_trivial_block(block_expr); | ||
35 | expr_to_unwrap = Some(exprto); | ||
36 | break; | ||
37 | } | ||
38 | } | 32 | } |
39 | } | 33 | } |
40 | let expr_to_unwrap = expr_to_unwrap?; | 34 | let expr_to_unwrap = expr_to_unwrap?; |
41 | // Find if we are in a else if block | 35 | // Find if we are in a else if block |
42 | let ancestor = ctx | 36 | let ancestor = if_expr.syntax().ancestors().skip(1).find_map(ast::IfExpr::cast); |
43 | .sema | ||
44 | .ancestors_with_macros(if_expr.syntax().clone()) | ||
45 | .skip(1) | ||
46 | .find_map(ast::IfExpr::cast); | ||
47 | 37 | ||
48 | if let Some(ancestor) = ancestor { | 38 | if let Some(ancestor) = ancestor { |
49 | Some((ast::Expr::IfExpr(ancestor), expr_to_unwrap)) | 39 | Some((ast::Expr::IfExpr(ancestor), expr_to_unwrap)) |
@@ -53,42 +43,18 @@ pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { | |||
53 | } else if let Some(for_expr) = ctx.find_node_at_offset::<ast::ForExpr>() { | 43 | } else if let Some(for_expr) = ctx.find_node_at_offset::<ast::ForExpr>() { |
54 | // for expression | 44 | // for expression |
55 | let block_expr = for_expr.loop_body()?; | 45 | let block_expr = for_expr.loop_body()?; |
56 | let block = block_expr.block()?; | 46 | excract_expr(ctx.frange.range, block_expr) |
57 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(ctx.frange.range); | 47 | .map(|expr_to_unwrap| (ast::Expr::ForExpr(for_expr), expr_to_unwrap)) |
58 | |||
59 | if cursor_in_range { | ||
60 | let expr_to_unwrap = unwrap_trivial_block(block_expr); | ||
61 | |||
62 | Some((ast::Expr::ForExpr(for_expr), expr_to_unwrap)) | ||
63 | } else { | ||
64 | None | ||
65 | } | ||
66 | } else if let Some(while_expr) = ctx.find_node_at_offset::<ast::WhileExpr>() { | 48 | } else if let Some(while_expr) = ctx.find_node_at_offset::<ast::WhileExpr>() { |
67 | // while expression | 49 | // while expression |
68 | let block_expr = while_expr.loop_body()?; | 50 | let block_expr = while_expr.loop_body()?; |
69 | let block = block_expr.block()?; | 51 | excract_expr(ctx.frange.range, block_expr) |
70 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(ctx.frange.range); | 52 | .map(|expr_to_unwrap| (ast::Expr::WhileExpr(while_expr), expr_to_unwrap)) |
71 | |||
72 | if cursor_in_range { | ||
73 | let expr_to_unwrap = unwrap_trivial_block(block_expr); | ||
74 | |||
75 | Some((ast::Expr::WhileExpr(while_expr), expr_to_unwrap)) | ||
76 | } else { | ||
77 | None | ||
78 | } | ||
79 | } else if let Some(loop_expr) = ctx.find_node_at_offset::<ast::LoopExpr>() { | 53 | } else if let Some(loop_expr) = ctx.find_node_at_offset::<ast::LoopExpr>() { |
80 | // loop expression | 54 | // loop expression |
81 | let block_expr = loop_expr.loop_body()?; | 55 | let block_expr = loop_expr.loop_body()?; |
82 | let block = block_expr.block()?; | 56 | excract_expr(ctx.frange.range, block_expr) |
83 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(ctx.frange.range); | 57 | .map(|expr_to_unwrap| (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap)) |
84 | |||
85 | if cursor_in_range { | ||
86 | let expr_to_unwrap = unwrap_trivial_block(block_expr); | ||
87 | |||
88 | Some((ast::Expr::LoopExpr(loop_expr), expr_to_unwrap)) | ||
89 | } else { | ||
90 | None | ||
91 | } | ||
92 | } else { | 58 | } else { |
93 | None | 59 | None |
94 | }; | 60 | }; |
@@ -114,6 +80,17 @@ pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { | |||
114 | }) | 80 | }) |
115 | } | 81 | } |
116 | 82 | ||
83 | fn excract_expr(cursor_range: TextRange, block_expr: BlockExpr) -> Option<Expr> { | ||
84 | let block = block_expr.block()?; | ||
85 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range); | ||
86 | |||
87 | if cursor_in_range { | ||
88 | Some(unwrap_trivial_block(block_expr)) | ||
89 | } else { | ||
90 | None | ||
91 | } | ||
92 | } | ||
93 | |||
117 | #[cfg(test)] | 94 | #[cfg(test)] |
118 | mod tests { | 95 | mod tests { |
119 | use crate::helpers::{check_assist, check_assist_not_applicable}; | 96 | use crate::helpers::{check_assist, check_assist_not_applicable}; |