diff options
-rw-r--r-- | crates/ra_assists/src/assists/early_return.rs | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs index 8c975714c..9c95adc53 100644 --- a/crates/ra_assists/src/assists/early_return.rs +++ b/crates/ra_assists/src/assists/early_return.rs | |||
@@ -1,32 +1,50 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Assist: `convert_to_guarded_return` |
2 | //! | ||
3 | //! Replace a large conditional with a guarded return. | ||
4 | //! | ||
5 | //! ```notrust | ||
6 | //! fn <|>main() { | ||
7 | //! if cond { | ||
8 | //! foo(); | ||
9 | //! bar(); | ||
10 | //! } | ||
11 | //! } | ||
12 | //! ``` | ||
13 | //! -> | ||
14 | //! ```notrust | ||
15 | //! fn main() { | ||
16 | //! if !cond { | ||
17 | //! return; | ||
18 | //! } | ||
19 | //! foo(); | ||
20 | //! bar(); | ||
21 | //! } | ||
22 | //! ``` | ||
23 | |||
24 | use std::ops::RangeInclusive; | ||
2 | 25 | ||
3 | use crate::{ | ||
4 | assist_ctx::{Assist, AssistCtx}, | ||
5 | AssistId, | ||
6 | }; | ||
7 | use hir::db::HirDatabase; | 26 | use hir::db::HirDatabase; |
8 | use ra_syntax::{ | 27 | use ra_syntax::{ |
9 | algo::replace_children, | 28 | algo::replace_children, |
10 | ast::edit::IndentLevel, | 29 | ast::{self, edit::IndentLevel, make}, |
11 | ast::make, | ||
12 | ast::Block, | ||
13 | ast::ContinueExpr, | ||
14 | ast::IfExpr, | ||
15 | ast::ReturnExpr, | ||
16 | AstNode, | 30 | AstNode, |
17 | SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, | 31 | SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, |
18 | }; | 32 | }; |
19 | use std::ops::RangeInclusive; | 33 | |
34 | use crate::{ | ||
35 | assist_ctx::{Assist, AssistCtx}, | ||
36 | AssistId, | ||
37 | }; | ||
20 | 38 | ||
21 | pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 39 | pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
22 | let if_expr: IfExpr = ctx.node_at_offset()?; | 40 | let if_expr: ast::IfExpr = ctx.node_at_offset()?; |
23 | let expr = if_expr.condition()?.expr()?; | 41 | let expr = if_expr.condition()?.expr()?; |
24 | let then_block = if_expr.then_branch()?.block()?; | 42 | let then_block = if_expr.then_branch()?.block()?; |
25 | if if_expr.else_branch().is_some() { | 43 | if if_expr.else_branch().is_some() { |
26 | return None; | 44 | return None; |
27 | } | 45 | } |
28 | 46 | ||
29 | let parent_block = if_expr.syntax().parent()?.ancestors().find_map(Block::cast)?; | 47 | let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::Block::cast)?; |
30 | 48 | ||
31 | if parent_block.expr()? != if_expr.clone().into() { | 49 | if parent_block.expr()? != if_expr.clone().into() { |
32 | return None; | 50 | return None; |
@@ -34,11 +52,11 @@ pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx<impl HirDatabase>) -> | |||
34 | 52 | ||
35 | // check for early return and continue | 53 | // check for early return and continue |
36 | let first_in_then_block = then_block.syntax().first_child()?.clone(); | 54 | let first_in_then_block = then_block.syntax().first_child()?.clone(); |
37 | if ReturnExpr::can_cast(first_in_then_block.kind()) | 55 | if ast::ReturnExpr::can_cast(first_in_then_block.kind()) |
38 | || ContinueExpr::can_cast(first_in_then_block.kind()) | 56 | || ast::ContinueExpr::can_cast(first_in_then_block.kind()) |
39 | || first_in_then_block | 57 | || first_in_then_block |
40 | .children() | 58 | .children() |
41 | .any(|x| ReturnExpr::can_cast(x.kind()) || ContinueExpr::can_cast(x.kind())) | 59 | .any(|x| ast::ReturnExpr::can_cast(x.kind()) || ast::ContinueExpr::can_cast(x.kind())) |
42 | { | 60 | { |
43 | return None; | 61 | return None; |
44 | } | 62 | } |
@@ -86,7 +104,7 @@ pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx<impl HirDatabase>) -> | |||
86 | &mut new_if_and_then_statements, | 104 | &mut new_if_and_then_statements, |
87 | ); | 105 | ); |
88 | edit.target(if_expr.syntax().text_range()); | 106 | edit.target(if_expr.syntax().text_range()); |
89 | edit.replace_ast(parent_block, Block::cast(new_block).unwrap()); | 107 | edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); |
90 | edit.set_cursor(cursor_position); | 108 | edit.set_cursor(cursor_position); |
91 | }); | 109 | }); |
92 | ctx.build() | 110 | ctx.build() |