From 9cb388178f8435794ae3e09e529c414d5dd15f31 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 4 Jun 2025 10:55:08 +0800 Subject: [PATCH] Add ide-assist: remove else branches --- .../src/handlers/remove_else_branches.rs | 90 +++++++++++++++++++ crates/ide-assists/src/lib.rs | 2 + crates/ide-assists/src/tests/generated.rs | 40 +++++++++ 3 files changed, 132 insertions(+) create mode 100644 crates/ide-assists/src/handlers/remove_else_branches.rs diff --git a/crates/ide-assists/src/handlers/remove_else_branches.rs b/crates/ide-assists/src/handlers/remove_else_branches.rs new file mode 100644 index 000000000000..6a02c37015d3 --- /dev/null +++ b/crates/ide-assists/src/handlers/remove_else_branches.rs @@ -0,0 +1,90 @@ +use syntax::{AstNode, SyntaxKind, T, TextRange, ast}; + +use crate::{AssistContext, AssistId, Assists}; + +// Assist: remove_else_branches +// +// Removes the `else` keyword and else branches. +// +// ``` +// fn main() { +// if true { +// let _ = 2; +// } $0else { +// unreachable!(); +// } +// } +// ``` +// -> +// ``` +// fn main() { +// if true { +// let _ = 2; +// } +// } +// ``` +// --- +// ``` +// fn main() { +// let _x = 2 $0else { unreachable!() }; +// } +// ``` +// -> +// ``` +// fn main() { +// let _x = 2; +// } +// ``` +pub(crate) fn remove_else_branches(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let else_token = ctx.find_token_syntax_at_offset(T![else])?; + let else_branches = ctx + .find_node_at_range::() + .and_then(|if_expr| if_expr.else_branch()?.syntax().clone().into()) + .or_else(|| { + ctx.find_node_at_range::()? + .let_else()? + .block_expr()? + .syntax() + .clone() + .into() + })?; + + let target = TextRange::cover(else_token.text_range(), else_branches.text_range()); + acc.add( + AssistId::refactor("remove_else_branches"), + "Remove `else` branches", + target, + |builder| { + let mut editor = builder.make_editor(&else_token.parent().unwrap()); + match else_token.prev_token() { + Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), + _ => (), + } + match else_token.next_token() { + Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), + _ => (), + } + editor.delete(else_token); + editor.delete(else_branches); + builder.add_file_edits(ctx.vfs_file_id(), editor); + }, + ) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::check_assist_not_applicable; + + #[test] + fn test_remove_else_branches_not_on_else_token() { + check_assist_not_applicable( + remove_else_branches, + r#" +fn main() { + let _x = 2 else {$0 unreachable!() }; +} +"#, + ); + } +} diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs index c2604432032d..f4d5136c1995 100644 --- a/crates/ide-assists/src/lib.rs +++ b/crates/ide-assists/src/lib.rs @@ -199,6 +199,7 @@ mod handlers { mod qualify_path; mod raw_string; mod remove_dbg; + mod remove_else_branches; mod remove_mut; mod remove_parentheses; mod remove_underscore; @@ -337,6 +338,7 @@ mod handlers { raw_string::remove_hash, remove_dbg::remove_dbg, remove_mut::remove_mut, + remove_else_branches::remove_else_branches, remove_parentheses::remove_parentheses, remove_underscore::remove_underscore, remove_unused_imports::remove_unused_imports, diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 72f7195cbd77..74c663450c69 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -2738,6 +2738,46 @@ fn main() { ) } +#[test] +fn doctest_remove_else_branches() { + check_doc_test( + "remove_else_branches", + r#####" +fn main() { + if true { + let _ = 2; + } $0else { + unreachable!(); + } +} +"#####, + r#####" +fn main() { + if true { + let _ = 2; + } +} +"#####, + ) +} + +#[test] +fn doctest_remove_else_branches_1() { + check_doc_test( + "remove_else_branches", + r#####" +fn main() { + let _x = 2 $0else { unreachable!() }; +} +"#####, + r#####" +fn main() { + let _x = 2; +} +"#####, + ) +} + #[test] fn doctest_remove_hash() { check_doc_test(