Skip to content

Commit 80b311d

Browse files
committed
migrate generate_from_impl_for_enum to SyntaxEditor and SyntaxFactory and remove usage of remove-generate-trail-impl-text-intransitive
1 parent 3d0d8ac commit 80b311d

2 files changed

Lines changed: 65 additions & 44 deletions

File tree

crates/ide-assists/src/handlers/generate_deref.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,12 @@ fn generate_edit(
144144

145145
let assoc_items: Vec<ast::AssocItem> = match deref_type {
146146
DerefType::Deref => {
147-
let target_alias = make.ty_alias(
148-
[],
149-
"Target",
150-
None,
151-
None,
152-
None,
153-
Some((field_type, None)),
154-
);
147+
let target_alias =
148+
make.ty_alias([], "Target", None, None, None, Some((field_type, None)));
155149
let ret_ty =
156150
make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), false);
157-
let field_expr =
158-
make.expr_field(make.expr_path(make.ident_path("self")), field_name);
159-
let body =
160-
make.block_expr([], Some(make.expr_ref(field_expr.into(), false)));
151+
let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name);
152+
let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), false)));
161153
let fn_ = make
162154
.fn_(
163155
[],
@@ -174,18 +166,13 @@ fn generate_edit(
174166
false,
175167
)
176168
.indent(1.into());
177-
vec![
178-
ast::AssocItem::TypeAlias(target_alias),
179-
ast::AssocItem::Fn(fn_),
180-
]
169+
vec![ast::AssocItem::TypeAlias(target_alias), ast::AssocItem::Fn(fn_)]
181170
}
182171
DerefType::DerefMut => {
183172
let ret_ty =
184173
make.ty_ref(make.ty_path(make.path_from_text("Self::Target")).into(), true);
185-
let field_expr =
186-
make.expr_field(make.expr_path(make.ident_path("self")), field_name);
187-
let body =
188-
make.block_expr([], Some(make.expr_ref(field_expr.into(), true)));
174+
let field_expr = make.expr_field(make.expr_path(make.ident_path("self")), field_name);
175+
let body = make.block_expr([], Some(make.expr_ref(field_expr.into(), true)));
189176
let fn_ = make
190177
.fn_(
191178
[],

crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use hir::next_solver::{DbInterner, TypingMode};
22
use ide_db::{RootDatabase, famous_defs::FamousDefs};
3-
use syntax::ast::{self, AstNode, HasName};
3+
use syntax::ast::{self, AstNode, HasName, edit::AstNodeEdit, syntax_factory::SyntaxFactory};
4+
use syntax::syntax_editor::Position;
45

56
use crate::{
67
AssistContext, AssistId, Assists,
7-
utils::{generate_trait_impl_text_intransitive, is_selected},
8+
utils::{generate_trait_impl_intransitive_with_item, is_selected},
89
};
910

1011
// Assist: generate_from_impl_for_enum
@@ -33,39 +34,72 @@ pub(crate) fn generate_from_impl_for_enum(
3334
let variants = selected_variants(ctx, &variant)?;
3435

3536
let target = variant.syntax().text_range();
37+
let file_id = ctx.vfs_file_id();
3638
acc.add(
3739
AssistId::generate("generate_from_impl_for_enum"),
3840
"Generate `From` impl for this enum variant(s)",
3941
target,
4042
|edit| {
41-
let start_offset = variant.parent_enum().syntax().text_range().end();
42-
let from_impl = variants
43-
.into_iter()
44-
.map(|variant_info| {
45-
let from_trait = format!("From<{}>", variant_info.ty);
46-
let impl_code = generate_impl_code(variant_info);
47-
generate_trait_impl_text_intransitive(&adt, &from_trait, &impl_code)
48-
})
49-
.collect::<String>();
50-
edit.insert(start_offset, from_impl);
43+
let make = SyntaxFactory::with_mappings();
44+
let indent = adt.indent_level();
45+
let mut elements = Vec::new();
46+
47+
for variant_info in variants {
48+
let impl_ = build_from_impl(&make, &adt, variant_info).indent(indent);
49+
elements.push(make.whitespace(&format!("\n\n{indent}")).into());
50+
elements.push(impl_.syntax().clone().into());
51+
}
52+
53+
let mut editor = edit.make_editor(adt.syntax());
54+
editor.insert_all(Position::after(adt.syntax()), elements);
55+
editor.add_mappings(make.finish_with_mappings());
56+
edit.add_file_edits(file_id, editor);
5157
},
5258
)
5359
}
5460

55-
fn generate_impl_code(VariantInfo { name, field_name, ty }: VariantInfo) -> String {
56-
if let Some(field) = field_name {
57-
format!(
58-
r#" fn from({field}: {ty}) -> Self {{
59-
Self::{name} {{ {field} }}
60-
}}"#
61-
)
61+
fn build_from_impl(make: &SyntaxFactory, adt: &ast::Adt, variant_info: VariantInfo) -> ast::Impl {
62+
let VariantInfo { name, field_name, ty } = variant_info;
63+
let trait_ty = make.ty(&format!("From<{ty}>"));
64+
let ret_ty = make.ret_type(make.ty_path(make.ident_path("Self")).into());
65+
66+
let (params, body_expr) = if let Some(field) = field_name {
67+
let field_str = field.to_string();
68+
let param = make.param(make.ident_pat(false, false, make.name(&field_str)).into(), ty);
69+
let field_item = make.record_expr_field(make.name_ref(&field_str), None);
70+
let record = make.record_expr(
71+
make.path_from_text(&format!("Self::{name}")),
72+
make.record_expr_field_list([field_item]),
73+
);
74+
(make.param_list(None, [param]), ast::Expr::from(record))
6275
} else {
63-
format!(
64-
r#" fn from(v: {ty}) -> Self {{
65-
Self::{name}(v)
66-
}}"#
76+
let param = make.param(make.ident_pat(false, false, make.name("v")).into(), ty);
77+
let call = make.expr_call(
78+
make.expr_path(make.path_from_text(&format!("Self::{name}"))),
79+
make.arg_list([make.expr_path(make.ident_path("v"))]),
80+
);
81+
(make.param_list(None, [param]), ast::Expr::from(call))
82+
};
83+
84+
let from_fn = make
85+
.fn_(
86+
[],
87+
None,
88+
make.name("from"),
89+
None,
90+
None,
91+
params,
92+
make.block_expr([], Some(body_expr)),
93+
Some(ret_ty),
94+
false,
95+
false,
96+
false,
97+
false,
6798
)
68-
}
99+
.indent(1.into());
100+
101+
let body = make.assoc_item_list([ast::AssocItem::Fn(from_fn)]);
102+
generate_trait_impl_intransitive_with_item(make, adt, trait_ty, body)
69103
}
70104

71105
struct VariantInfo {

0 commit comments

Comments
 (0)