aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assists/invert_if.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/assists/invert_if.rs')
-rw-r--r--crates/ra_assists/src/assists/invert_if.rs33
1 files changed, 22 insertions, 11 deletions
diff --git a/crates/ra_assists/src/assists/invert_if.rs b/crates/ra_assists/src/assists/invert_if.rs
index 694c3642c..983392f21 100644
--- a/crates/ra_assists/src/assists/invert_if.rs
+++ b/crates/ra_assists/src/assists/invert_if.rs
@@ -1,4 +1,4 @@
1use ra_syntax::ast::{self, AstNode}; 1use ra_syntax::ast::{self, make, AstNode};
2use ra_syntax::T; 2use ra_syntax::T;
3 3
4use crate::{Assist, AssistCtx, AssistId}; 4use crate::{Assist, AssistCtx, AssistId};
@@ -35,8 +35,8 @@ pub(crate) fn invert_if(ctx: AssistCtx) -> Option<Assist> {
35 let then_node = expr.then_branch()?.syntax().clone(); 35 let then_node = expr.then_branch()?.syntax().clone();
36 36
37 if let ast::ElseBranch::Block(else_block) = expr.else_branch()? { 37 if let ast::ElseBranch::Block(else_block) = expr.else_branch()? {
38 let flip_cond = invert_boolean_expression(&cond)?;
39 let cond_range = cond.syntax().text_range(); 38 let cond_range = cond.syntax().text_range();
39 let flip_cond = invert_boolean_expression(cond);
40 let else_node = else_block.syntax(); 40 let else_node = else_block.syntax();
41 let else_range = else_node.text_range(); 41 let else_range = else_node.text_range();
42 let then_range = then_node.text_range(); 42 let then_range = then_node.text_range();
@@ -51,16 +51,23 @@ pub(crate) fn invert_if(ctx: AssistCtx) -> Option<Assist> {
51 None 51 None
52} 52}
53 53
54pub(crate) fn invert_boolean_expression(expr: &ast::Expr) -> Option<ast::Expr> { 54pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
55 if let Some(expr) = invert_special_case(&expr) {
56 return expr;
57 }
58 make::expr_prefix(T![!], expr)
59}
60
61pub(crate) fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
55 match expr { 62 match expr {
56 ast::Expr::BinExpr(bin) => match bin.op_kind()? { 63 ast::Expr::BinExpr(bin) => match bin.op_kind()? {
57 ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()), 64 ast::BinOp::NegatedEqualityTest => bin.replace_op(T![==]).map(|it| it.into()),
65 ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
58 _ => None, 66 _ => None,
59 }, 67 },
60 ast::Expr::PrefixExpr(pe) => match pe.op_kind()? { 68 ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(),
61 ast::PrefixOp::Not => pe.expr(), 69 // FIXME:
62 _ => None, 70 // ast::Expr::Literal(true | false )
63 },
64 _ => None, 71 _ => None,
65 } 72 }
66} 73}
@@ -90,12 +97,16 @@ mod tests {
90 } 97 }
91 98
92 #[test] 99 #[test]
93 fn invert_if_doesnt_apply_with_cursor_not_on_if() { 100 fn invert_if_general_case() {
94 check_assist_not_applicable(invert_if, "fn f() { if !<|>cond { 3 * 2 } else { 1 } }") 101 check_assist(
102 invert_if,
103 "fn f() { i<|>f cond { 3 * 2 } else { 1 } }",
104 "fn f() { i<|>f !cond { 1 } else { 3 * 2 } }",
105 )
95 } 106 }
96 107
97 #[test] 108 #[test]
98 fn invert_if_doesnt_apply_without_negated() { 109 fn invert_if_doesnt_apply_with_cursor_not_on_if() {
99 check_assist_not_applicable(invert_if, "fn f() { i<|>f cond { 3 * 2 } else { 1 } }") 110 check_assist_not_applicable(invert_if, "fn f() { if !<|>cond { 3 * 2 } else { 1 } }")
100 } 111 }
101} 112}