diff options
Diffstat (limited to 'crates/ra_assists/src/assists/invert_if.rs')
-rw-r--r-- | crates/ra_assists/src/assists/invert_if.rs | 33 |
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 @@ | |||
1 | use ra_syntax::ast::{self, AstNode}; | 1 | use ra_syntax::ast::{self, make, AstNode}; |
2 | use ra_syntax::T; | 2 | use ra_syntax::T; |
3 | 3 | ||
4 | use crate::{Assist, AssistCtx, AssistId}; | 4 | use 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 | ||
54 | pub(crate) fn invert_boolean_expression(expr: &ast::Expr) -> Option<ast::Expr> { | 54 | pub(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 | |||
61 | pub(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 | } |