@@ -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