Migrate `generate_delegate_methods` assist to use `SyntaxEditor`
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index 7f1e7cc..11201af 100644
--- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -183,13 +183,11 @@
.clone()
.into_iter()
.chain(other_items.iter().cloned())
- .map(either::Either::Right)
.collect::<Vec<_>>();
let mut editor = edit.make_editor(impl_def.syntax());
if let Some(assoc_item_list) = impl_def.assoc_item_list() {
- let items = new_assoc_items.into_iter().filter_map(either::Either::right).collect();
- assoc_item_list.add_items(&mut editor, items);
+ assoc_item_list.add_items(&mut editor, new_assoc_items);
} else {
let assoc_item_list = make::assoc_item_list(Some(new_assoc_items)).clone_for_update();
editor.insert_all(
diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index 6063898..2c81e28 100644
--- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -2,9 +2,11 @@
use ide_db::{FxHashSet, path_transform::PathTransform};
use syntax::{
ast::{
- self, AstNode, HasGenericParams, HasName, HasVisibility as _, edit_in_place::Indent, make,
+ self, AstNode, HasGenericParams, HasName, HasVisibility as _,
+ edit::{AstNodeEdit, IndentLevel},
+ make,
},
- ted,
+ syntax_editor::Position,
};
use crate::{
@@ -165,54 +167,66 @@
is_unsafe,
is_gen,
)
- .clone_for_update();
+ .indent(IndentLevel(1));
+ let item = ast::AssocItem::Fn(f.clone());
- // Get the impl to update, or create one if we need to.
- let impl_def = match impl_def {
- Some(impl_def) => edit.make_mut(impl_def),
+ let mut editor = edit.make_editor(strukt.syntax());
+ let fn_: Option<ast::AssocItem> = match impl_def {
+ Some(impl_def) => match impl_def.assoc_item_list() {
+ Some(assoc_item_list) => {
+ let item = item.indent(IndentLevel::from_node(impl_def.syntax()));
+ assoc_item_list.add_items(&mut editor, vec![item.clone()]);
+ Some(item)
+ }
+ None => {
+ let assoc_item_list = make::assoc_item_list(Some(vec![item]));
+ editor.insert(
+ Position::last_child_of(impl_def.syntax()),
+ assoc_item_list.syntax(),
+ );
+ assoc_item_list.assoc_items().next()
+ }
+ },
None => {
let name = &strukt_name.to_string();
let ty_params = strukt.generic_param_list();
let ty_args = ty_params.as_ref().map(|it| it.to_generic_args());
let where_clause = strukt.where_clause();
+ let assoc_item_list = make::assoc_item_list(Some(vec![item]));
let impl_def = make::impl_(
ty_params,
ty_args,
make::ty_path(make::ext::ident_path(name)),
where_clause,
- None,
+ Some(assoc_item_list),
)
.clone_for_update();
// Fixup impl_def indentation
let indent = strukt.indent_level();
- impl_def.reindent_to(indent);
+ let impl_def = impl_def.indent(indent);
// Insert the impl block.
let strukt = edit.make_mut(strukt.clone());
- ted::insert_all(
- ted::Position::after(strukt.syntax()),
+ editor.insert_all(
+ Position::after(strukt.syntax()),
vec![
make::tokens::whitespace(&format!("\n\n{indent}")).into(),
impl_def.syntax().clone().into(),
],
);
-
- impl_def
+ impl_def.assoc_item_list().and_then(|list| list.assoc_items().next())
}
};
- // Fixup function indentation.
- // FIXME: Should really be handled by `AssocItemList::add_item`
- f.reindent_to(impl_def.indent_level() + 1);
-
- let assoc_items = impl_def.get_or_create_assoc_item_list();
- assoc_items.add_item(f.clone().into());
-
- if let Some(cap) = ctx.config.snippet_cap {
- edit.add_tabstop_before(cap, f)
+ if let Some(cap) = ctx.config.snippet_cap
+ && let Some(fn_) = fn_
+ {
+ let tabstop = edit.make_tabstop_before(cap);
+ editor.add_annotation(fn_.syntax(), tabstop);
}
+ edit.add_file_edits(ctx.vfs_file_id(), editor);
},
)?;
}
diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs
index fcb81d2..b38ee6f 100644
--- a/crates/ide-assists/src/handlers/generate_impl.rs
+++ b/crates/ide-assists/src/handlers/generate_impl.rs
@@ -201,7 +201,6 @@
&impl_,
&target_scope,
);
- let assoc_items = assoc_items.into_iter().map(either::Either::Right).collect();
let assoc_item_list = make::assoc_item_list(Some(assoc_items));
make_impl_(Some(assoc_item_list))
};
diff --git a/crates/ide-assists/src/handlers/generate_new.rs b/crates/ide-assists/src/handlers/generate_new.rs
index 5bda122..351f134 100644
--- a/crates/ide-assists/src/handlers/generate_new.rs
+++ b/crates/ide-assists/src/handlers/generate_new.rs
@@ -168,7 +168,7 @@
);
fn_.syntax().clone()
} else {
- let items = vec![either::Either::Right(ast::AssocItem::Fn(fn_))];
+ let items = vec![ast::AssocItem::Fn(fn_)];
let list = make::assoc_item_list(Some(items));
editor.insert(Position::after(impl_def.syntax()), list.syntax());
list.syntax().clone()
@@ -176,7 +176,7 @@
} else {
// Generate a new impl to add the method to
let indent_level = strukt.indent_level();
- let body = vec![either::Either::Right(ast::AssocItem::Fn(fn_))];
+ let body = vec![ast::AssocItem::Fn(fn_)];
let list = make::assoc_item_list(Some(body));
let impl_def = generate_impl_with_item(&ast::Adt::Struct(strukt.clone()), Some(list));
diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 45bb6ce..175f261 100644
--- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -221,11 +221,7 @@
} else {
Some(first.clone())
};
- let items = first_item
- .into_iter()
- .chain(other.iter().cloned())
- .map(either::Either::Right)
- .collect();
+ let items = first_item.into_iter().chain(other.iter().cloned()).collect();
make::assoc_item_list(Some(items))
} else {
make::assoc_item_list(None)
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 2a7b51c..daeb79c 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -229,9 +229,7 @@
}
}
-pub fn assoc_item_list(
- body: Option<Vec<either::Either<ast::Attr, ast::AssocItem>>>,
-) -> ast::AssocItemList {
+pub fn assoc_item_list(body: Option<Vec<ast::AssocItem>>) -> ast::AssocItemList {
let is_break_braces = body.is_some();
let body_newline = if is_break_braces { "\n".to_owned() } else { String::new() };
let body_indent = if is_break_braces { " ".to_owned() } else { String::new() };