Skip to main content

ide_assists/handlers/
remove_else_branches.rs

1use syntax::{AstNode, SyntaxKind, T, TextRange, ast};
2
3use crate::{AssistContext, AssistId, Assists};
4
5// Assist: remove_else_branches
6//
7// Removes the `else` keyword and else branches.
8//
9// ```
10// fn main() {
11//     if true {
12//         let _ = 2;
13//     } $0else {
14//         unreachable!();
15//     }
16// }
17// ```
18// ->
19// ```
20// fn main() {
21//     if true {
22//         let _ = 2;
23//     }
24// }
25// ```
26// ---
27// ```
28// fn main() {
29//     let _x = 2 $0else { unreachable!() };
30// }
31// ```
32// ->
33// ```
34// fn main() {
35//     let _x = 2;
36// }
37// ```
38pub(crate) fn remove_else_branches(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
39    let else_token = ctx.find_token_syntax_at_offset(T![else])?;
40    let else_branches = ctx
41        .find_node_at_range::<ast::IfExpr>()
42        .and_then(|if_expr| if_expr.else_branch()?.syntax().clone().into())
43        .or_else(|| {
44            ctx.find_node_at_range::<ast::LetStmt>()?
45                .let_else()?
46                .block_expr()?
47                .syntax()
48                .clone()
49                .into()
50        })?;
51
52    let target = TextRange::cover(else_token.text_range(), else_branches.text_range());
53    acc.add(
54        AssistId::refactor("remove_else_branches"),
55        "Remove `else` branches",
56        target,
57        |builder| {
58            let editor = builder.make_editor(&else_token.parent().unwrap());
59            match else_token.prev_token() {
60                Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it),
61                _ => (),
62            }
63            match else_token.next_token() {
64                Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it),
65                _ => (),
66            }
67            editor.delete(else_token);
68            editor.delete(else_branches);
69            builder.add_file_edits(ctx.vfs_file_id(), editor);
70        },
71    )
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::tests::check_assist_not_applicable;
78
79    #[test]
80    fn test_remove_else_branches_not_on_else_token() {
81        check_assist_not_applicable(
82            remove_else_branches,
83            r#"
84fn main() {
85    let _x = 2 else {$0 unreachable!() };
86}
87"#,
88        );
89    }
90}