diff options
| author | Shoyu Vanilla (Flint) <modulo641@gmail.com> | 2025-09-26 08:58:07 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-26 08:58:07 +0000 |
| commit | 8d4c00def0cc0657645b3ac956a7a35e4639871a (patch) | |
| tree | 49cae8ad9cd9edf75e60ff1a338e24a4c80fbc29 /src/tools | |
| parent | a7df846d55a31b3c4cd796a9a8628f60938ec4c5 (diff) | |
| parent | 1bf57df7d72333bb4289d8f7072e8e170ad54ce2 (diff) | |
| download | rust-8d4c00def0cc0657645b3ac956a7a35e4639871a.tar.gz rust-8d4c00def0cc0657645b3ac956a7a35e4639871a.zip | |
Merge pull request #20599 from A4-Tacks/bang-de-morgan
Add applicable on bang `!` for apply_demorgan
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 753a9e56c35..53a0a11998a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -6,7 +6,7 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - SyntaxKind, T, + NodeOrToken, SyntaxKind, T, ast::{ self, AstNode, Expr::BinExpr, @@ -38,15 +38,27 @@ use crate::{AssistContext, AssistId, Assists, utils::invert_boolean_expression}; // } // ``` pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let mut bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?; + let mut bin_expr = if let Some(not) = ctx.find_token_syntax_at_offset(T![!]) + && let Some(NodeOrToken::Node(next)) = not.next_sibling_or_token() + && let Some(paren) = ast::ParenExpr::cast(next) + && let Some(ast::Expr::BinExpr(bin_expr)) = paren.expr() + { + bin_expr + } else { + let bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?; + let op_range = bin_expr.op_token()?.text_range(); + + // Is the cursor on the expression's logical operator? + if !op_range.contains_range(ctx.selection_trimmed()) { + return None; + } + + bin_expr + }; + let op = bin_expr.op_kind()?; let op_range = bin_expr.op_token()?.text_range(); - // Is the cursor on the expression's logical operator? - if !op_range.contains_range(ctx.selection_trimmed()) { - return None; - } - // Walk up the tree while we have the same binary operator while let Some(parent_expr) = bin_expr.syntax().parent().and_then(ast::BinExpr::cast) { match parent_expr.op_kind() { @@ -367,6 +379,15 @@ fn f() { !(S <= S || S < S) } } #[test] + fn demorgan_on_not() { + check_assist( + apply_demorgan, + "fn f() { $0!(1 || 3 && 4 || 5) }", + "fn f() { !1 && !(3 && 4) && !5 }", + ) + } + + #[test] fn demorgan_keep_pars_for_op_precedence() { check_assist( apply_demorgan, |
