Merge #11017
11017: Support "move if to guard" with an else branch r=Veykril a=weirane
Support the assist `move_arm_cond_to_match_guard` when there is an else branch.
I have two questions:
1. How to indent the first line of a match arm? `matcharm.indent()` doesn't seem to work. so I hard coded four spaces here:
95a0de85d5/crates/ide_assists/src/handlers/move_guard.rs (L162-L163)
2. I find a little issue in the original implementation, this code
```rust
let y = match 92 {
x => {
if x == 0 {$0
false
}
}
_ => true,
};
```
will be transformed to
```rust
let y = match 92 {
x if x == 0 => false
_ => true,
};
```
a comma is missing after the `false`. Should I also fix that? Or this can go in a separate PR.
Closes #10997.
Co-authored-by: Wang Ruochen <wrc@ruo-chen.wang>
This commit is contained in:
commit
4ec6bd6206
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -384,6 +412,255 @@ fn main() {
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user