@@ -8,12 +8,13 @@ use ide_db::{
8
8
} ;
9
9
use itertools:: Itertools ;
10
10
use syntax:: {
11
- ast:: { self , edit:: AstNodeEdit , make, HasArgList } ,
12
- ted, AstNode , SyntaxNode ,
11
+ ast:: { self , edit:: AstNodeEdit , syntax_factory:: SyntaxFactory , HasArgList } ,
12
+ syntax_editor:: SyntaxEditor ,
13
+ AstNode , SyntaxNode ,
13
14
} ;
14
15
15
16
use crate :: {
16
- utils:: { invert_boolean_expression_legacy , unwrap_trivial_block} ,
17
+ utils:: { invert_boolean_expression , unwrap_trivial_block} ,
17
18
AssistContext , AssistId , AssistKind , Assists ,
18
19
} ;
19
20
@@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
76
77
"Convert `if` expression to `bool::then` call" ,
77
78
target,
78
79
|builder| {
79
- let closure_body = closure_body. clone_for_update ( ) ;
80
+ let closure_body = closure_body. clone_subtree ( ) ;
81
+ let mut editor = SyntaxEditor :: new ( closure_body. syntax ( ) . clone ( ) ) ;
80
82
// Rewrite all `Some(e)` in tail position to `e`
81
- let mut replacements = Vec :: new ( ) ;
82
83
for_each_tail_expr ( & closure_body, & mut |e| {
83
84
let e = match e {
84
85
ast:: Expr :: BreakExpr ( e) => e. expr ( ) ,
@@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
88
89
if let Some ( ast:: Expr :: CallExpr ( call) ) = e {
89
90
if let Some ( arg_list) = call. arg_list ( ) {
90
91
if let Some ( arg) = arg_list. args ( ) . next ( ) {
91
- replacements . push ( ( call. syntax ( ) . clone ( ) , arg. syntax ( ) . clone ( ) ) ) ;
92
+ editor . replace ( call. syntax ( ) , arg. syntax ( ) ) ;
92
93
}
93
94
}
94
95
}
95
96
} ) ;
96
- replacements. into_iter ( ) . for_each ( |( old, new) | ted:: replace ( old, new) ) ;
97
+ let edit = editor. finish ( ) ;
98
+ let closure_body = ast:: Expr :: cast ( edit. new_root ( ) . clone ( ) ) . unwrap ( ) ;
99
+
100
+ let mut editor = builder. make_editor ( expr. syntax ( ) ) ;
101
+ let make = SyntaxFactory :: new ( ) ;
97
102
let closure_body = match closure_body {
98
103
ast:: Expr :: BlockExpr ( block) => unwrap_trivial_block ( block) ,
99
104
e => e,
@@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
119
124
| ast:: Expr :: WhileExpr ( _)
120
125
| ast:: Expr :: YieldExpr ( _)
121
126
) ;
122
- let cond = if invert_cond { invert_boolean_expression_legacy ( cond) } else { cond } ;
123
- let cond = if parenthesize { make:: expr_paren ( cond) } else { cond } ;
124
- let arg_list = make:: arg_list ( Some ( make:: expr_closure ( None , closure_body) ) ) ;
125
- let mcall = make:: expr_method_call ( cond, make:: name_ref ( "then" ) , arg_list) ;
126
- builder. replace ( target, mcall. to_string ( ) ) ;
127
+ let cond = if invert_cond {
128
+ invert_boolean_expression ( & make, cond)
129
+ } else {
130
+ cond. clone_for_update ( )
131
+ } ;
132
+ let cond = if parenthesize { make. expr_paren ( cond) . into ( ) } else { cond } ;
133
+ let arg_list = make. arg_list ( Some ( make. expr_closure ( None , closure_body) . into ( ) ) ) ;
134
+ let mcall = make. expr_method_call ( cond, make. name_ref ( "then" ) , arg_list) ;
135
+ editor. replace ( expr. syntax ( ) , mcall. syntax ( ) ) ;
136
+
137
+ editor. add_mappings ( make. finish_with_mappings ( ) ) ;
138
+ builder. add_file_edits ( ctx. file_id ( ) , editor) ;
127
139
} ,
128
140
)
129
141
}
@@ -173,45 +185,55 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
173
185
"Convert `bool::then` call to `if`" ,
174
186
target,
175
187
|builder| {
176
- let closure_body = match closure_body {
188
+ let mapless_make = SyntaxFactory :: without_mappings ( ) ;
189
+ let closure_body = match closure_body. reset_indent ( ) {
177
190
ast:: Expr :: BlockExpr ( block) => block,
178
- e => make :: block_expr ( None , Some ( e) ) ,
191
+ e => mapless_make . block_expr ( None , Some ( e) ) ,
179
192
} ;
180
193
181
- let closure_body = closure_body. clone_for_update ( ) ;
194
+ let closure_body = closure_body. clone_subtree ( ) ;
195
+ let mut editor = SyntaxEditor :: new ( closure_body. syntax ( ) . clone ( ) ) ;
182
196
// Wrap all tails in `Some(...)`
183
- let none_path = make:: expr_path ( make:: ext:: ident_path ( "None" ) ) ;
184
- let some_path = make:: expr_path ( make:: ext:: ident_path ( "Some" ) ) ;
185
- let mut replacements = Vec :: new ( ) ;
197
+ let none_path = mapless_make. expr_path ( mapless_make. ident_path ( "None" ) ) ;
198
+ let some_path = mapless_make. expr_path ( mapless_make. ident_path ( "Some" ) ) ;
186
199
for_each_tail_expr ( & ast:: Expr :: BlockExpr ( closure_body. clone ( ) ) , & mut |e| {
187
200
let e = match e {
188
201
ast:: Expr :: BreakExpr ( e) => e. expr ( ) ,
189
202
ast:: Expr :: ReturnExpr ( e) => e. expr ( ) ,
190
203
_ => Some ( e. clone ( ) ) ,
191
204
} ;
192
205
if let Some ( expr) = e {
193
- replacements . push ( (
206
+ editor . replace (
194
207
expr. syntax ( ) . clone ( ) ,
195
- make:: expr_call ( some_path. clone ( ) , make:: arg_list ( Some ( expr) ) )
208
+ mapless_make
209
+ . expr_call ( some_path. clone ( ) , mapless_make. arg_list ( Some ( expr) ) )
196
210
. syntax ( )
197
- . clone_for_update ( ) ,
198
- ) ) ;
211
+ . clone ( ) ,
212
+ ) ;
199
213
}
200
214
} ) ;
201
- replacements. into_iter ( ) . for_each ( |( old, new) | ted:: replace ( old, new) ) ;
215
+ let edit = editor. finish ( ) ;
216
+ let closure_body = ast:: BlockExpr :: cast ( edit. new_root ( ) . clone ( ) ) . unwrap ( ) ;
217
+
218
+ let mut editor = builder. make_editor ( mcall. syntax ( ) ) ;
219
+ let make = SyntaxFactory :: new ( ) ;
202
220
203
221
let cond = match & receiver {
204
222
ast:: Expr :: ParenExpr ( expr) => expr. expr ( ) . unwrap_or ( receiver) ,
205
223
_ => receiver,
206
224
} ;
207
- let if_expr = make:: expr_if (
208
- cond,
209
- closure_body. reset_indent ( ) ,
210
- Some ( ast:: ElseBranch :: Block ( make:: block_expr ( None , Some ( none_path) ) ) ) ,
211
- )
212
- . indent ( mcall. indent_level ( ) ) ;
225
+ let if_expr = make
226
+ . expr_if (
227
+ cond,
228
+ closure_body,
229
+ Some ( ast:: ElseBranch :: Block ( make. block_expr ( None , Some ( none_path) ) ) ) ,
230
+ )
231
+ . indent ( mcall. indent_level ( ) )
232
+ . clone_for_update ( ) ;
233
+ editor. replace ( mcall. syntax ( ) . clone ( ) , if_expr. syntax ( ) . clone ( ) ) ;
213
234
214
- builder. replace ( target, if_expr. to_string ( ) ) ;
235
+ editor. add_mappings ( make. finish_with_mappings ( ) ) ;
236
+ builder. add_file_edits ( ctx. file_id ( ) , editor) ;
215
237
} ,
216
238
)
217
239
}
0 commit comments