1- use syntax:: ast:: { self , AstNode , BinExpr } ;
1+ use syntax:: {
2+ ast:: { self , syntax_factory:: SyntaxFactory , AstNode , BinExpr } ,
3+ SyntaxKind , T ,
4+ } ;
25
36use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
47
@@ -19,22 +22,17 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
1922// ```
2023pub ( crate ) fn flip_binexpr ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
2124 let expr = ctx. find_node_at_offset :: < BinExpr > ( ) ?;
22- let rhs = expr. rhs ( ) ?. syntax ( ) . clone ( ) ;
23- let lhs = expr. lhs ( ) ?. syntax ( ) . clone ( ) ;
24-
25- let lhs = if let Some ( bin_expr) = BinExpr :: cast ( lhs. clone ( ) ) {
26- if bin_expr. op_kind ( ) == expr. op_kind ( ) {
27- bin_expr. rhs ( ) ?. syntax ( ) . clone ( )
28- } else {
29- lhs
30- }
31- } else {
32- lhs
25+ let lhs = expr. lhs ( ) ?;
26+ let rhs = expr. rhs ( ) ?;
27+
28+ let lhs = match & lhs {
29+ ast:: Expr :: BinExpr ( bin_expr) if bin_expr. op_kind ( ) == expr. op_kind ( ) => bin_expr. rhs ( ) ?,
30+ _ => lhs,
3331 } ;
3432
35- let op_range = expr. op_token ( ) ?. text_range ( ) ;
33+ let op_token = expr. op_token ( ) ?;
3634 // The assist should be applied only if the cursor is on the operator
37- let cursor_in_range = op_range . contains_range ( ctx. selection_trimmed ( ) ) ;
35+ let cursor_in_range = op_token . text_range ( ) . contains_range ( ctx. selection_trimmed ( ) ) ;
3836 if !cursor_in_range {
3937 return None ;
4038 }
@@ -47,13 +45,18 @@ pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
4745 acc. add (
4846 AssistId ( "flip_binexpr" , AssistKind :: RefactorRewrite ) ,
4947 "Flip binary expression" ,
50- op_range,
51- |edit| {
52- if let FlipAction :: FlipAndReplaceOp ( new_op) = action {
53- edit. replace ( op_range, new_op) ;
54- }
55- edit. replace ( lhs. text_range ( ) , rhs. text ( ) ) ;
56- edit. replace ( rhs. text_range ( ) , lhs. text ( ) ) ;
48+ op_token. text_range ( ) ,
49+ |builder| {
50+ let mut editor = builder. make_editor ( & expr. syntax ( ) . parent ( ) . unwrap ( ) ) ;
51+ let make = SyntaxFactory :: new ( ) ;
52+ if let FlipAction :: FlipAndReplaceOp ( binary_op) = action {
53+ editor. replace ( op_token, make. token ( binary_op) )
54+ } ;
55+ // FIXME: remove `clone_for_update` when `SyntaxEditor` handles it for us
56+ editor. replace ( lhs. syntax ( ) , rhs. syntax ( ) . clone_for_update ( ) ) ;
57+ editor. replace ( rhs. syntax ( ) , lhs. syntax ( ) . clone_for_update ( ) ) ;
58+ editor. add_mappings ( make. finish_with_mappings ( ) ) ;
59+ builder. add_file_edits ( ctx. file_id ( ) , editor) ;
5760 } ,
5861 )
5962}
@@ -62,7 +65,7 @@ enum FlipAction {
6265 // Flip the expression
6366 Flip ,
6467 // Flip the expression and replace the operator with this string
65- FlipAndReplaceOp ( & ' static str ) ,
68+ FlipAndReplaceOp ( SyntaxKind ) ,
6669 // Do not flip the expression
6770 DontFlip ,
6871}
@@ -73,10 +76,10 @@ impl From<ast::BinaryOp> for FlipAction {
7376 ast:: BinaryOp :: Assignment { .. } => FlipAction :: DontFlip ,
7477 ast:: BinaryOp :: CmpOp ( ast:: CmpOp :: Ord { ordering, strict } ) => {
7578 let rev_op = match ( ordering, strict) {
76- ( ast:: Ordering :: Less , true ) => ">" ,
77- ( ast:: Ordering :: Less , false ) => ">=" ,
78- ( ast:: Ordering :: Greater , true ) => "<" ,
79- ( ast:: Ordering :: Greater , false ) => "<=" ,
79+ ( ast:: Ordering :: Less , true ) => T ! [ > ] ,
80+ ( ast:: Ordering :: Less , false ) => T ! [ >= ] ,
81+ ( ast:: Ordering :: Greater , true ) => T ! [ < ] ,
82+ ( ast:: Ordering :: Greater , false ) => T ! [ <= ] ,
8083 } ;
8184 FlipAction :: FlipAndReplaceOp ( rev_op)
8285 }
0 commit comments