Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_assists/src/handlers/move_guard.rs')
-rw-r--r--crates/ide_assists/src/handlers/move_guard.rs289
1 files changed, 283 insertions, 6 deletions
diff --git a/crates/ide_assists/src/handlers/move_guard.rs b/crates/ide_assists/src/handlers/move_guard.rs
index d7e7c363af..2f44ca40ab 100644
--- a/crates/ide_assists/src/handlers/move_guard.rs
+++ b/crates/ide_assists/src/handlers/move_guard.rs
@@ -1,6 +1,7 @@
use syntax::{
- ast::{edit::AstNodeEdit, make, AstNode, BlockExpr, Expr, IfExpr, MatchArm},
- SyntaxKind::WHITESPACE,
+ ast::{edit::AstNodeEdit, make, AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm},
+ NodeOrToken,
+ SyntaxKind::{COMMA, WHITESPACE},
};
use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -118,10 +119,6 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
let cond = if_expr.condition()?;
let then_block = if_expr.then_branch()?;
- // Not support if with else branch
- if if_expr.else_branch().is_some() {
- return None;
- }
// Not support moving if let to arm guard
if cond.is_pattern_cond() {
return None;
@@ -149,6 +146,37 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
}
edit.insert(match_pat.syntax().text_range().end(), buf);
+
+ // If with only an else branch
+ if let Some(ElseBranch::Block(else_block)) = if_expr.else_branch() {
+ let then_arm_end = match_arm.syntax().text_range().end();
+ if then_block.tail_expr().is_some() && then_only_expr {
+ // Insert comma for expression if there isn't one
+ match match_arm.syntax().last_child_or_token() {
+ Some(NodeOrToken::Token(t)) if t.kind() == COMMA => {}
+ _ => edit.insert(then_arm_end, ","),
+ }
+ }
+ let else_only_expr = else_block.statements().next().is_none();
+ let indent_level = match_arm.indent_level();
+ let spaces = " ".repeat(indent_level.0 as _);
+ edit.insert(then_arm_end, format!("\n{}{} => ", spaces, match_pat));
+ match &else_block.tail_expr() {
+ Some(else_expr) if else_only_expr => {
+ cov_mark::hit!(move_guard_ifelse_expr_only);
+ edit.insert(then_arm_end, else_expr.syntax().text());
+ edit.insert(then_arm_end, ",");
+ }
+ _ if replace_node != *if_expr.syntax() => {
+ cov_mark::hit!(move_guard_ifelse_in_block);
+ edit.insert(then_arm_end, else_block.dedent(1.into()).syntax().text());
+ }
+ _ => {
+ cov_mark::hit!(move_guard_ifelse_else_block);
+ edit.insert(then_arm_end, else_block.syntax().text());
+ }
+ }
+ }
},
)
}
@@ -387,4 +415,253 @@ fn main() {
"#,
)
}
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_works() {
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => if x > 10 {$0
+ false
+ } else {
+ true
+ }
+ _ => true,
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => false,
+ x => true,
+ _ => true,
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_block_works() {
+ cov_mark::check!(move_guard_ifelse_expr_only);
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => {
+ if x > 10 {$0
+ false
+ } else {
+ true
+ }
+ }
+ _ => true
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => false,
+ x => true,
+ _ => true
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_else_if_empty_body_works() {
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => if x > 10 { $0 } else { },
+ _ => true
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => { },
+ x => { }
+ _ => true
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_multiline_works() {
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => if x > 10 {
+ 92;$0
+ false
+ } else {
+ true
+ }
+ _ => true
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => {
+ 92;
+ false
+ }
+ x => true,
+ _ => true
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_multiline_else_works() {
+ cov_mark::check!(move_guard_ifelse_else_block);
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => if x > 10 {$0
+ false
+ } else {
+ 42;
+ true
+ }
+ _ => true
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => false,
+ x => {
+ 42;
+ true
+ }
+ _ => true
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_multiline_else_block_works() {
+ cov_mark::check!(move_guard_ifelse_in_block);
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ x => {
+ if x > 10 {$0
+ false
+ } else {
+ 42;
+ true
+ }
+ }
+ _ => true
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ x if x > 10 => false,
+ x => {
+ 42;
+ true
+ }
+ _ => true
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_last_arm_works() {
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ 3 => true,
+ x => {
+ if x > 10 {$0
+ false
+ } else {
+ 92;
+ true
+ }
+ }
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ 3 => true,
+ x if x > 10 => false,
+ x => {
+ 92;
+ true
+ }
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn move_arm_cond_to_match_guard_with_else_comma_works() {
+ check_assist(
+ move_arm_cond_to_match_guard,
+ r#"
+fn main() {
+ match 92 {
+ 3 => true,
+ x => if x > 10 {$0
+ false
+ } else {
+ 92;
+ true
+ },
+ }
+}
+"#,
+ r#"
+fn main() {
+ match 92 {
+ 3 => true,
+ x if x > 10 => false,
+ x => {
+ 92;
+ true
+ }
+ }
+}
+"#,
+ )
+ }
}