]> git.lizzy.rs Git - rust.git/commitdiff
Parenthesize composite if condition before inverting in invert-if assist
authorJesse Bakker <github@jessebakker.com>
Tue, 15 Dec 2020 15:25:57 +0000 (16:25 +0100)
committerJesse Bakker <github@jessebakker.com>
Tue, 15 Dec 2020 15:25:57 +0000 (16:25 +0100)
crates/assists/src/handlers/invert_if.rs
crates/assists/src/utils.rs
crates/syntax/src/ast/make.rs

index ea722b91b2da65bd1878c93549fe92cd247f933f..91e2f5c8cb33f93fe1088d48a0364214c18eb211 100644 (file)
@@ -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(
index 01f5c291fb3526a8ac8289219f805160e09d12ba..f2cacf7c80a4fe83e0b8ab2fbef07e32ffa54c24 100644 (file)
@@ -212,6 +212,10 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
         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) => {
index cc09b77a590348f1add8d7bab956ed813ba20a0a..16b079c42acf04a71d82a2c6fc02fbe6f6605c07 100644 (file)
@@ -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))
 }