Skip to content

Commit b373cb1

Browse files
committed
Migrate generate_trait_from_impl assist to use SyntaxEditor
1 parent f360d6c commit b373cb1

File tree

1 file changed

+35
-34
lines changed

1 file changed

+35
-34
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_trait_from_impl.rs

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ use crate::assist_context::{AssistContext, Assists};
22
use ide_db::assists::AssistId;
33
use syntax::{
44
AstNode, SyntaxKind, T,
5-
ast::{
6-
self, HasGenericParams, HasName, HasVisibility,
7-
edit_in_place::{HasVisibilityEdit, Indent},
8-
make,
9-
},
10-
ted::{self, Position},
5+
ast::{self, HasGenericParams, HasName, HasVisibility, edit_in_place::Indent, make},
6+
syntax_editor::{Position, SyntaxEditor},
117
};
128

139
// NOTES :
@@ -88,8 +84,8 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
8884
return None;
8985
}
9086

91-
let assoc_items = impl_ast.assoc_item_list()?;
92-
let first_element = assoc_items.assoc_items().next();
87+
let impl_assoc_items = impl_ast.assoc_item_list()?;
88+
let first_element = impl_assoc_items.assoc_items().next();
9389
first_element.as_ref()?;
9490

9591
let impl_name = impl_ast.self_ty()?;
@@ -99,20 +95,16 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
9995
"Generate trait from impl",
10096
impl_ast.syntax().text_range(),
10197
|builder| {
102-
let impl_ast = builder.make_mut(impl_ast);
103-
let trait_items = assoc_items.clone_for_update();
104-
let impl_items = builder.make_mut(assoc_items);
105-
let impl_name = builder.make_mut(impl_name);
106-
107-
trait_items.assoc_items().for_each(|item| {
108-
strip_body(&item);
109-
remove_items_visibility(&item);
110-
});
111-
112-
impl_items.assoc_items().for_each(|item| {
113-
remove_items_visibility(&item);
114-
});
115-
98+
let trait_items: ast::AssocItemList = {
99+
let trait_items = impl_assoc_items.clone_subtree();
100+
let mut trait_items_editor = SyntaxEditor::new(trait_items.syntax().clone());
101+
102+
trait_items.assoc_items().for_each(|item| {
103+
strip_body(&mut trait_items_editor, &item);
104+
remove_items_visibility(&mut trait_items_editor, &item);
105+
});
106+
ast::AssocItemList::cast(trait_items_editor.finish().new_root().clone()).unwrap()
107+
};
116108
let trait_ast = make::trait_(
117109
false,
118110
"NewTrait",
@@ -130,17 +122,23 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
130122
trait_name_ref.syntax().clone().into(),
131123
make::tokens::single_space().into(),
132124
make::token(T![for]).into(),
125+
make::tokens::single_space().into(),
133126
];
134127

135128
if let Some(params) = impl_ast.generic_param_list() {
136129
let gen_args = &params.to_generic_args().clone_for_update();
137130
elements.insert(1, gen_args.syntax().clone().into());
138131
}
139132

140-
ted::insert_all(Position::before(impl_name.syntax()), elements);
133+
let mut editor = builder.make_editor(impl_ast.syntax());
134+
impl_assoc_items.assoc_items().for_each(|item| {
135+
remove_items_visibility(&mut editor, &item);
136+
});
137+
138+
editor.insert_all(Position::before(impl_name.syntax()), elements);
141139

142140
// Insert trait before TraitImpl
143-
ted::insert_all_raw(
141+
editor.insert_all(
144142
Position::before(impl_ast.syntax()),
145143
vec![
146144
trait_ast.syntax().clone().into(),
@@ -150,31 +148,34 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_
150148

151149
// Link the trait name & trait ref names together as a placeholder snippet group
152150
if let Some(cap) = ctx.config.snippet_cap {
153-
builder.add_placeholder_snippet_group(
154-
cap,
155-
vec![trait_name.syntax().clone(), trait_name_ref.syntax().clone()],
156-
);
151+
let placeholder = builder.make_placeholder_snippet(cap);
152+
editor.add_annotation(trait_name.syntax(), placeholder);
153+
editor.add_annotation(trait_name_ref.syntax(), placeholder);
157154
}
155+
156+
builder.add_file_edits(ctx.vfs_file_id(), editor);
158157
},
159158
);
160159

161160
Some(())
162161
}
163162

164163
/// `E0449` Trait items always share the visibility of their trait
165-
fn remove_items_visibility(item: &ast::AssocItem) {
164+
fn remove_items_visibility(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
166165
if let Some(has_vis) = ast::AnyHasVisibility::cast(item.syntax().clone()) {
167166
if let Some(vis) = has_vis.visibility()
168167
&& let Some(token) = vis.syntax().next_sibling_or_token()
169168
&& token.kind() == SyntaxKind::WHITESPACE
170169
{
171-
ted::remove(token);
170+
editor.delete(token);
171+
}
172+
if let Some(vis) = has_vis.visibility() {
173+
editor.delete(vis.syntax());
172174
}
173-
has_vis.set_visibility(None);
174175
}
175176
}
176177

177-
fn strip_body(item: &ast::AssocItem) {
178+
fn strip_body(editor: &mut SyntaxEditor, item: &ast::AssocItem) {
178179
if let ast::AssocItem::Fn(f) = item
179180
&& let Some(body) = f.body()
180181
{
@@ -183,10 +184,10 @@ fn strip_body(item: &ast::AssocItem) {
183184
if let Some(prev) = body.syntax().prev_sibling_or_token()
184185
&& prev.kind() == SyntaxKind::WHITESPACE
185186
{
186-
ted::remove(prev);
187+
editor.delete(prev);
187188
}
188189

189-
ted::replace(body.syntax(), make::tokens::semicolon());
190+
editor.replace(body.syntax(), make::tokens::semicolon());
190191
};
191192
}
192193

0 commit comments

Comments
 (0)