aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-05-01 15:41:29 +0100
committerBenjamin Coenen <[email protected]>2020-05-01 15:41:29 +0100
commitdf7899e47a83fb5544d09d2db9405762d3ce29b7 (patch)
tree3a9ad151b5ce6688ae617071bc2a04dd68a9078b /crates/ra_assists/src
parentdc34162450797f5756ce2b44f1a3fe73d8e2dce4 (diff)
Add unwrap block assist #4156
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs69
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 @@
1use crate::{Assist, AssistCtx, AssistId}; 1use crate::{Assist, AssistCtx, AssistId};
2 2
3use ast::LoopBodyOwner; 3use ast::{BlockExpr, Expr, LoopBodyOwner};
4use ra_fmt::unwrap_trivial_block; 4use ra_fmt::unwrap_trivial_block;
5use ra_syntax::{ast, AstNode}; 5use 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
83fn 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)]
118mod tests { 95mod tests {
119 use crate::helpers::{check_assist, check_assist_not_applicable}; 96 use crate::helpers::{check_assist, check_assist_not_applicable};