@@ -9,10 +9,11 @@ use ide_db::{
99 search:: FileReference ,
1010} ;
1111use itertools:: Itertools ;
12+ use syntax:: ast:: syntax_factory:: SyntaxFactory ;
13+ use syntax:: syntax_editor:: SyntaxEditor ;
1214use syntax:: {
1315 AstNode , NodeOrToken , SyntaxNode ,
14- ast:: { self , HasGenericParams , HasName , make} ,
15- ted,
16+ ast:: { self , HasGenericParams , HasName } ,
1617} ;
1718
1819use crate :: {
@@ -68,37 +69,41 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>)
6869 let mut definition_deleted = false ;
6970
7071 let mut inline_refs_for_file = |file_id, refs : Vec < FileReference > | {
71- builder. edit_file ( file_id) ;
72+ let source = ctx. sema . parse ( file_id) ;
73+ let mut editor = builder. make_editor ( source. syntax ( ) ) ;
7274
7375 let ( path_types, path_type_uses) =
7476 split_refs_and_uses ( builder, refs, |path_type| {
7577 path_type. syntax ( ) . ancestors ( ) . nth ( 3 ) . and_then ( ast:: PathType :: cast)
7678 } ) ;
77-
7879 path_type_uses
7980 . iter ( )
8081 . flat_map ( ast_to_remove_for_path_in_use_stmt)
81- . for_each ( |x| builder. delete ( x. syntax ( ) . text_range ( ) ) ) ;
82+ . for_each ( |x| editor. delete ( x. syntax ( ) ) ) ;
83+
8284 for ( target, replacement) in path_types. into_iter ( ) . filter_map ( |path_type| {
83- let replacement = inline ( & ast_alias, & path_type) ?. to_text ( & concrete_type) ;
84- let target = path_type. syntax ( ) . text_range ( ) ;
85+ let replacement =
86+ inline ( & ast_alias, & path_type) ?. replace_generic ( & concrete_type) ;
87+ let target = path_type. syntax ( ) . clone ( ) ;
8588 Some ( ( target, replacement) )
8689 } ) {
87- builder . replace ( target, replacement) ;
90+ editor . replace ( target, replacement) ;
8891 }
8992
90- if file_id == ctx. vfs_file_id ( ) {
91- builder . delete ( ast_alias. syntax ( ) . text_range ( ) ) ;
93+ if file_id. file_id ( ctx . db ( ) ) == ctx. vfs_file_id ( ) {
94+ editor . delete ( ast_alias. syntax ( ) ) ;
9295 definition_deleted = true ;
9396 }
97+ builder. add_file_edits ( file_id. file_id ( ctx. db ( ) ) , editor) ;
9498 } ;
9599
96100 for ( file_id, refs) in usages. into_iter ( ) {
97- inline_refs_for_file ( file_id. file_id ( ctx . db ( ) ) , refs) ;
101+ inline_refs_for_file ( file_id, refs) ;
98102 }
99103 if !definition_deleted {
100- builder. edit_file ( ctx. vfs_file_id ( ) ) ;
101- builder. delete ( ast_alias. syntax ( ) . text_range ( ) ) ;
104+ let mut editor = builder. make_editor ( ast_alias. syntax ( ) ) ;
105+ editor. delete ( ast_alias. syntax ( ) ) ;
106+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor)
102107 }
103108 } ,
104109 )
@@ -146,23 +151,26 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
146151 }
147152 }
148153
149- let target = alias_instance. syntax ( ) . text_range ( ) ;
150-
151154 acc. add (
152155 AssistId :: refactor_inline ( "inline_type_alias" ) ,
153156 "Inline type alias" ,
154- target,
155- |builder| builder. replace ( target, replacement. to_text ( & concrete_type) ) ,
157+ alias_instance. syntax ( ) . text_range ( ) ,
158+ |builder| {
159+ let mut editor = builder. make_editor ( alias_instance. syntax ( ) ) ;
160+ let replace = replacement. replace_generic ( & concrete_type) ;
161+ editor. replace ( alias_instance. syntax ( ) , replace) ;
162+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor) ;
163+ } ,
156164 )
157165}
158166
159167impl Replacement {
160- fn to_text ( & self , concrete_type : & ast:: Type ) -> String {
168+ fn replace_generic ( & self , concrete_type : & ast:: Type ) -> SyntaxNode {
161169 match self {
162170 Replacement :: Generic { lifetime_map, const_and_type_map } => {
163171 create_replacement ( lifetime_map, const_and_type_map, concrete_type)
164172 }
165- Replacement :: Plain => concrete_type. to_string ( ) ,
173+ Replacement :: Plain => concrete_type. syntax ( ) . clone_subtree ( ) . clone_for_update ( ) ,
166174 }
167175 }
168176}
@@ -199,8 +207,8 @@ impl LifetimeMap {
199207 alias_generics : & ast:: GenericParamList ,
200208 ) -> Option < Self > {
201209 let mut inner = FxHashMap :: default ( ) ;
202-
203- let wildcard_lifetime = make:: lifetime ( "'_" ) ;
210+ let make = SyntaxFactory :: without_mappings ( ) ;
211+ let wildcard_lifetime = make. lifetime ( "'_" ) ;
204212 let lifetimes = alias_generics
205213 . lifetime_params ( )
206214 . filter_map ( |lp| lp. lifetime ( ) )
@@ -299,15 +307,14 @@ fn create_replacement(
299307 lifetime_map : & LifetimeMap ,
300308 const_and_type_map : & ConstAndTypeMap ,
301309 concrete_type : & ast:: Type ,
302- ) -> String {
303- let updated_concrete_type = concrete_type. clone_for_update ( ) ;
304- let mut replacements = Vec :: new ( ) ;
305- let mut removals = Vec :: new ( ) ;
310+ ) -> SyntaxNode {
311+ let updated_concrete_type = concrete_type. syntax ( ) . clone_subtree ( ) ;
312+ let mut editor = SyntaxEditor :: new ( updated_concrete_type. clone ( ) ) ;
306313
307- for syntax in updated_concrete_type. syntax ( ) . descendants ( ) {
308- let syntax_string = syntax. to_string ( ) ;
309- let syntax_str = syntax_string. as_str ( ) ;
314+ let mut replacements: Vec < ( SyntaxNode , SyntaxNode ) > = Vec :: new ( ) ;
315+ let mut removals: Vec < NodeOrToken < SyntaxNode , _ > > = Vec :: new ( ) ;
310316
317+ for syntax in updated_concrete_type. descendants ( ) {
311318 if let Some ( old_lifetime) = ast:: Lifetime :: cast ( syntax. clone ( ) ) {
312319 if let Some ( new_lifetime) = lifetime_map. 0 . get ( & old_lifetime. to_string ( ) ) {
313320 if new_lifetime. text ( ) == "'_" {
@@ -322,27 +329,30 @@ fn create_replacement(
322329
323330 replacements. push ( ( syntax. clone ( ) , new_lifetime. syntax ( ) . clone_for_update ( ) ) ) ;
324331 }
325- } else if let Some ( replacement_syntax) = const_and_type_map. 0 . get ( syntax_str) {
332+ } else if let Some ( name_ref) = ast:: NameRef :: cast ( syntax. clone ( ) ) {
333+ let Some ( replacement_syntax) = const_and_type_map. 0 . get ( & name_ref. to_string ( ) ) else {
334+ continue ;
335+ } ;
326336 let new_string = replacement_syntax. to_string ( ) ;
327337 let new = if new_string == "_" {
328- make:: wildcard_pat ( ) . syntax ( ) . clone_for_update ( )
338+ let make = SyntaxFactory :: without_mappings ( ) ;
339+ make. wildcard_pat ( ) . syntax ( ) . clone ( )
329340 } else {
330- replacement_syntax. clone_for_update ( )
341+ replacement_syntax. clone ( )
331342 } ;
332343
333344 replacements. push ( ( syntax. clone ( ) , new) ) ;
334345 }
335346 }
336347
337348 for ( old, new) in replacements {
338- ted :: replace ( old, new) ;
349+ editor . replace ( old, new) ;
339350 }
340351
341352 for syntax in removals {
342- ted :: remove ( syntax) ;
353+ editor . delete ( syntax) ;
343354 }
344-
345- updated_concrete_type. to_string ( )
355+ editor. finish ( ) . new_root ( ) . clone ( )
346356}
347357
348358fn get_type_alias ( ctx : & AssistContext < ' _ > , path : & ast:: PathType ) -> Option < ast:: TypeAlias > {
@@ -377,12 +387,15 @@ impl ConstOrTypeGeneric {
377387 }
378388
379389 fn replacement_value ( & self ) -> Option < SyntaxNode > {
380- Some ( match self {
381- ConstOrTypeGeneric :: ConstArg ( ca) => ca. expr ( ) ?. syntax ( ) . clone ( ) ,
382- ConstOrTypeGeneric :: TypeArg ( ta) => ta. syntax ( ) . clone ( ) ,
383- ConstOrTypeGeneric :: ConstParam ( cp) => cp. default_val ( ) ?. syntax ( ) . clone ( ) ,
384- ConstOrTypeGeneric :: TypeParam ( tp) => tp. default_type ( ) ?. syntax ( ) . clone ( ) ,
385- } )
390+ Some (
391+ match self {
392+ ConstOrTypeGeneric :: ConstArg ( ca) => ca. expr ( ) ?. syntax ( ) . clone ( ) ,
393+ ConstOrTypeGeneric :: TypeArg ( ta) => ta. syntax ( ) . clone ( ) ,
394+ ConstOrTypeGeneric :: ConstParam ( cp) => cp. default_val ( ) ?. syntax ( ) . clone ( ) ,
395+ ConstOrTypeGeneric :: TypeParam ( tp) => tp. default_type ( ) ?. syntax ( ) . clone ( ) ,
396+ }
397+ . clone_for_update ( ) ,
398+ )
386399 }
387400}
388401
0 commit comments