1
- use syntax:: ast:: { self , AstNode , BinExpr } ;
1
+ use syntax:: {
2
+ ast:: { self , syntax_factory:: SyntaxFactory , AstNode , BinExpr } ,
3
+ SyntaxKind , T ,
4
+ } ;
2
5
3
6
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
4
7
@@ -19,22 +22,17 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
19
22
// ```
20
23
pub ( crate ) fn flip_binexpr ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
21
24
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,
33
31
} ;
34
32
35
- let op_range = expr. op_token ( ) ?. text_range ( ) ;
33
+ let op_token = expr. op_token ( ) ?;
36
34
// 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 ( ) ) ;
38
36
if !cursor_in_range {
39
37
return None ;
40
38
}
@@ -47,13 +45,18 @@ pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
47
45
acc. add (
48
46
AssistId ( "flip_binexpr" , AssistKind :: RefactorRewrite ) ,
49
47
"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) ;
57
60
} ,
58
61
)
59
62
}
@@ -62,7 +65,7 @@ enum FlipAction {
62
65
// Flip the expression
63
66
Flip ,
64
67
// Flip the expression and replace the operator with this string
65
- FlipAndReplaceOp ( & ' static str ) ,
68
+ FlipAndReplaceOp ( SyntaxKind ) ,
66
69
// Do not flip the expression
67
70
DontFlip ,
68
71
}
@@ -73,10 +76,10 @@ impl From<ast::BinaryOp> for FlipAction {
73
76
ast:: BinaryOp :: Assignment { .. } => FlipAction :: DontFlip ,
74
77
ast:: BinaryOp :: CmpOp ( ast:: CmpOp :: Ord { ordering, strict } ) => {
75
78
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 ! [ <= ] ,
80
83
} ;
81
84
FlipAction :: FlipAndReplaceOp ( rev_op)
82
85
}
0 commit comments