mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
Merge #7861
7861: Special-case parenthesized and negated expressions in demorgan assist r=lnicola a=Jesse-Bakker Fixes #7831 Co-authored-by: Jesse Bakker <github@jessebakker.com>
This commit is contained in:
commit
603481f534
1 changed files with 43 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
use syntax::ast::{self, AstNode};
|
use syntax::ast::{self, AstNode};
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
|
use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
|
||||||
|
|
||||||
|
@ -43,9 +44,36 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
||||||
"Apply De Morgan's law",
|
"Apply De Morgan's law",
|
||||||
op_range,
|
op_range,
|
||||||
|edit| {
|
|edit| {
|
||||||
|
let paren_expr = expr.syntax().parent().and_then(|parent| ast::ParenExpr::cast(parent));
|
||||||
|
|
||||||
|
let neg_expr = paren_expr
|
||||||
|
.clone()
|
||||||
|
.and_then(|paren_expr| paren_expr.syntax().parent())
|
||||||
|
.and_then(|parent| ast::PrefixExpr::cast(parent))
|
||||||
|
.and_then(|prefix_expr| {
|
||||||
|
if prefix_expr.op_kind().unwrap() == ast::PrefixOp::Not {
|
||||||
|
Some(prefix_expr)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
edit.replace(op_range, opposite_op);
|
edit.replace(op_range, opposite_op);
|
||||||
edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
|
|
||||||
edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
|
if let Some(paren_expr) = paren_expr {
|
||||||
|
edit.replace(lhs_range, not_lhs.syntax().text());
|
||||||
|
edit.replace(rhs_range, not_rhs.syntax().text());
|
||||||
|
if let Some(neg_expr) = neg_expr {
|
||||||
|
mark::hit!(demorgan_double_negation);
|
||||||
|
edit.replace(neg_expr.op_token().unwrap().text_range(), "");
|
||||||
|
} else {
|
||||||
|
mark::hit!(demorgan_double_parens);
|
||||||
|
edit.replace(paren_expr.l_paren_token().unwrap().text_range(), "!(");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
|
||||||
|
edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -62,6 +90,7 @@ fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ide_db::helpers::FamousDefs;
|
use ide_db::helpers::FamousDefs;
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -156,4 +185,16 @@ fn f() {
|
||||||
fn demorgan_doesnt_apply_with_cursor_not_on_op() {
|
fn demorgan_doesnt_apply_with_cursor_not_on_op() {
|
||||||
check_assist_not_applicable(apply_demorgan, "fn f() { $0 !x || !x }")
|
check_assist_not_applicable(apply_demorgan, "fn f() { $0 !x || !x }")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn demorgan_doesnt_double_negation() {
|
||||||
|
mark::check!(demorgan_double_negation);
|
||||||
|
check_assist(apply_demorgan, "fn f() { !(x ||$0 x) }", "fn f() { (!x && !x) }")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn demorgan_doesnt_double_parens() {
|
||||||
|
mark::check!(demorgan_double_parens);
|
||||||
|
check_assist(apply_demorgan, "fn f() { (x ||$0 x) }", "fn f() { !(!x && !x) }")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue