@@ -9,10 +9,10 @@ use ide_db::{
9
9
search:: FileReference ,
10
10
} ;
11
11
use itertools:: Itertools ;
12
+ use syntax:: syntax_editor:: SyntaxEditor ;
12
13
use syntax:: {
13
14
AstNode , NodeOrToken , SyntaxNode ,
14
15
ast:: { self , HasGenericParams , HasName , make} ,
15
- ted,
16
16
} ;
17
17
18
18
use crate :: {
@@ -68,37 +68,41 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>)
68
68
let mut definition_deleted = false ;
69
69
70
70
let mut inline_refs_for_file = |file_id, refs : Vec < FileReference > | {
71
- builder. edit_file ( file_id) ;
71
+ let source = ctx. sema . parse ( file_id) ;
72
+ let mut editor = builder. make_editor ( source. syntax ( ) ) ;
72
73
73
74
let ( path_types, path_type_uses) =
74
75
split_refs_and_uses ( builder, refs, |path_type| {
75
76
path_type. syntax ( ) . ancestors ( ) . nth ( 3 ) . and_then ( ast:: PathType :: cast)
76
77
} ) ;
77
-
78
78
path_type_uses
79
79
. iter ( )
80
80
. flat_map ( ast_to_remove_for_path_in_use_stmt)
81
- . for_each ( |x| builder. delete ( x. syntax ( ) . text_range ( ) ) ) ;
81
+ . for_each ( |x| editor. delete ( x. syntax ( ) ) ) ;
82
+
82
83
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 ( ) ;
84
+ let replacement =
85
+ inline ( & ast_alias, & path_type) ?. replace_generic ( & concrete_type) ;
86
+ let target = path_type. syntax ( ) . clone ( ) ;
85
87
Some ( ( target, replacement) )
86
88
} ) {
87
- builder . replace ( target, replacement) ;
89
+ editor . replace ( target, replacement) ;
88
90
}
89
91
90
- if file_id == ctx. vfs_file_id ( ) {
91
- builder . delete ( ast_alias. syntax ( ) . text_range ( ) ) ;
92
+ if file_id. file_id ( ctx . db ( ) ) == ctx. vfs_file_id ( ) {
93
+ editor . delete ( ast_alias. syntax ( ) ) ;
92
94
definition_deleted = true ;
93
95
}
96
+ builder. add_file_edits ( file_id. file_id ( ctx. db ( ) ) , editor) ;
94
97
} ;
95
98
96
99
for ( file_id, refs) in usages. into_iter ( ) {
97
- inline_refs_for_file ( file_id. file_id ( ctx . db ( ) ) , refs) ;
100
+ inline_refs_for_file ( file_id, refs) ;
98
101
}
99
102
if !definition_deleted {
100
- builder. edit_file ( ctx. vfs_file_id ( ) ) ;
101
- builder. delete ( ast_alias. syntax ( ) . text_range ( ) ) ;
103
+ let mut editor = builder. make_editor ( ast_alias. syntax ( ) ) ;
104
+ editor. delete ( ast_alias. syntax ( ) ) ;
105
+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor)
102
106
}
103
107
} ,
104
108
)
@@ -146,23 +150,26 @@ pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
146
150
}
147
151
}
148
152
149
- let target = alias_instance. syntax ( ) . text_range ( ) ;
150
-
151
153
acc. add (
152
154
AssistId :: refactor_inline ( "inline_type_alias" ) ,
153
155
"Inline type alias" ,
154
- target,
155
- |builder| builder. replace ( target, replacement. to_text ( & concrete_type) ) ,
156
+ alias_instance. syntax ( ) . text_range ( ) ,
157
+ |builder| {
158
+ let mut editor = builder. make_editor ( alias_instance. syntax ( ) ) ;
159
+ let replace = replacement. replace_generic ( & concrete_type) ;
160
+ editor. replace ( alias_instance. syntax ( ) , replace) ;
161
+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor) ;
162
+ } ,
156
163
)
157
164
}
158
165
159
166
impl Replacement {
160
- fn to_text ( & self , concrete_type : & ast:: Type ) -> String {
167
+ fn replace_generic ( & self , concrete_type : & ast:: Type ) -> SyntaxNode {
161
168
match self {
162
169
Replacement :: Generic { lifetime_map, const_and_type_map } => {
163
170
create_replacement ( lifetime_map, const_and_type_map, concrete_type)
164
171
}
165
- Replacement :: Plain => concrete_type. to_string ( ) ,
172
+ Replacement :: Plain => concrete_type. syntax ( ) . clone_subtree ( ) . clone_for_update ( ) ,
166
173
}
167
174
}
168
175
}
@@ -299,15 +306,14 @@ fn create_replacement(
299
306
lifetime_map : & LifetimeMap ,
300
307
const_and_type_map : & ConstAndTypeMap ,
301
308
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 ( ) ;
309
+ ) -> SyntaxNode {
310
+ let updated_concrete_type = concrete_type. syntax ( ) . clone_subtree ( ) ;
311
+ let mut editor = SyntaxEditor :: new ( updated_concrete_type. clone ( ) ) ;
306
312
307
- for syntax in updated_concrete_type. syntax ( ) . descendants ( ) {
308
- let syntax_string = syntax. to_string ( ) ;
309
- let syntax_str = syntax_string. as_str ( ) ;
313
+ let mut replacements: Vec < ( SyntaxNode , SyntaxNode ) > = Vec :: new ( ) ;
314
+ let mut removals: Vec < NodeOrToken < SyntaxNode , _ > > = Vec :: new ( ) ;
310
315
316
+ for syntax in updated_concrete_type. descendants ( ) {
311
317
if let Some ( old_lifetime) = ast:: Lifetime :: cast ( syntax. clone ( ) ) {
312
318
if let Some ( new_lifetime) = lifetime_map. 0 . get ( & old_lifetime. to_string ( ) ) {
313
319
if new_lifetime. text ( ) == "'_" {
@@ -338,14 +344,13 @@ fn create_replacement(
338
344
}
339
345
340
346
for ( old, new) in replacements {
341
- ted :: replace ( old, new) ;
347
+ editor . replace ( old, new) ;
342
348
}
343
349
344
350
for syntax in removals {
345
- ted :: remove ( syntax) ;
351
+ editor . delete ( syntax) ;
346
352
}
347
-
348
- updated_concrete_type. to_string ( )
353
+ editor. finish ( ) . new_root ( ) . clone ( )
349
354
}
350
355
351
356
fn get_type_alias ( ctx : & AssistContext < ' _ > , path : & ast:: PathType ) -> Option < ast:: TypeAlias > {
0 commit comments