aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assists/apply_demorgan.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-11-24 08:32:07 +0000
committerGitHub <[email protected]>2019-11-24 08:32:07 +0000
commit7b6aa7c34e5650506924decfee0a77aa9bb0a480 (patch)
tree8a8fc896efbf5f12ae55da28a370bdfe9e6ce445 /crates/ra_assists/src/assists/apply_demorgan.rs
parentf2c36e5a6f5892532dec9e6523dc0944453a384f (diff)
parentadac4fc2f21117486356063d82d79f8c3add084a (diff)
Merge #2343
2343: implement assist invert_if r=matklad a=bravomikekilo fix [issue 2219 invert if condition](https://github.com/rust-analyzer/rust-analyzer/issues/2219) I put the assist cursor range to `if` of the if expression, because both condition and body will be replaced. Is there any way to replace them without cover the cursor position? @matklad Co-authored-by: bravomikekilo <[email protected]>
Diffstat (limited to 'crates/ra_assists/src/assists/apply_demorgan.rs')
-rw-r--r--crates/ra_assists/src/assists/apply_demorgan.rs40
1 files changed, 9 insertions, 31 deletions
diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs
index 068da1774..7c57c0560 100644
--- a/crates/ra_assists/src/assists/apply_demorgan.rs
+++ b/crates/ra_assists/src/assists/apply_demorgan.rs
@@ -1,6 +1,6 @@
1use super::invert_if::invert_boolean_expression;
1use hir::db::HirDatabase; 2use hir::db::HirDatabase;
2use ra_syntax::ast::{self, AstNode}; 3use ra_syntax::ast::{self, AstNode};
3use ra_syntax::SyntaxNode;
4 4
5use crate::{Assist, AssistCtx, AssistId}; 5use crate::{Assist, AssistCtx, AssistId};
6 6
@@ -32,18 +32,18 @@ pub(crate) fn apply_demorgan(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist>
32 if !cursor_in_range { 32 if !cursor_in_range {
33 return None; 33 return None;
34 } 34 }
35 let lhs = expr.lhs()?.syntax().clone(); 35 let lhs = expr.lhs()?;
36 let lhs_range = lhs.text_range(); 36 let lhs_range = lhs.syntax().text_range();
37 let rhs = expr.rhs()?.syntax().clone(); 37 let rhs = expr.rhs()?;
38 let rhs_range = rhs.text_range(); 38 let rhs_range = rhs.syntax().text_range();
39 let not_lhs = undo_negation(lhs)?; 39 let not_lhs = invert_boolean_expression(&lhs)?;
40 let not_rhs = undo_negation(rhs)?; 40 let not_rhs = invert_boolean_expression(&rhs)?;
41 41
42 ctx.add_assist(AssistId("apply_demorgan"), "apply demorgan's law", |edit| { 42 ctx.add_assist(AssistId("apply_demorgan"), "apply demorgan's law", |edit| {
43 edit.target(op_range); 43 edit.target(op_range);
44 edit.replace(op_range, opposite_op); 44 edit.replace(op_range, opposite_op);
45 edit.replace(lhs_range, format!("!({}", not_lhs)); 45 edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
46 edit.replace(rhs_range, format!("{})", not_rhs)); 46 edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
47 }) 47 })
48} 48}
49 49
@@ -56,28 +56,6 @@ fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> {
56 } 56 }
57} 57}
58 58
59// This function tries to undo unary negation, or inequality
60fn undo_negation(node: SyntaxNode) -> Option<String> {
61 match ast::Expr::cast(node)? {
62 ast::Expr::BinExpr(bin) => match bin.op_kind()? {
63 ast::BinOp::NegatedEqualityTest => {
64 let lhs = bin.lhs()?.syntax().text();
65 let rhs = bin.rhs()?.syntax().text();
66 Some(format!("{} == {}", lhs, rhs))
67 }
68 _ => None,
69 },
70 ast::Expr::PrefixExpr(pe) => match pe.op_kind()? {
71 ast::PrefixOp::Not => {
72 let child = pe.expr()?.syntax().text();
73 Some(String::from(child))
74 }
75 _ => None,
76 },
77 _ => None,
78 }
79}
80
81#[cfg(test)] 59#[cfg(test)]
82mod tests { 60mod tests {
83 use super::*; 61 use super::*;