Skip to content

Commit 9edd2ad

Browse files
committed
Add applicable on bang ! for apply_demorgan
Example --- ```rust fn f() { $0!(1 || 3 && 4 || 5) } ``` -> ```rust fn f() { !1 && !(3 && 4) && !5 } ```
1 parent 1f4e5e8 commit 9edd2ad

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

crates/ide-assists/src/handlers/apply_demorgan.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ide_db::{
66
syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
77
};
88
use syntax::{
9-
SyntaxKind, T,
9+
NodeOrToken, SyntaxKind, T,
1010
ast::{
1111
self, AstNode,
1212
Expr::BinExpr,
@@ -38,15 +38,27 @@ use crate::{AssistContext, AssistId, Assists, utils::invert_boolean_expression};
3838
// }
3939
// ```
4040
pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
41-
let mut bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
41+
let mut bin_expr = if let Some(not) = ctx.find_token_syntax_at_offset(T![!])
42+
&& let Some(NodeOrToken::Node(next)) = not.next_sibling_or_token()
43+
&& let Some(paren) = ast::ParenExpr::cast(next)
44+
&& let Some(ast::Expr::BinExpr(bin_expr)) = paren.expr()
45+
{
46+
bin_expr
47+
} else {
48+
let bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
49+
let op_range = bin_expr.op_token()?.text_range();
50+
51+
// Is the cursor on the expression's logical operator?
52+
if !op_range.contains_range(ctx.selection_trimmed()) {
53+
return None;
54+
}
55+
56+
bin_expr
57+
};
58+
4259
let op = bin_expr.op_kind()?;
4360
let op_range = bin_expr.op_token()?.text_range();
4461

45-
// Is the cursor on the expression's logical operator?
46-
if !op_range.contains_range(ctx.selection_trimmed()) {
47-
return None;
48-
}
49-
5062
// Walk up the tree while we have the same binary operator
5163
while let Some(parent_expr) = bin_expr.syntax().parent().and_then(ast::BinExpr::cast) {
5264
match parent_expr.op_kind() {
@@ -366,6 +378,15 @@ fn f() { !(S <= S || S < S) }
366378
)
367379
}
368380

381+
#[test]
382+
fn demorgan_on_not() {
383+
check_assist(
384+
apply_demorgan,
385+
"fn f() { $0!(1 || 3 && 4 || 5) }",
386+
"fn f() { !1 && !(3 && 4) && !5 }",
387+
)
388+
}
389+
369390
#[test]
370391
fn demorgan_keep_pars_for_op_precedence() {
371392
check_assist(

0 commit comments

Comments
 (0)