Skip to content

Commit e600060

Browse files
committed
add SyntaxEditor::delete_all to migrate utils.rs add_trait_assoc_items_to_impl
1 parent 8611b71 commit e600060

File tree

3 files changed

+67
-26
lines changed

3 files changed

+67
-26
lines changed

crates/ide-assists/src/utils.rs

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ use syntax::{
2323
ast::{
2424
self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
2525
edit::{AstNodeEdit, IndentLevel},
26-
edit_in_place::{AttrsOwnerEdit, Removable},
26+
edit_in_place::AttrsOwnerEdit,
2727
make,
2828
syntax_factory::SyntaxFactory,
2929
},
30-
syntax_editor::SyntaxEditor,
31-
ted,
30+
syntax_editor::{Removable, SyntaxEditor},
3231
};
3332

3433
use crate::{
@@ -207,7 +206,7 @@ pub fn add_trait_assoc_items_to_impl(
207206
stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`");
208207
}
209208
}
210-
original_item.clone_for_update()
209+
original_item
211210
}
212211
.reset_indent();
213212

@@ -221,31 +220,37 @@ pub fn add_trait_assoc_items_to_impl(
221220
cloned_item.remove_attrs_and_docs();
222221
cloned_item
223222
})
224-
.map(|item| {
225-
match &item {
226-
ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
227-
let body = AstNodeEdit::indent(
228-
&make::block_expr(
229-
None,
230-
Some(match config.expr_fill_default {
231-
ExprFillDefaultMode::Todo => make::ext::expr_todo(),
232-
ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
233-
ExprFillDefaultMode::Default => make::ext::expr_todo(),
234-
}),
235-
),
236-
IndentLevel::single(),
237-
);
238-
ted::replace(fn_.get_or_create_body().syntax(), body.syntax());
239-
}
240-
ast::AssocItem::TypeAlias(type_alias) => {
241-
if let Some(type_bound_list) = type_alias.type_bound_list() {
242-
type_bound_list.remove()
243-
}
223+
.filter_map(|item| match item {
224+
ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
225+
let fn_ = fn_.clone_subtree();
226+
let new_body = &make::block_expr(
227+
None,
228+
Some(match config.expr_fill_default {
229+
ExprFillDefaultMode::Todo => make::ext::expr_todo(),
230+
ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
231+
ExprFillDefaultMode::Default => make::ext::expr_todo(),
232+
}),
233+
);
234+
let new_body = AstNodeEdit::indent(new_body, IndentLevel::single());
235+
let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone());
236+
fn_.replace_or_insert_body(&mut fn_editor, new_body);
237+
let new_fn_ = fn_editor.finish().new_root().clone();
238+
ast::AssocItem::cast(new_fn_)
239+
}
240+
ast::AssocItem::TypeAlias(type_alias) => {
241+
let type_alias = type_alias.clone_subtree();
242+
if let Some(type_bound_list) = type_alias.type_bound_list() {
243+
let mut type_alias_editor = SyntaxEditor::new(type_alias.syntax().clone());
244+
type_bound_list.remove(&mut type_alias_editor);
245+
let type_alias = type_alias_editor.finish().new_root().clone();
246+
ast::AssocItem::cast(type_alias)
247+
} else {
248+
Some(ast::AssocItem::TypeAlias(type_alias))
244249
}
245-
_ => {}
246250
}
247-
AstNodeEdit::indent(&item, new_indent_level)
251+
item => Some(item),
248252
})
253+
.map(|item| AstNodeEdit::indent(&item, new_indent_level))
249254
.collect()
250255
}
251256

crates/syntax/src/syntax_editor.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ impl SyntaxEditor {
8383
self.changes.push(Change::Replace(element.syntax_element(), None));
8484
}
8585

86+
pub fn delete_all(&mut self, range: RangeInclusive<SyntaxElement>) {
87+
if range.start() == range.end() {
88+
self.delete(range.start());
89+
return;
90+
}
91+
92+
debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
93+
self.changes.push(Change::ReplaceAll(range, Vec::new()))
94+
}
95+
8696
pub fn replace(&mut self, old: impl Element, new: impl Element) {
8797
let old = old.syntax_element();
8898
debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));

crates/syntax/src/syntax_editor/edits.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,23 @@ impl ast::VariantList {
153153
}
154154
}
155155

156+
impl ast::Fn {
157+
pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::BlockExpr) {
158+
if let Some(old_body) = self.body() {
159+
editor.replace(old_body.syntax(), body.syntax());
160+
} else {
161+
let single_space = make::tokens::single_space();
162+
let elements = vec![single_space.into(), body.syntax().clone().into()];
163+
164+
if let Some(semicolon) = self.semicolon_token() {
165+
editor.replace_with_many(semicolon, elements);
166+
} else {
167+
editor.insert_all(Position::last_child_of(self.syntax()), elements);
168+
}
169+
}
170+
}
171+
}
172+
156173
fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> {
157174
let make = SyntaxFactory::without_mappings();
158175
let l = node
@@ -184,6 +201,15 @@ pub trait Removable: AstNode {
184201
fn remove(&self, editor: &mut SyntaxEditor);
185202
}
186203

204+
impl Removable for ast::TypeBoundList {
205+
fn remove(&self, editor: &mut SyntaxEditor) {
206+
match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
207+
Some(colon) => editor.delete_all(colon..=self.syntax().clone().into()),
208+
None => editor.delete(self.syntax()),
209+
}
210+
}
211+
}
212+
187213
impl Removable for ast::Use {
188214
fn remove(&self, editor: &mut SyntaxEditor) {
189215
let make = SyntaxFactory::without_mappings();

0 commit comments

Comments
 (0)