@@ -8,12 +8,13 @@ use ide_db::{
88} ;
99use itertools:: Itertools ;
1010use 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 ,
1314} ;
1415
1516use crate :: {
16- utils:: { invert_boolean_expression_legacy , unwrap_trivial_block} ,
17+ utils:: { invert_boolean_expression , unwrap_trivial_block} ,
1718 AssistContext , AssistId , AssistKind , Assists ,
1819} ;
1920
@@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
7677 "Convert `if` expression to `bool::then` call" ,
7778 target,
7879 |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 ( ) ) ;
8082 // Rewrite all `Some(e)` in tail position to `e`
81- let mut replacements = Vec :: new ( ) ;
8283 for_each_tail_expr ( & closure_body, & mut |e| {
8384 let e = match e {
8485 ast:: Expr :: BreakExpr ( e) => e. expr ( ) ,
@@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
8889 if let Some ( ast:: Expr :: CallExpr ( call) ) = e {
8990 if let Some ( arg_list) = call. arg_list ( ) {
9091 if let Some ( arg) = arg_list. args ( ) . next ( ) {
91- replacements . push ( ( call. syntax ( ) . clone ( ) , arg. syntax ( ) . clone ( ) ) ) ;
92+ editor . replace ( call. syntax ( ) , arg. syntax ( ) ) ;
9293 }
9394 }
9495 }
9596 } ) ;
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 ( ) ;
97102 let closure_body = match closure_body {
98103 ast:: Expr :: BlockExpr ( block) => unwrap_trivial_block ( block) ,
99104 e => e,
@@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
119124 | ast:: Expr :: WhileExpr ( _)
120125 | ast:: Expr :: YieldExpr ( _)
121126 ) ;
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) ;
127139 } ,
128140 )
129141}
@@ -173,45 +185,55 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
173185 "Convert `bool::then` call to `if`" ,
174186 target,
175187 |builder| {
176- let closure_body = match closure_body {
188+ let mapless_make = SyntaxFactory :: without_mappings ( ) ;
189+ let closure_body = match closure_body. reset_indent ( ) {
177190 ast:: Expr :: BlockExpr ( block) => block,
178- e => make :: block_expr ( None , Some ( e) ) ,
191+ e => mapless_make . block_expr ( None , Some ( e) ) ,
179192 } ;
180193
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 ( ) ) ;
182196 // 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" ) ) ;
186199 for_each_tail_expr ( & ast:: Expr :: BlockExpr ( closure_body. clone ( ) ) , & mut |e| {
187200 let e = match e {
188201 ast:: Expr :: BreakExpr ( e) => e. expr ( ) ,
189202 ast:: Expr :: ReturnExpr ( e) => e. expr ( ) ,
190203 _ => Some ( e. clone ( ) ) ,
191204 } ;
192205 if let Some ( expr) = e {
193- replacements . push ( (
206+ editor . replace (
194207 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) ) )
196210 . syntax ( )
197- . clone_for_update ( ) ,
198- ) ) ;
211+ . clone ( ) ,
212+ ) ;
199213 }
200214 } ) ;
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 ( ) ;
202220
203221 let cond = match & receiver {
204222 ast:: Expr :: ParenExpr ( expr) => expr. expr ( ) . unwrap_or ( receiver) ,
205223 _ => receiver,
206224 } ;
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 ( ) ) ;
213234
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) ;
215237 } ,
216238 )
217239}
0 commit comments