@@ -6,9 +6,16 @@ use ide_db::{
66 syntax_helpers:: node_ext:: { for_each_tail_expr, walk_expr} ,
77} ;
88use syntax:: {
9- ast:: { self , syntax_factory:: SyntaxFactory , AstNode , Expr :: BinExpr , HasArgList } ,
9+ ast:: {
10+ self ,
11+ prec:: { precedence, ExprPrecedence } ,
12+ syntax_factory:: SyntaxFactory ,
13+ AstNode ,
14+ Expr :: BinExpr ,
15+ HasArgList ,
16+ } ,
1017 syntax_editor:: { Position , SyntaxEditor } ,
11- SyntaxKind , SyntaxNode , T ,
18+ SyntaxKind , T ,
1219} ;
1320
1421use crate :: { utils:: invert_boolean_expression, AssistContext , AssistId , AssistKind , Assists } ;
@@ -52,9 +59,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
5259 }
5360
5461 let op = bin_expr. op_kind ( ) ?;
55- let inv_token = match op {
56- ast:: BinaryOp :: LogicOp ( ast:: LogicOp :: And ) => SyntaxKind :: PIPE2 ,
57- ast:: BinaryOp :: LogicOp ( ast:: LogicOp :: Or ) => SyntaxKind :: AMP2 ,
62+ let ( inv_token, prec ) = match op {
63+ ast:: BinaryOp :: LogicOp ( ast:: LogicOp :: And ) => ( SyntaxKind :: PIPE2 , ExprPrecedence :: LOr ) ,
64+ ast:: BinaryOp :: LogicOp ( ast:: LogicOp :: Or ) => ( SyntaxKind :: AMP2 , ExprPrecedence :: LAnd ) ,
5865 _ => return None ,
5966 } ;
6067
@@ -65,33 +72,33 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
6572 editor. replace ( demorganed. op_token ( ) ?, make. token ( inv_token) ) ;
6673
6774 let mut exprs = VecDeque :: from ( [
68- ( bin_expr. lhs ( ) ?, demorganed. lhs ( ) ?) ,
69- ( bin_expr. rhs ( ) ?, demorganed. rhs ( ) ?) ,
75+ ( bin_expr. lhs ( ) ?, demorganed. lhs ( ) ?, prec ) ,
76+ ( bin_expr. rhs ( ) ?, demorganed. rhs ( ) ?, prec ) ,
7077 ] ) ;
7178
72- while let Some ( ( expr, dm ) ) = exprs. pop_front ( ) {
79+ while let Some ( ( expr, demorganed , prec ) ) = exprs. pop_front ( ) {
7380 if let BinExpr ( bin_expr) = & expr {
74- if let BinExpr ( cbin_expr) = & dm {
81+ if let BinExpr ( cbin_expr) = & demorganed {
7582 if op == bin_expr. op_kind ( ) ? {
7683 editor. replace ( cbin_expr. op_token ( ) ?, make. token ( inv_token) ) ;
77- exprs. push_back ( ( bin_expr. lhs ( ) ?, cbin_expr. lhs ( ) ?) ) ;
78- exprs. push_back ( ( bin_expr. rhs ( ) ?, cbin_expr. rhs ( ) ?) ) ;
84+ exprs. push_back ( ( bin_expr. lhs ( ) ?, cbin_expr. lhs ( ) ?, prec ) ) ;
85+ exprs. push_back ( ( bin_expr. rhs ( ) ?, cbin_expr. rhs ( ) ?, prec ) ) ;
7986 } else {
8087 let mut inv = invert_boolean_expression ( & make, expr) ;
81- if needs_parens_in_place_of ( & inv, & dm . syntax ( ) . parent ( ) ? , & dm ) {
88+ if precedence ( & inv) . needs_parentheses_in ( prec ) {
8289 inv = make. expr_paren ( inv) . into ( ) ;
8390 }
84- editor. replace ( dm . syntax ( ) , inv. syntax ( ) ) ;
91+ editor. replace ( demorganed . syntax ( ) , inv. syntax ( ) ) ;
8592 }
8693 } else {
8794 return None ;
8895 }
8996 } else {
90- let mut inv = invert_boolean_expression ( & make, dm . clone ( ) ) ;
91- if needs_parens_in_place_of ( & inv, & dm . syntax ( ) . parent ( ) ? , & dm ) {
97+ let mut inv = invert_boolean_expression ( & make, demorganed . clone ( ) ) ;
98+ if precedence ( & inv) . needs_parentheses_in ( prec ) {
9299 inv = make. expr_paren ( inv) . into ( ) ;
93100 }
94- editor. replace ( dm . syntax ( ) , inv. syntax ( ) ) ;
101+ editor. replace ( demorganed . syntax ( ) , inv. syntax ( ) ) ;
95102 }
96103 }
97104
@@ -121,7 +128,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
121128 let parent = neg_expr. syntax ( ) . parent ( ) ;
122129 editor = builder. make_editor ( neg_expr. syntax ( ) ) ;
123130
124- if parent. is_some_and ( |parent| demorganed. needs_parens_in ( parent) ) {
131+ if parent. is_some_and ( |parent| demorganed. needs_parens_in ( & parent) ) {
125132 cov_mark:: hit!( demorgan_keep_parens_for_op_precedence2) ;
126133 editor. replace ( neg_expr. syntax ( ) , make. expr_paren ( demorganed) . syntax ( ) ) ;
127134 } else {
@@ -271,30 +278,6 @@ fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr {
271278 make. expr_prefix ( T ! [ !] , make. expr_paren ( expr) . into ( ) ) . into ( )
272279}
273280
274- fn needs_parens_in_place_of (
275- this : & ast:: Expr ,
276- parent : & SyntaxNode ,
277- in_place_of : & ast:: Expr ,
278- ) -> bool {
279- assert_eq ! ( Some ( parent) , in_place_of. syntax( ) . parent( ) . as_ref( ) ) ;
280-
281- let child_idx = parent
282- . children ( )
283- . enumerate ( )
284- . find_map ( |( i, it) | if & it == in_place_of. syntax ( ) { Some ( i) } else { None } )
285- . unwrap ( ) ;
286- let parent = parent. clone_subtree ( ) ;
287- let subtree_place = parent. children ( ) . nth ( child_idx) . unwrap ( ) ;
288-
289- let mut editor = SyntaxEditor :: new ( parent) ;
290- editor. replace ( subtree_place, this. syntax ( ) ) ;
291- let edit = editor. finish ( ) ;
292-
293- let replaced = edit. new_root ( ) . children ( ) . nth ( child_idx) . unwrap ( ) ;
294- let replaced = ast:: Expr :: cast ( replaced) . unwrap ( ) ;
295- replaced. needs_parens_in ( edit. new_root ( ) . clone ( ) )
296- }
297-
298281#[ cfg( test) ]
299282mod tests {
300283 use super :: * ;
0 commit comments