Skip to content

Commit 7fefac4

Browse files
committed
Keep comments and attrs when extracting struct from enum variant
1 parent c7edc38 commit 7fefac4

File tree

1 file changed

+126
-9
lines changed

1 file changed

+126
-9
lines changed

crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,37 @@ fn create_struct_def(
151151
field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>,
152152
visibility: Option<ast::Visibility>,
153153
) -> ast::Struct {
154-
let pub_vis = Some(make::visibility_pub());
154+
let pub_vis = make::visibility_pub();
155+
156+
let insert_pub = |node: &'_ SyntaxNode| {
157+
let pub_vis = pub_vis.clone_for_update();
158+
ted::insert(ted::Position::before(node), pub_vis.syntax());
159+
};
160+
161+
// for fields without any existing visibility, use pub visibility
155162
let field_list = match field_list {
156163
Either::Left(field_list) => {
157-
make::record_field_list(field_list.fields().flat_map(|field| {
158-
Some(make::record_field(pub_vis.clone(), field.name()?, field.ty()?))
159-
}))
160-
.into()
164+
let field_list = field_list.clone_for_update();
165+
166+
field_list
167+
.fields()
168+
.filter(|field| field.visibility().is_none())
169+
.filter_map(|field| field.name())
170+
.for_each(|it| insert_pub(it.syntax()));
171+
172+
field_list.into()
161173
}
162-
Either::Right(field_list) => make::tuple_field_list(
174+
Either::Right(field_list) => {
175+
let field_list = field_list.clone_for_update();
176+
163177
field_list
164178
.fields()
165-
.flat_map(|field| Some(make::tuple_field(pub_vis.clone(), field.ty()?))),
166-
)
167-
.into(),
179+
.filter(|field| field.visibility().is_none())
180+
.filter_map(|field| field.ty())
181+
.for_each(|it| insert_pub(it.syntax()));
182+
183+
field_list.into()
184+
}
168185
};
169186

170187
make::struct_(visibility, variant_name, None, field_list).clone_for_update()
@@ -290,6 +307,106 @@ enum A { One(One) }"#,
290307
"enum A { $0One { foo: u32 } }",
291308
r#"struct One{ pub foo: u32 }
292309
310+
enum A { One(One) }"#,
311+
);
312+
}
313+
314+
#[test]
315+
fn test_extract_struct_keep_comments_and_attrs_one_field_named() {
316+
check_assist(
317+
extract_struct_from_enum_variant,
318+
r#"
319+
enum A {
320+
$0One {
321+
// leading comment
322+
/// doc comment
323+
#[an_attr]
324+
foo: u32
325+
// trailing comment
326+
}
327+
}"#,
328+
r#"
329+
struct One{
330+
// leading comment
331+
/// doc comment
332+
#[an_attr]
333+
pub foo: u32
334+
// trailing comment
335+
}
336+
337+
enum A {
338+
One(One)
339+
}"#,
340+
);
341+
}
342+
343+
#[test]
344+
fn test_extract_struct_keep_comments_and_attrs_several_fields_named() {
345+
check_assist(
346+
extract_struct_from_enum_variant,
347+
r#"
348+
enum A {
349+
$0One {
350+
// comment
351+
/// doc
352+
#[attr]
353+
foo: u32,
354+
// comment
355+
#[attr]
356+
/// doc
357+
bar: u32
358+
}
359+
}"#,
360+
r#"
361+
struct One{
362+
// comment
363+
/// doc
364+
#[attr]
365+
pub foo: u32,
366+
// comment
367+
#[attr]
368+
/// doc
369+
pub bar: u32
370+
}
371+
372+
enum A {
373+
One(One)
374+
}"#,
375+
);
376+
}
377+
378+
#[test]
379+
fn test_extract_struct_keep_comments_and_attrs_several_fields_tuple() {
380+
check_assist(
381+
extract_struct_from_enum_variant,
382+
"enum A { $0One(/* comment */ #[attr] u32, /* another */ u32 /* tail */) }",
383+
r#"
384+
struct One(/* comment */ #[attr] pub u32, /* another */ pub u32 /* tail */);
385+
386+
enum A { One(One) }"#,
387+
);
388+
}
389+
390+
#[test]
391+
fn test_extract_struct_keep_existing_visibility_named() {
392+
check_assist(
393+
extract_struct_from_enum_variant,
394+
"enum A { $0One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, d: u32 } }",
395+
r#"
396+
struct One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, pub d: u32 }
397+
398+
enum A { One(One) }"#,
399+
);
400+
}
401+
402+
#[test]
403+
fn test_extract_struct_keep_existing_visibility_tuple() {
404+
check_assist(
405+
extract_struct_from_enum_variant,
406+
"enum A { $0One(pub u32, pub(crate) u32, pub(super) u32, u32) }",
407+
r#"
408+
struct One(pub u32, pub(crate) u32, pub(super) u32, pub u32);
409+
293410
enum A { One(One) }"#,
294411
);
295412
}

0 commit comments

Comments
 (0)