diff options
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r-- | crates/ra_assists/src/handlers/unwrap_block.rs | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs index b407eb870..859c70ad8 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::{BlockExpr, Expr, ForExpr, IfExpr, LoopBodyOwner, LoopExpr, WhileExpr}; | 3 | use ast::LoopBodyOwner; |
4 | use ra_fmt::unwrap_trivial_block; | 4 | use ra_fmt::unwrap_trivial_block; |
5 | use ra_syntax::{ast, AstNode, TextRange, T}; | 5 | use ra_syntax::{ast, match_ast, AstNode, TextRange, T}; |
6 | 6 | ||
7 | // Assist: unwrap_block | 7 | // Assist: unwrap_block |
8 | // | 8 | // |
@@ -23,37 +23,38 @@ use ra_syntax::{ast, AstNode, TextRange, T}; | |||
23 | // ``` | 23 | // ``` |
24 | pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { | 24 | pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { |
25 | let l_curly_token = ctx.find_token_at_offset(T!['{'])?; | 25 | let l_curly_token = ctx.find_token_at_offset(T!['{'])?; |
26 | 26 | let block = ast::BlockExpr::cast(l_curly_token.parent())?; | |
27 | let (expr, expr_to_unwrap) = if let Some(if_expr) = | 27 | let parent = block.syntax().parent()?; |
28 | l_curly_token.ancestors().find_map(IfExpr::cast) | 28 | let (expr, expr_to_unwrap) = match_ast! { |
29 | { | 29 | match parent { |
30 | // if expression | 30 | ast::IfExpr(if_expr) => { |
31 | let expr_to_unwrap = if_expr.blocks().find_map(|expr| extract_expr(ctx.frange.range, expr)); | 31 | let expr_to_unwrap = if_expr.blocks().find_map(|expr| extract_expr(ctx.frange.range, expr)); |
32 | let expr_to_unwrap = expr_to_unwrap?; | 32 | let expr_to_unwrap = expr_to_unwrap?; |
33 | // Find if we are in a else if block | 33 | // Find if we are in a else if block |
34 | let ancestor = if_expr.syntax().ancestors().skip(1).find_map(ast::IfExpr::cast); | 34 | let ancestor = if_expr.syntax().parent().and_then(ast::IfExpr::cast); |
35 | 35 | ||
36 | match ancestor { | 36 | match ancestor { |
37 | None => (ast::Expr::IfExpr(if_expr), expr_to_unwrap), | 37 | None => (ast::Expr::IfExpr(if_expr), expr_to_unwrap), |
38 | Some(ancestor) => (ast::Expr::IfExpr(ancestor), expr_to_unwrap), | 38 | Some(ancestor) => (ast::Expr::IfExpr(ancestor), expr_to_unwrap), |
39 | } | ||
40 | }, | ||
41 | ast::ForExpr(for_expr) => { | ||
42 | let block_expr = for_expr.loop_body()?; | ||
43 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
44 | (ast::Expr::ForExpr(for_expr), expr_to_unwrap) | ||
45 | }, | ||
46 | ast::WhileExpr(while_expr) => { | ||
47 | let block_expr = while_expr.loop_body()?; | ||
48 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
49 | (ast::Expr::WhileExpr(while_expr), expr_to_unwrap) | ||
50 | }, | ||
51 | ast::LoopExpr(loop_expr) => { | ||
52 | let block_expr = loop_expr.loop_body()?; | ||
53 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
54 | (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap) | ||
55 | }, | ||
56 | _ => return None, | ||
39 | } | 57 | } |
40 | } else if let Some(for_expr) = l_curly_token.ancestors().find_map(ForExpr::cast) { | ||
41 | // for expression | ||
42 | let block_expr = for_expr.loop_body()?; | ||
43 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
44 | (ast::Expr::ForExpr(for_expr), expr_to_unwrap) | ||
45 | } else if let Some(while_expr) = l_curly_token.ancestors().find_map(WhileExpr::cast) { | ||
46 | // while expression | ||
47 | let block_expr = while_expr.loop_body()?; | ||
48 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
49 | (ast::Expr::WhileExpr(while_expr), expr_to_unwrap) | ||
50 | } else if let Some(loop_expr) = l_curly_token.ancestors().find_map(LoopExpr::cast) { | ||
51 | // loop expression | ||
52 | let block_expr = loop_expr.loop_body()?; | ||
53 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
54 | (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap) | ||
55 | } else { | ||
56 | return None; | ||
57 | }; | 58 | }; |
58 | 59 | ||
59 | ctx.add_assist(AssistId("unwrap_block"), "Unwrap block", |edit| { | 60 | ctx.add_assist(AssistId("unwrap_block"), "Unwrap block", |edit| { |
@@ -76,7 +77,7 @@ pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { | |||
76 | }) | 77 | }) |
77 | } | 78 | } |
78 | 79 | ||
79 | fn extract_expr(cursor_range: TextRange, block: BlockExpr) -> Option<Expr> { | 80 | fn extract_expr(cursor_range: TextRange, block: ast::BlockExpr) -> Option<ast::Expr> { |
80 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range); | 81 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range); |
81 | 82 | ||
82 | if cursor_in_range { | 83 | if cursor_in_range { |