Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20345 from Hmikihiro/Migrate_add_trait_assoc_items_to_impl
add `SyntaxEditor::delete_all` to migrate utils.rs `add_trait_assoc_items_to_impl`
Shoyu Vanilla (Flint) 9 months ago
parent 46f97f3 · parent e600060 · commit 68e7ec9
-rw-r--r--crates/ide-assists/src/utils.rs57
-rw-r--r--crates/syntax/src/syntax_editor.rs10
-rw-r--r--crates/syntax/src/syntax_editor/edits.rs26
3 files changed, 67 insertions, 26 deletions
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 77d471e5a7..91aac9cf7b 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -23,12 +23,11 @@ use syntax::{
ast::{
self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
edit::{AstNodeEdit, IndentLevel},
- edit_in_place::{AttrsOwnerEdit, Removable},
+ edit_in_place::AttrsOwnerEdit,
make,
syntax_factory::SyntaxFactory,
},
- syntax_editor::SyntaxEditor,
- ted,
+ syntax_editor::{Removable, SyntaxEditor},
};
use crate::{
@@ -207,7 +206,7 @@ pub fn add_trait_assoc_items_to_impl(
stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`");
}
}
- original_item.clone_for_update()
+ original_item
}
.reset_indent();
@@ -221,31 +220,37 @@ pub fn add_trait_assoc_items_to_impl(
cloned_item.remove_attrs_and_docs();
cloned_item
})
- .map(|item| {
- match &item {
- ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
- let body = AstNodeEdit::indent(
- &make::block_expr(
- None,
- Some(match config.expr_fill_default {
- ExprFillDefaultMode::Todo => make::ext::expr_todo(),
- ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
- ExprFillDefaultMode::Default => make::ext::expr_todo(),
- }),
- ),
- IndentLevel::single(),
- );
- ted::replace(fn_.get_or_create_body().syntax(), body.syntax());
- }
- ast::AssocItem::TypeAlias(type_alias) => {
- if let Some(type_bound_list) = type_alias.type_bound_list() {
- type_bound_list.remove()
- }
+ .filter_map(|item| match item {
+ ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
+ let fn_ = fn_.clone_subtree();
+ let new_body = &make::block_expr(
+ None,
+ Some(match config.expr_fill_default {
+ ExprFillDefaultMode::Todo => make::ext::expr_todo(),
+ ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
+ ExprFillDefaultMode::Default => make::ext::expr_todo(),
+ }),
+ );
+ let new_body = AstNodeEdit::indent(new_body, IndentLevel::single());
+ let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone());
+ fn_.replace_or_insert_body(&mut fn_editor, new_body);
+ let new_fn_ = fn_editor.finish().new_root().clone();
+ ast::AssocItem::cast(new_fn_)
+ }
+ ast::AssocItem::TypeAlias(type_alias) => {
+ let type_alias = type_alias.clone_subtree();
+ if let Some(type_bound_list) = type_alias.type_bound_list() {
+ let mut type_alias_editor = SyntaxEditor::new(type_alias.syntax().clone());
+ type_bound_list.remove(&mut type_alias_editor);
+ let type_alias = type_alias_editor.finish().new_root().clone();
+ ast::AssocItem::cast(type_alias)
+ } else {
+ Some(ast::AssocItem::TypeAlias(type_alias))
}
- _ => {}
}
- AstNodeEdit::indent(&item, new_indent_level)
+ item => Some(item),
})
+ .map(|item| AstNodeEdit::indent(&item, new_indent_level))
.collect()
}
diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs
index 124ac5c072..18f5015e9e 100644
--- a/crates/syntax/src/syntax_editor.rs
+++ b/crates/syntax/src/syntax_editor.rs
@@ -83,6 +83,16 @@ impl SyntaxEditor {
self.changes.push(Change::Replace(element.syntax_element(), None));
}
+ pub fn delete_all(&mut self, range: RangeInclusive<SyntaxElement>) {
+ if range.start() == range.end() {
+ self.delete(range.start());
+ return;
+ }
+
+ debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
+ self.changes.push(Change::ReplaceAll(range, Vec::new()))
+ }
+
pub fn replace(&mut self, old: impl Element, new: impl Element) {
let old = old.syntax_element();
debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
diff --git a/crates/syntax/src/syntax_editor/edits.rs b/crates/syntax/src/syntax_editor/edits.rs
index 840e769797..9090f7c9eb 100644
--- a/crates/syntax/src/syntax_editor/edits.rs
+++ b/crates/syntax/src/syntax_editor/edits.rs
@@ -153,6 +153,23 @@ impl ast::VariantList {
}
}
+impl ast::Fn {
+ pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::BlockExpr) {
+ if let Some(old_body) = self.body() {
+ editor.replace(old_body.syntax(), body.syntax());
+ } else {
+ let single_space = make::tokens::single_space();
+ let elements = vec![single_space.into(), body.syntax().clone().into()];
+
+ if let Some(semicolon) = self.semicolon_token() {
+ editor.replace_with_many(semicolon, elements);
+ } else {
+ editor.insert_all(Position::last_child_of(self.syntax()), elements);
+ }
+ }
+ }
+}
+
fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> {
let make = SyntaxFactory::without_mappings();
let l = node
@@ -184,6 +201,15 @@ pub trait Removable: AstNode {
fn remove(&self, editor: &mut SyntaxEditor);
}
+impl Removable for ast::TypeBoundList {
+ fn remove(&self, editor: &mut SyntaxEditor) {
+ match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
+ Some(colon) => editor.delete_all(colon..=self.syntax().clone().into()),
+ None => editor.delete(self.syntax()),
+ }
+ }
+}
+
impl Removable for ast::Use {
fn remove(&self, editor: &mut SyntaxEditor) {
let make = SyntaxFactory::without_mappings();