aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assists/apply_demorgan.rs66
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)`.
4use hir::db::HirDatabase; 4use hir::db::HirDatabase;
5use ra_syntax::ast::{AstNode, BinExpr, BinOp, Expr, PrefixOp}; 5use ra_syntax::ast::{self, AstNode};
6use ra_syntax::SyntaxNode; 6use ra_syntax::SyntaxNode;
7 7
8use crate::{Assist, AssistCtx, AssistId}; 8use crate::{Assist, AssistCtx, AssistId};
9 9
10// Return the opposite text for a given logical operator, if it makes sense
11fn 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
20fn 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`.
47pub(crate) fn apply_demorgan(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 16pub(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
42fn 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
51fn 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)]
73mod tests { 73mod tests {
74 use super::*; 74 use super::*;