aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assists/early_return.rs54
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
24use std::ops::RangeInclusive;
2 25
3use crate::{
4 assist_ctx::{Assist, AssistCtx},
5 AssistId,
6};
7use hir::db::HirDatabase; 26use hir::db::HirDatabase;
8use ra_syntax::{ 27use 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};
19use std::ops::RangeInclusive; 33
34use crate::{
35 assist_ctx::{Assist, AssistCtx},
36 AssistId,
37};
20 38
21pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 39pub(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()