@@ -12,7 +12,7 @@ use syn::parse::Parse;
12
12
use syn:: punctuated:: Punctuated ;
13
13
use syn:: spanned:: Spanned ;
14
14
use syn:: Token ;
15
- use syn:: { parse_quote_spanned, LitStr } ;
15
+ use syn:: { parse_quote_spanned, Attribute , LitStr } ;
16
16
17
17
pub struct PropsMacroInput {
18
18
wrapper_ty : syn:: Path ,
@@ -255,6 +255,7 @@ struct PropDesc {
255
255
field_ident : syn:: Ident ,
256
256
ty : syn:: Type ,
257
257
name : syn:: LitStr ,
258
+ comments : Vec < Attribute > ,
258
259
override_class : Option < syn:: Type > ,
259
260
override_interface : Option < syn:: Type > ,
260
261
nullable : bool ,
@@ -271,6 +272,7 @@ impl PropDesc {
271
272
attrs_span : proc_macro2:: Span ,
272
273
field_ident : syn:: Ident ,
273
274
field_ty : syn:: Type ,
275
+ comments : Vec < Attribute > ,
274
276
attrs : ReceivedAttrs ,
275
277
) -> syn:: Result < Self > {
276
278
let ReceivedAttrs {
@@ -321,6 +323,7 @@ impl PropDesc {
321
323
field_ident,
322
324
ty,
323
325
name,
326
+ comments,
324
327
override_class,
325
328
override_interface,
326
329
nullable,
@@ -524,26 +527,33 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
524
527
}
525
528
526
529
fn parse_fields ( fields : syn:: Fields ) -> syn:: Result < Vec < PropDesc > > {
527
- fields
528
- . into_iter ( )
529
- . flat_map ( |field| {
530
- let syn:: Field {
531
- ident, attrs, ty, ..
532
- } = field;
533
- attrs
534
- . into_iter ( )
535
- . filter ( |a| a. path ( ) . is_ident ( "property" ) )
536
- . map ( move |prop_attrs| {
537
- let span = prop_attrs. span ( ) ;
538
- PropDesc :: new (
539
- span,
540
- ident. as_ref ( ) . unwrap ( ) . clone ( ) ,
541
- ty. clone ( ) ,
542
- prop_attrs. parse_args ( ) ?,
543
- )
544
- } )
545
- } )
546
- . collect :: < syn:: Result < _ > > ( )
530
+ let mut properties = vec ! [ ] ;
531
+
532
+ for field in fields. into_iter ( ) {
533
+ let syn:: Field {
534
+ ident, attrs, ty, ..
535
+ } = field;
536
+ // Store the comments until the next `#[property]` we see and then attach them to it.
537
+ let mut comments: Vec < Attribute > = vec ! [ ] ;
538
+ for prop_attr in attrs. iter ( ) {
539
+ if prop_attr. path ( ) . is_ident ( "doc" ) {
540
+ comments. push ( prop_attr. clone ( ) ) ;
541
+ } else if prop_attr. path ( ) . is_ident ( "property" ) {
542
+ let span = prop_attr. span ( ) ;
543
+ let existing_comments = comments;
544
+ comments = vec ! [ ] ;
545
+ properties. push ( PropDesc :: new (
546
+ span,
547
+ ident. as_ref ( ) . unwrap ( ) . clone ( ) ,
548
+ ty. clone ( ) ,
549
+ existing_comments,
550
+ prop_attr. parse_args ( ) ?,
551
+ ) ?) ;
552
+ }
553
+ }
554
+ }
555
+
556
+ Ok ( properties)
547
557
}
548
558
549
559
/// Converts a glib property name to a correct rust ident
@@ -567,7 +577,7 @@ fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
567
577
let ident = name_to_ident ( name) ;
568
578
let ty = & p. ty ;
569
579
570
- let getter = p. get . is_some ( ) . then ( || {
580
+ let mut getter: Option < syn :: ImplItemFn > = p. get . is_some ( ) . then ( || {
571
581
let span = p. attrs_span ;
572
582
parse_quote_spanned ! ( span=>
573
583
#[ must_use]
@@ -578,6 +588,12 @@ fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
578
588
)
579
589
} ) ;
580
590
591
+ if let Some ( ref mut getter) = getter {
592
+ for lit in & p. comments {
593
+ getter. attrs . push ( lit. clone ( ) ) ;
594
+ }
595
+ }
596
+
581
597
let setter = ( p. set . is_some ( ) && !p. is_construct_only ) . then ( || {
582
598
let ident = format_ident ! ( "set_{}" , ident) ;
583
599
let target_ty = quote ! ( <<#ty as #crate_ident:: property:: Property >:: Value as #crate_ident:: prelude:: HasParamSpec >:: SetValue ) ;
0 commit comments