Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/pull_assignment_up.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/pull_assignment_up.rs | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/crates/ide-assists/src/handlers/pull_assignment_up.rs b/crates/ide-assists/src/handlers/pull_assignment_up.rs index 1b0c313935..812ebf6c6e 100644 --- a/crates/ide-assists/src/handlers/pull_assignment_up.rs +++ b/crates/ide-assists/src/handlers/pull_assignment_up.rs @@ -1,3 +1,4 @@ +use either::Either; use syntax::{ AstNode, algo::find_node_at_range, @@ -52,20 +53,25 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) -> assignments: Vec::new(), }; - let tgt: ast::Expr = if let Some(if_expr) = ctx.find_node_at_offset::<ast::IfExpr>() { + let node: Either<ast::IfExpr, ast::MatchExpr> = ctx.find_node_at_offset()?; + let tgt: ast::Expr = if let Either::Left(if_expr) = node { + let if_expr = std::iter::successors(Some(if_expr), |it| { + it.syntax().parent().and_then(ast::IfExpr::cast) + }) + .last()?; collector.collect_if(&if_expr)?; if_expr.into() - } else if let Some(match_expr) = ctx.find_node_at_offset::<ast::MatchExpr>() { + } else if let Either::Right(match_expr) = node { collector.collect_match(&match_expr)?; match_expr.into() } else { return None; }; - if let Some(parent) = tgt.syntax().parent() { - if matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) { - return None; - } + if let Some(parent) = tgt.syntax().parent() + && matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) + { + return None; } let target = tgt.syntax().text_range(); @@ -90,10 +96,10 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext<'_>) -> let mut editor = SyntaxEditor::new(edit_tgt); for (stmt, rhs) in assignments { let mut stmt = stmt.syntax().clone(); - if let Some(parent) = stmt.parent() { - if ast::ExprStmt::cast(parent.clone()).is_some() { - stmt = parent.clone(); - } + if let Some(parent) = stmt.parent() + && ast::ExprStmt::cast(parent.clone()).is_some() + { + stmt = parent.clone(); } editor.replace(stmt, rhs.syntax()); } @@ -238,6 +244,37 @@ fn foo() { } #[test] + fn test_pull_assignment_up_inner_if() { + check_assist( + pull_assignment_up, + r#" +fn foo() { + let mut a = 1; + + if true { + a = 2; + } else if true { + $0a = 3; + } else { + a = 4; + } +}"#, + r#" +fn foo() { + let mut a = 1; + + a = if true { + 2 + } else if true { + 3 + } else { + 4 + }; +}"#, + ); + } + + #[test] fn test_pull_assignment_up_match() { check_assist( pull_assignment_up, @@ -277,6 +314,33 @@ fn foo() { } #[test] + fn test_pull_assignment_up_match_in_if_expr() { + check_assist( + pull_assignment_up, + r#" +fn foo() { + let x; + if true { + match true { + true => $0x = 2, + false => x = 3, + } + } +}"#, + r#" +fn foo() { + let x; + if true { + x = match true { + true => 2, + false => 3, + }; + } +}"#, + ); + } + + #[test] fn test_pull_assignment_up_assignment_expressions() { check_assist( pull_assignment_up, |