Skip to content

Commit 6bef398

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

File tree

1 file changed

+124
-9
lines changed

1 file changed

+124
-9
lines changed

crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,35 @@ 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_map(|field| field.name().filter(|_| field.visibility().is_none()))
169+
.for_each(|it| insert_pub(it.syntax()));
170+
171+
field_list.into()
161172
}
162-
Either::Right(field_list) => make::tuple_field_list(
173+
Either::Right(field_list) => {
174+
let field_list = field_list.clone_for_update();
175+
163176
field_list
164177
.fields()
165-
.flat_map(|field| Some(make::tuple_field(pub_vis.clone(), field.ty()?))),
166-
)
167-
.into(),
178+
.filter_map(|field| field.ty().filter(|_| field.visibility().is_none()))
179+
.for_each(|it| insert_pub(it.syntax()));
180+
181+
field_list.into()
182+
}
168183
};
169184

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

0 commit comments

Comments
 (0)