@@ -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+
293410enum A { One(One) }"# ,
294411 ) ;
295412 }
0 commit comments