diff options
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r-- | crates/ra_assists/src/assists/apply_demorgan.rs | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs index caecc50cc..5f2b0dd18 100644 --- a/crates/ra_assists/src/assists/apply_demorgan.rs +++ b/crates/ra_assists/src/assists/apply_demorgan.rs | |||
@@ -2,42 +2,11 @@ | |||
2 | //! This assist transforms boolean expressions of the form `!a || !b` into | 2 | //! This assist transforms boolean expressions of the form `!a || !b` into |
3 | //! `!(a && b)`. | 3 | //! `!(a && b)`. |
4 | use hir::db::HirDatabase; | 4 | use hir::db::HirDatabase; |
5 | use ra_syntax::ast::{AstNode, BinExpr, BinOp, Expr, PrefixOp}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | use ra_syntax::SyntaxNode; | 6 | use ra_syntax::SyntaxNode; |
7 | 7 | ||
8 | use crate::{Assist, AssistCtx, AssistId}; | 8 | use crate::{Assist, AssistCtx, AssistId}; |
9 | 9 | ||
10 | // Return the opposite text for a given logical operator, if it makes sense | ||
11 | fn opposite_logic_op(kind: BinOp) -> Option<&'static str> { | ||
12 | match kind { | ||
13 | BinOp::BooleanOr => Some("&&"), | ||
14 | BinOp::BooleanAnd => Some("||"), | ||
15 | _ => None, | ||
16 | } | ||
17 | } | ||
18 | |||
19 | // This function tries to undo unary negation, or inequality | ||
20 | fn undo_negation(node: SyntaxNode) -> Option<String> { | ||
21 | match Expr::cast(node)? { | ||
22 | Expr::BinExpr(bin) => match bin.op_kind()? { | ||
23 | BinOp::NegatedEqualityTest => { | ||
24 | let lhs = bin.lhs()?.syntax().text(); | ||
25 | let rhs = bin.rhs()?.syntax().text(); | ||
26 | Some(format!("{} == {}", lhs, rhs)) | ||
27 | } | ||
28 | _ => None, | ||
29 | }, | ||
30 | Expr::PrefixExpr(pe) => match pe.op_kind()? { | ||
31 | PrefixOp::Not => { | ||
32 | let child = pe.expr()?.syntax().text(); | ||
33 | Some(String::from(child)) | ||
34 | } | ||
35 | _ => None, | ||
36 | }, | ||
37 | _ => None, | ||
38 | } | ||
39 | } | ||
40 | |||
41 | /// Assist for applying demorgan's law | 10 | /// Assist for applying demorgan's law |
42 | /// | 11 | /// |
43 | /// This transforms expressions of the form `!l || !r` into `!(l && r)`. | 12 | /// This transforms expressions of the form `!l || !r` into `!(l && r)`. |
@@ -45,7 +14,7 @@ fn undo_negation(node: SyntaxNode) -> Option<String> { | |||
45 | /// on either `||` or `&&`, with both operands being a negation of some kind. | 14 | /// on either `||` or `&&`, with both operands being a negation of some kind. |
46 | /// This means something of the form `!x` or `x != y`. | 15 | /// This means something of the form `!x` or `x != y`. |
47 | pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 16 | pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
48 | let expr = ctx.node_at_offset::<BinExpr>()?; | 17 | let expr = ctx.node_at_offset::<ast::BinExpr>()?; |
49 | let op = expr.op_kind()?; | 18 | let op = expr.op_kind()?; |
50 | let op_range = expr.op_token()?.text_range(); | 19 | let op_range = expr.op_token()?.text_range(); |
51 | let opposite_op = opposite_logic_op(op)?; | 20 | let opposite_op = opposite_logic_op(op)?; |
@@ -69,6 +38,37 @@ pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Ass | |||
69 | ctx.build() | 38 | ctx.build() |
70 | } | 39 | } |
71 | 40 | ||
41 | // Return the opposite text for a given logical operator, if it makes sense | ||
42 | fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> { | ||
43 | match kind { | ||
44 | ast::BinOp::BooleanOr => Some("&&"), | ||
45 | ast::BinOp::BooleanAnd => Some("||"), | ||
46 | _ => None, | ||
47 | } | ||
48 | } | ||
49 | |||
50 | // This function tries to undo unary negation, or inequality | ||
51 | fn undo_negation(node: SyntaxNode) -> Option<String> { | ||
52 | match ast::Expr::cast(node)? { | ||
53 | ast::Expr::BinExpr(bin) => match bin.op_kind()? { | ||
54 | ast::BinOp::NegatedEqualityTest => { | ||
55 | let lhs = bin.lhs()?.syntax().text(); | ||
56 | let rhs = bin.rhs()?.syntax().text(); | ||
57 | Some(format!("{} == {}", lhs, rhs)) | ||
58 | } | ||
59 | _ => None, | ||
60 | }, | ||
61 | ast::Expr::PrefixExpr(pe) => match pe.op_kind()? { | ||
62 | ast::PrefixOp::Not => { | ||
63 | let child = pe.expr()?.syntax().text(); | ||
64 | Some(String::from(child)) | ||
65 | } | ||
66 | _ => None, | ||
67 | }, | ||
68 | _ => None, | ||
69 | } | ||
70 | } | ||
71 | |||
72 | #[cfg(test)] | 72 | #[cfg(test)] |
73 | mod tests { | 73 | mod tests { |
74 | use super::*; | 74 | use super::*; |