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`
This commit is contained in:
Shoyu Vanilla (Flint) 2025-07-31 15:11:22 +00:00 committed by GitHub
commit 68e7ec90bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 27 deletions

View File

@ -23,12 +23,11 @@ use syntax::{
ast::{ ast::{
self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, self, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
edit::{AstNodeEdit, IndentLevel}, edit::{AstNodeEdit, IndentLevel},
edit_in_place::{AttrsOwnerEdit, Removable}, edit_in_place::AttrsOwnerEdit,
make, make,
syntax_factory::SyntaxFactory, syntax_factory::SyntaxFactory,
}, },
syntax_editor::SyntaxEditor, syntax_editor::{Removable, SyntaxEditor},
ted,
}; };
use crate::{ 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`"); stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`");
} }
} }
original_item.clone_for_update() original_item
} }
.reset_indent(); .reset_indent();
@ -221,31 +220,37 @@ pub fn add_trait_assoc_items_to_impl(
cloned_item.remove_attrs_and_docs(); cloned_item.remove_attrs_and_docs();
cloned_item cloned_item
}) })
.map(|item| { .filter_map(|item| match item {
match &item { ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
ast::AssocItem::Fn(fn_) if fn_.body().is_none() => { let fn_ = fn_.clone_subtree();
let body = AstNodeEdit::indent( let new_body = &make::block_expr(
&make::block_expr( None,
None, Some(match config.expr_fill_default {
Some(match config.expr_fill_default { ExprFillDefaultMode::Todo => make::ext::expr_todo(),
ExprFillDefaultMode::Todo => make::ext::expr_todo(), ExprFillDefaultMode::Underscore => make::ext::expr_underscore(),
ExprFillDefaultMode::Underscore => make::ext::expr_underscore(), ExprFillDefaultMode::Default => make::ext::expr_todo(),
ExprFillDefaultMode::Default => make::ext::expr_todo(), }),
}), );
), let new_body = AstNodeEdit::indent(new_body, IndentLevel::single());
IndentLevel::single(), let mut fn_editor = SyntaxEditor::new(fn_.syntax().clone());
); fn_.replace_or_insert_body(&mut fn_editor, new_body);
ted::replace(fn_.get_or_create_body().syntax(), body.syntax()); let new_fn_ = fn_editor.finish().new_root().clone();
} ast::AssocItem::cast(new_fn_)
ast::AssocItem::TypeAlias(type_alias) => {
if let Some(type_bound_list) = type_alias.type_bound_list() {
type_bound_list.remove()
}
}
_ => {}
} }
AstNodeEdit::indent(&item, new_indent_level) 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))
}
}
item => Some(item),
}) })
.map(|item| AstNodeEdit::indent(&item, new_indent_level))
.collect() .collect()
} }

View File

@ -83,6 +83,16 @@ impl SyntaxEditor {
self.changes.push(Change::Replace(element.syntax_element(), None)); 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) { pub fn replace(&mut self, old: impl Element, new: impl Element) {
let old = old.syntax_element(); let old = old.syntax_element();
debug_assert!(is_ancestor_or_self_of_element(&old, &self.root)); debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));

View File

@ -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<()> { fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> {
let make = SyntaxFactory::without_mappings(); let make = SyntaxFactory::without_mappings();
let l = node let l = node
@ -184,6 +201,15 @@ pub trait Removable: AstNode {
fn remove(&self, editor: &mut SyntaxEditor); 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 { impl Removable for ast::Use {
fn remove(&self, editor: &mut SyntaxEditor) { fn remove(&self, editor: &mut SyntaxEditor) {
let make = SyntaxFactory::without_mappings(); let make = SyntaxFactory::without_mappings();