Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/generate_single_field_struct_from.rs')
-rw-r--r--crates/ide-assists/src/handlers/generate_single_field_struct_from.rs110
1 files changed, 60 insertions, 50 deletions
diff --git a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
index d3022ceda3..2fc2b9efe8 100644
--- a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
+++ b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs
@@ -1,14 +1,16 @@
-use ast::make;
use hir::next_solver::{DbInterner, TypingMode};
use hir::{HasCrate, ModuleDef, Semantics};
use ide_db::{
RootDatabase, famous_defs::FamousDefs, helpers::mod_path_to_ast,
imports::import_assets::item_for_path_search, use_trivial_constructor::use_trivial_constructor,
};
-use syntax::syntax_editor::{Element, Position};
+use syntax::syntax_editor::{Position, SyntaxEditor};
use syntax::{
TokenText,
- ast::{self, AstNode, HasAttrs, HasGenericParams, HasName, edit::AstNodeEdit},
+ ast::{
+ self, AstNode, HasAttrs, HasGenericParams, HasName, edit::AstNodeEdit,
+ syntax_factory::SyntaxFactory,
+ },
};
use crate::{
@@ -78,47 +80,52 @@ pub(crate) fn generate_single_field_struct_from(
"Generate single field `From`",
strukt.syntax().text_range(),
|builder| {
+ let make = SyntaxFactory::with_mappings();
+ let mut editor = builder.make_editor(strukt.syntax());
+
let indent = strukt.indent_level();
let ty_where_clause = strukt.where_clause();
let type_gen_params = strukt.generic_param_list();
let type_gen_args = type_gen_params.as_ref().map(|params| params.to_generic_args());
- let trait_gen_args = Some(make::generic_arg_list([ast::GenericArg::TypeArg(
- make::type_arg(main_field_ty.clone()),
- )]));
+ let trait_gen_args = Some(make.generic_arg_list(
+ [ast::GenericArg::TypeArg(make.type_arg(main_field_ty.clone()))],
+ false,
+ ));
- let ty = make::ty(&strukt_name.text());
+ let ty = make.ty(&strukt_name.text());
let constructor =
- make_adt_constructor(names.as_deref(), constructors, &main_field_name);
- let body = make::block_expr([], Some(constructor));
+ make_adt_constructor(names.as_deref(), constructors, &main_field_name, &make);
+ let body = make.block_expr([], Some(constructor));
- let fn_ = make::fn_(
- None,
- None,
- make::name("from"),
- None,
- None,
- make::param_list(
+ let fn_ = make
+ .fn_(
+ [],
None,
- [make::param(
- make::path_pat(make::path_from_text(&main_field_name)),
- main_field_ty,
- )],
- ),
- body,
- Some(make::ret_type(make::ty("Self"))),
- false,
- false,
- false,
- false,
- )
- .indent(1.into());
+ make.name("from"),
+ None,
+ None,
+ make.param_list(
+ None,
+ [make.param(
+ make.path_pat(make.path_from_text(&main_field_name)),
+ main_field_ty,
+ )],
+ ),
+ body,
+ Some(make.ret_type(make.ty("Self"))),
+ false,
+ false,
+ false,
+ false,
+ )
+ .indent_with_mapping(1.into(), &make);
let cfg_attrs = strukt
.attrs()
.filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg"));
- let impl_ = make::impl_trait(
+ let impl_ = make.impl_trait(
cfg_attrs,
false,
None,
@@ -126,28 +133,31 @@ pub(crate) fn generate_single_field_struct_from(
type_gen_params,
type_gen_args,
false,
- make::ty("From"),
+ make.ty("From"),
ty.clone(),
None,
ty_where_clause.map(|wc| wc.reset_indent()),
None,
- )
- .clone_for_update();
-
- impl_.get_or_create_assoc_item_list().add_item(fn_.into());
- let impl_ = impl_.indent(indent);
+ );
- let mut edit = builder.make_editor(strukt.syntax());
+ let (mut impl_editor, impl_root) = SyntaxEditor::with_ast_node(&impl_);
+ let assoc_list =
+ impl_root.get_or_create_assoc_item_list_with_editor(&mut impl_editor, &make);
+ assoc_list.add_items(&mut impl_editor, vec![fn_.into()]);
+ let impl_ = ast::Impl::cast(impl_editor.finish().new_root().clone())
+ .unwrap()
+ .indent_with_mapping(indent, &make);
- edit.insert_all(
+ editor.insert_all(
Position::after(strukt.syntax()),
vec![
- make::tokens::whitespace(&format!("\n\n{indent}")).syntax_element(),
- impl_.syntax().syntax_element(),
+ make.whitespace(&format!("\n\n{indent}")).into(),
+ impl_.syntax().clone().into(),
],
);
- builder.add_file_edits(ctx.vfs_file_id(), edit);
+ editor.add_mappings(make.finish_with_mappings());
+ builder.add_file_edits(ctx.vfs_file_id(), editor);
},
)
}
@@ -156,19 +166,18 @@ fn make_adt_constructor(
names: Option<&[ast::Name]>,
constructors: Vec<Option<ast::Expr>>,
main_field_name: &TokenText<'_>,
+ make: &SyntaxFactory,
) -> ast::Expr {
if let Some(names) = names {
- let fields = make::record_expr_field_list(names.iter().zip(constructors).map(
- |(name, initializer)| {
- make::record_expr_field(make::name_ref(&name.text()), initializer)
- },
+ let fields = make.record_expr_field_list(names.iter().zip(constructors).map(
+ |(name, initializer)| make.record_expr_field(make.name_ref(&name.text()), initializer),
));
- make::record_expr(make::path_from_text("Self"), fields).into()
+ make.record_expr(make.path_from_text("Self"), fields).into()
} else {
- let arg_list = make::arg_list(constructors.into_iter().map(|expr| {
- expr.unwrap_or_else(|| make::expr_path(make::path_from_text(main_field_name)))
+ let arg_list = make.arg_list(constructors.into_iter().map(|expr| {
+ expr.unwrap_or_else(|| make.expr_path(make.path_from_text(main_field_name)))
}));
- make::expr_call(make::expr_path(make::path_from_text("Self")), arg_list).into()
+ make.expr_call(make.expr_path(make.path_from_text("Self")), arg_list).into()
}
}
@@ -177,6 +186,7 @@ fn make_constructors(
module: hir::Module,
types: &[ast::Type],
) -> Vec<Option<ast::Expr>> {
+ let make = SyntaxFactory::without_mappings();
let (db, sema) = (ctx.db(), &ctx.sema);
let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db)));
types
@@ -184,7 +194,7 @@ fn make_constructors(
.map(|ty| {
let ty = sema.resolve_type(ty)?;
if ty.is_unit() {
- return Some(make::expr_tuple([]).into());
+ return Some(make.expr_tuple([]).into());
}
let item_in_ns = ModuleDef::Adt(ty.as_adt()?).into();
let edition = module.krate(db).edition(db);