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.rs84
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,