2
2
//! This assist transforms boolean expressions of the form `!a || !b` into
3
3
//! `!(a && b)`.
4
4
use hir:: db:: HirDatabase ;
5
- use ra_syntax:: ast:: { AstNode , BinExpr , BinOp , Expr , PrefixOp } ;
5
+ use ra_syntax:: ast:: { self , AstNode } ;
6
6
use ra_syntax:: SyntaxNode ;
7
7
8
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
10
/// Assist for applying demorgan's law
42
11
///
43
12
/// This transforms expressions of the form `!l || !r` into `!(l && r)`.
44
13
/// This also works with `&&`. This assist can only be applied with the cursor
45
14
/// on either `||` or `&&`, with both operands being a negation of some kind.
46
15
/// This means something of the form `!x` or `x != y`.
47
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
18
let op = expr. op_kind ( ) ?;
50
19
let op_range = expr. op_token ( ) ?. text_range ( ) ;
51
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
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
72
#[ cfg( test) ]
73
73
mod tests {
74
74
use super :: * ;
0 commit comments