From 0f42a71806ad62cd042dd40ab42501180fb72999 Mon Sep 17 00:00:00 2001 From: Jesse Bakker Date: Tue, 15 Dec 2020 16:25:57 +0100 Subject: Parenthesize composite if condition before inverting in invert-if assist --- crates/assists/src/handlers/invert_if.rs | 9 +++++++++ crates/assists/src/utils.rs | 4 ++++ crates/syntax/src/ast/make.rs | 3 +++ 3 files changed, 16 insertions(+) (limited to 'crates') diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs index ea722b91b..91e2f5c8c 100644 --- a/crates/assists/src/handlers/invert_if.rs +++ b/crates/assists/src/handlers/invert_if.rs @@ -68,6 +68,15 @@ mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; + #[test] + fn invert_if_composite_condition() { + check_assist( + invert_if, + "fn f() { i<|>f x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", + "fn f() { if !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", + ) + } + #[test] fn invert_if_remove_inequality() { check_assist( diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 01f5c291f..f2cacf7c8 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -212,6 +212,10 @@ fn invert_special_case(expr: &ast::Expr) -> Option { ast::Expr::BinExpr(bin) => match bin.op_kind()? { ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()), ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()), + // Parenthesize composite boolean expressions before prefixing `!` + ast::BinOp::BooleanAnd | ast::BinOp::BooleanOr => { + Some(make::expr_prefix(T![!], make::expr_paren(expr.clone()))) + } _ => None, }, ast::Expr::MethodCallExpr(mce) => { diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index cc09b77a5..16b079c42 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -196,6 +196,9 @@ pub fn expr_method_call(receiver: ast::Expr, method: &str, arg_list: ast::ArgLis pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr { expr_from_text(&if exclusive { format!("&mut {}", expr) } else { format!("&{}", expr) }) } +pub fn expr_paren(expr: ast::Expr) -> ast::Expr { + expr_from_text(&format!("({})", expr)) +} fn expr_from_text(text: &str) -> ast::Expr { ast_from_text(&format!("const C: () = {};", text)) } -- cgit v1.2.3