Skip to content

Commit 95a0de8

Browse files
committed
Support "move if to guard" with an else branch
1 parent db2a708 commit 95a0de8

File tree

1 file changed

+243
-6
lines changed

1 file changed

+243
-6
lines changed

crates/ide_assists/src/handlers/move_guard.rs

Lines changed: 243 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use syntax::{
2-
ast::{edit::AstNodeEdit, make, AstNode, BlockExpr, Expr, IfExpr, MatchArm},
3-
SyntaxKind::WHITESPACE,
2+
ast::{edit::AstNodeEdit, make, AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm},
3+
NodeOrToken,
4+
SyntaxKind::{COMMA, WHITESPACE},
45
};
56

67
use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -118,10 +119,6 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
118119
let cond = if_expr.condition()?;
119120
let then_block = if_expr.then_branch()?;
120121

121-
// Not support if with else branch
122-
if if_expr.else_branch().is_some() {
123-
return None;
124-
}
125122
// Not support moving if let to arm guard
126123
if cond.is_pattern_cond() {
127124
return None;
@@ -149,6 +146,32 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
149146
}
150147

151148
edit.insert(match_pat.syntax().text_range().end(), buf);
149+
150+
// If with only an else branch
151+
if let Some(ElseBranch::Block(else_block)) = if_expr.else_branch() {
152+
let then_arm_end = match_arm.syntax().text_range().end();
153+
if then_block.tail_expr().is_some() && then_only_expr {
154+
// Insert comma for expression if there isn't one
155+
match match_arm.syntax().last_child_or_token() {
156+
Some(NodeOrToken::Token(t)) if t.kind() == COMMA => {}
157+
_ => edit.insert(then_arm_end, ","),
158+
}
159+
}
160+
let else_only_expr = else_block.statements().next().is_none();
161+
let indent_level = match_arm.indent_level();
162+
let spaces = " ".repeat(indent_level.0 as _);
163+
edit.insert(then_arm_end, format!("\n{}{} => ", spaces, match_pat));
164+
match &else_block.tail_expr() {
165+
Some(else_expr) if else_only_expr => {
166+
edit.insert(then_arm_end, else_expr.syntax().text());
167+
edit.insert(then_arm_end, ",");
168+
}
169+
_ if replace_node != *if_expr.syntax() => {
170+
edit.insert(then_arm_end, else_block.dedent(1.into()).syntax().text());
171+
}
172+
_ => edit.insert(then_arm_end, else_block.syntax().text()),
173+
}
174+
}
152175
},
153176
)
154177
}
@@ -384,6 +407,220 @@ fn main() {
384407
_ => true
385408
}
386409
}
410+
"#,
411+
)
412+
}
413+
414+
#[test]
415+
fn move_arm_cond_to_match_guard_with_else_works() {
416+
check_assist(
417+
move_arm_cond_to_match_guard,
418+
r#"
419+
fn main() {
420+
match 92 {
421+
x => if x > 10 {$0
422+
false
423+
} else {
424+
true
425+
}
426+
_ => true,
427+
}
428+
}
429+
"#,
430+
r#"
431+
fn main() {
432+
match 92 {
433+
x if x > 10 => false,
434+
x => true,
435+
_ => true,
436+
}
437+
}
438+
"#,
439+
)
440+
}
441+
442+
#[test]
443+
fn move_arm_cond_to_match_guard_with_else_block_works() {
444+
check_assist(
445+
move_arm_cond_to_match_guard,
446+
r#"
447+
fn main() {
448+
match 92 {
449+
x => {
450+
if x > 10 {$0
451+
false
452+
} else {
453+
true
454+
}
455+
}
456+
_ => true
457+
}
458+
}
459+
"#,
460+
r#"
461+
fn main() {
462+
match 92 {
463+
x if x > 10 => false,
464+
x => true,
465+
_ => true
466+
}
467+
}
468+
"#,
469+
)
470+
}
471+
472+
#[test]
473+
fn move_arm_cond_to_match_guard_else_if_empty_body_works() {
474+
check_assist(
475+
move_arm_cond_to_match_guard,
476+
r#"
477+
fn main() {
478+
match 92 {
479+
x => if x > 10 { $0 } else { },
480+
_ => true
481+
}
482+
}
483+
"#,
484+
r#"
485+
fn main() {
486+
match 92 {
487+
x if x > 10 => { },
488+
x => { }
489+
_ => true
490+
}
491+
}
492+
"#,
493+
);
494+
}
495+
496+
#[test]
497+
fn move_arm_cond_to_match_guard_with_else_multiline_works() {
498+
check_assist(
499+
move_arm_cond_to_match_guard,
500+
r#"
501+
fn main() {
502+
match 92 {
503+
x => if x > 10 {
504+
92;$0
505+
false
506+
} else {
507+
true
508+
}
509+
_ => true
510+
}
511+
}
512+
"#,
513+
r#"
514+
fn main() {
515+
match 92 {
516+
x if x > 10 => {
517+
92;
518+
false
519+
}
520+
x => true,
521+
_ => true
522+
}
523+
}
524+
"#,
525+
)
526+
}
527+
528+
#[test]
529+
fn move_arm_cond_to_match_guard_with_else_multiline_else_works() {
530+
check_assist(
531+
move_arm_cond_to_match_guard,
532+
r#"
533+
fn main() {
534+
match 92 {
535+
x => {
536+
if x > 10 {$0
537+
false
538+
} else {
539+
42;
540+
true
541+
}
542+
}
543+
_ => true
544+
}
545+
}
546+
"#,
547+
r#"
548+
fn main() {
549+
match 92 {
550+
x if x > 10 => false,
551+
x => {
552+
42;
553+
true
554+
}
555+
_ => true
556+
}
557+
}
558+
"#,
559+
)
560+
}
561+
562+
#[test]
563+
fn move_arm_cond_to_match_guard_with_else_last_arm_works() {
564+
check_assist(
565+
move_arm_cond_to_match_guard,
566+
r#"
567+
fn main() {
568+
match 92 {
569+
3 => true,
570+
x => {
571+
if x > 10 {$0
572+
false
573+
} else {
574+
92;
575+
true
576+
}
577+
}
578+
}
579+
}
580+
"#,
581+
r#"
582+
fn main() {
583+
match 92 {
584+
3 => true,
585+
x if x > 10 => false,
586+
x => {
587+
92;
588+
true
589+
}
590+
}
591+
}
592+
"#,
593+
)
594+
}
595+
596+
#[test]
597+
fn move_arm_cond_to_match_guard_with_else_comma_works() {
598+
check_assist(
599+
move_arm_cond_to_match_guard,
600+
r#"
601+
fn main() {
602+
match 92 {
603+
3 => true,
604+
x => if x > 10 {$0
605+
false
606+
} else {
607+
92;
608+
true
609+
},
610+
}
611+
}
612+
"#,
613+
r#"
614+
fn main() {
615+
match 92 {
616+
3 => true,
617+
x if x > 10 => false,
618+
x => {
619+
92;
620+
true
621+
}
622+
}
623+
}
387624
"#,
388625
)
389626
}

0 commit comments

Comments
 (0)