@@ -13,9 +13,9 @@ use ide_db::{
13
13
} ;
14
14
use rustc_hash:: FxHashSet ;
15
15
use syntax:: {
16
- algo:: { find_node_at_offset, SyntaxRewriter } ,
17
- ast:: { self , edit :: IndentLevel , make, AstNode , NameOwner , VisibilityOwner } ,
18
- SourceFile , SyntaxElement , SyntaxNode , T ,
16
+ algo:: find_node_at_offset,
17
+ ast:: { self , make, AstNode , NameOwner , VisibilityOwner } ,
18
+ ted , SourceFile , SyntaxElement , SyntaxNode , T ,
19
19
} ;
20
20
21
21
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
@@ -62,40 +62,45 @@ pub(crate) fn extract_struct_from_enum_variant(
62
62
let mut visited_modules_set = FxHashSet :: default ( ) ;
63
63
let current_module = enum_hir. module ( ctx. db ( ) ) ;
64
64
visited_modules_set. insert ( current_module) ;
65
- let mut def_rewriter = None ;
65
+ let mut def_file_references = None ;
66
66
for ( file_id, references) in usages {
67
- let mut rewriter = SyntaxRewriter :: default ( ) ;
68
- let source_file = ctx. sema . parse ( file_id) ;
67
+ if file_id == ctx. frange . file_id {
68
+ def_file_references = Some ( references) ;
69
+ continue ;
70
+ }
71
+ builder. edit_file ( file_id) ;
72
+ let source_file = builder. make_ast_mut ( ctx. sema . parse ( file_id) ) ;
69
73
for reference in references {
70
74
update_reference (
71
75
ctx,
72
- & mut rewriter,
73
76
reference,
74
77
& source_file,
75
78
& enum_module_def,
76
79
& variant_hir_name,
77
80
& mut visited_modules_set,
78
81
) ;
79
82
}
80
- if file_id == ctx. frange . file_id {
81
- def_rewriter = Some ( rewriter) ;
82
- continue ;
83
- }
84
- builder. edit_file ( file_id) ;
85
- builder. rewrite ( rewriter) ;
86
83
}
87
- let mut rewriter = def_rewriter. unwrap_or_default ( ) ;
88
- update_variant ( & mut rewriter, & variant) ;
84
+ builder. edit_file ( ctx. frange . file_id ) ;
85
+ let variant = builder. make_ast_mut ( variant. clone ( ) ) ;
86
+ let source_file = builder. make_ast_mut ( ctx. sema . parse ( ctx. frange . file_id ) ) ;
87
+ for reference in def_file_references. into_iter ( ) . flatten ( ) {
88
+ update_reference (
89
+ ctx,
90
+ reference,
91
+ & source_file,
92
+ & enum_module_def,
93
+ & variant_hir_name,
94
+ & mut visited_modules_set,
95
+ ) ;
96
+ }
89
97
extract_struct_def (
90
- & mut rewriter,
91
- & enum_ast,
92
98
variant_name. clone ( ) ,
93
99
& field_list,
94
100
& variant. parent_enum ( ) . syntax ( ) . clone ( ) . into ( ) ,
95
101
enum_ast. visibility ( ) ,
96
102
) ;
97
- builder. edit_file ( ctx. frange . file_id ) ;
98
- builder. rewrite ( rewriter) ;
103
+ update_variant ( & variant) ;
99
104
} ,
100
105
)
101
106
}
@@ -138,7 +143,6 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va
138
143
139
144
fn insert_import (
140
145
ctx : & AssistContext ,
141
- rewriter : & mut SyntaxRewriter ,
142
146
scope_node : & SyntaxNode ,
143
147
module : & Module ,
144
148
enum_module_def : & ModuleDef ,
@@ -151,14 +155,12 @@ fn insert_import(
151
155
mod_path. pop_segment ( ) ;
152
156
mod_path. push_segment ( variant_hir_name. clone ( ) ) ;
153
157
let scope = ImportScope :: find_insert_use_container ( scope_node, & ctx. sema ) ?;
154
- * rewriter += insert_use ( & scope, mod_path_to_ast ( & mod_path) , ctx. config . insert_use ) ;
158
+ insert_use ( & scope, mod_path_to_ast ( & mod_path) , ctx. config . insert_use ) ;
155
159
}
156
160
Some ( ( ) )
157
161
}
158
162
159
163
fn extract_struct_def (
160
- rewriter : & mut SyntaxRewriter ,
161
- enum_ : & ast:: Enum ,
162
164
variant_name : ast:: Name ,
163
165
field_list : & Either < ast:: RecordFieldList , ast:: TupleFieldList > ,
164
166
start_offset : & SyntaxElement ,
@@ -180,33 +182,34 @@ fn extract_struct_def(
180
182
. into ( ) ,
181
183
} ;
182
184
183
- rewriter . insert_before (
184
- start_offset,
185
- make:: struct_ ( visibility, variant_name, None , field_list) . syntax ( ) ,
185
+ ted :: insert_raw (
186
+ ted :: Position :: before ( start_offset) ,
187
+ make:: struct_ ( visibility, variant_name, None , field_list) . clone_for_update ( ) . syntax ( ) ,
186
188
) ;
187
- rewriter . insert_before ( start_offset, & make:: tokens:: blank_line ( ) ) ;
189
+ ted :: insert_raw ( ted :: Position :: before ( start_offset) , & make:: tokens:: blank_line ( ) ) ;
188
190
189
- if let indent_level @ 1 ..=usize:: MAX = IndentLevel :: from_node ( enum_. syntax ( ) ) . 0 as usize {
190
- rewriter
191
- . insert_before ( start_offset, & make:: tokens:: whitespace ( & " " . repeat ( 4 * indent_level) ) ) ;
192
- }
191
+ // if let indent_level @ 1..=usize::MAX = IndentLevel::from_node(enum_.syntax()).0 as usize {
192
+ // ted::insert(ted::Position::before(start_offset), &make::tokens::blank_line());
193
+ // rewriter
194
+ // .insert_before(start_offset, &make::tokens::whitespace(&" ".repeat(4 * indent_level)));
195
+ // }
193
196
Some ( ( ) )
194
197
}
195
198
196
- fn update_variant ( rewriter : & mut SyntaxRewriter , variant : & ast:: Variant ) -> Option < ( ) > {
199
+ fn update_variant ( variant : & ast:: Variant ) -> Option < ( ) > {
197
200
let name = variant. name ( ) ?;
198
201
let tuple_field = make:: tuple_field ( None , make:: ty ( & name. text ( ) ) ) ;
199
202
let replacement = make:: variant (
200
203
name,
201
204
Some ( ast:: FieldList :: TupleFieldList ( make:: tuple_field_list ( iter:: once ( tuple_field) ) ) ) ,
202
- ) ;
203
- rewriter. replace ( variant. syntax ( ) , replacement. syntax ( ) ) ;
205
+ )
206
+ . clone_for_update ( ) ;
207
+ ted:: replace ( variant. syntax ( ) , replacement. syntax ( ) ) ;
204
208
Some ( ( ) )
205
209
}
206
210
207
211
fn update_reference (
208
212
ctx : & AssistContext ,
209
- rewriter : & mut SyntaxRewriter ,
210
213
reference : FileReference ,
211
214
source_file : & SourceFile ,
212
215
enum_module_def : & ModuleDef ,
@@ -230,14 +233,16 @@ fn update_reference(
230
233
231
234
let module = ctx. sema . scope ( & expr) . module ( ) ?;
232
235
if !visited_modules_set. contains ( & module) {
233
- if insert_import ( ctx, rewriter, & expr, & module, enum_module_def, variant_hir_name) . is_some ( )
234
- {
236
+ if insert_import ( ctx, & expr, & module, enum_module_def, variant_hir_name) . is_some ( ) {
235
237
visited_modules_set. insert ( module) ;
236
238
}
237
239
}
238
- rewriter. insert_after ( segment. syntax ( ) , & make:: token ( T ! [ '(' ] ) ) ;
239
- rewriter. insert_after ( segment. syntax ( ) , segment. syntax ( ) ) ;
240
- rewriter. insert_after ( & expr, & make:: token ( T ! [ ')' ] ) ) ;
240
+ ted:: insert_raw (
241
+ ted:: Position :: before ( segment. syntax ( ) ) ,
242
+ make:: path_from_text ( & format ! ( "{}" , segment) ) . clone_for_update ( ) . syntax ( ) ,
243
+ ) ;
244
+ ted:: insert_raw ( ted:: Position :: before ( segment. syntax ( ) ) , make:: token ( T ! [ '(' ] ) ) ;
245
+ ted:: insert_raw ( ted:: Position :: after ( & expr) , make:: token ( T ! [ ')' ] ) ) ;
241
246
Some ( ( ) )
242
247
}
243
248
0 commit comments