@@ -57,7 +57,9 @@ use crate::ir::var::Var;
57
57
58
58
use proc_macro2:: { Ident , Span , TokenStream } ;
59
59
use quote:: { ToTokens , TokenStreamExt } ;
60
- use syn:: { parse_quote, Attribute } ;
60
+ use syn:: parse:: ParseStream ;
61
+ use syn:: token:: Pound ;
62
+ use syn:: { parse, parse2, parse_quote, parse_str, Attribute , Block } ;
61
63
62
64
use crate :: { Entry , HashMap , HashSet } ;
63
65
use std:: borrow:: Cow ;
@@ -500,6 +502,51 @@ trait CodeGenerator {
500
502
) -> Self :: Return ;
501
503
}
502
504
505
+ fn normalize_attributes ( attrs : HashSet < String > ) -> HashSet < String > {
506
+ attrs
507
+ . iter ( )
508
+ . map ( |attr| {
509
+ let mut in_quotes = None ;
510
+ attr. chars ( )
511
+ . filter_map ( |c| match c {
512
+ '"' | '\'' if in_quotes. is_none ( ) => {
513
+ in_quotes = Some ( c) ;
514
+ Some ( c)
515
+ }
516
+ c if in_quotes == Some ( c) => {
517
+ in_quotes = None ;
518
+ Some ( c)
519
+ }
520
+ c if in_quotes. is_some ( ) => Some ( c) ,
521
+ c if !c. is_whitespace ( ) => Some ( c) ,
522
+ _ => None ,
523
+ } )
524
+ . collect ( )
525
+ } )
526
+ . collect ( )
527
+ }
528
+
529
+ fn process_attributes (
530
+ result : & mut CodegenResult ,
531
+ item : & Item ,
532
+ ctx : & BindgenContext ,
533
+ attrs : HashSet < String > ,
534
+ kind : AttributeItemKind ,
535
+ ) -> Vec < TokenStream > {
536
+ let mut attrs = normalize_attributes ( attrs) ;
537
+ ctx. options ( ) . for_each_callback_mut ( |cb| {
538
+ cb. process_attributes (
539
+ & AttributeInfo {
540
+ name : & item. canonical_name ( ctx) ,
541
+ kind,
542
+ } ,
543
+ & mut attrs,
544
+ ) ;
545
+ } ) ;
546
+ result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
547
+ parse_tokens ( normalize_attributes ( attrs) )
548
+ }
549
+
503
550
impl Item {
504
551
fn process_before_codegen (
505
552
& self ,
@@ -703,17 +750,24 @@ impl CodeGenerator for Var {
703
750
let ty = var_ty. to_rust_ty_or_opaque ( ctx, & ( ) ) ;
704
751
705
752
if let Some ( val) = self . val ( ) {
706
- ctx. options ( ) . for_each_callback_mut ( |cb| {
707
- cb. process_attributes (
708
- & AttributeInfo {
709
- name : & canonical_name,
710
- kind : AttributeItemKind :: Var ,
711
- } ,
712
- & mut attrs,
713
- ) ;
714
- } ) ;
715
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
716
- let attrs = parse_tokens ( attrs) ;
753
+ /*if let Item::Fn(func) = item {
754
+ for attr in func.attrs {
755
+ // Process the attribute and extract key-value pairs
756
+ if let Ok(Meta::NameValue(meta)) = attr.parse_meta() {
757
+ // Check if the value of the attribute is a string literal
758
+ if let Lit::Str(value) = meta.lit {
759
+ attrs.insert(meta.path.get_ident().unwrap().to_string(), value.value());
760
+ }
761
+ }
762
+ }
763
+ }*/
764
+ let attrs = process_attributes (
765
+ result,
766
+ item,
767
+ ctx,
768
+ attrs,
769
+ AttributeItemKind :: Var ,
770
+ ) ;
717
771
718
772
match * val {
719
773
VarType :: Bool ( val) => {
@@ -829,17 +883,13 @@ impl CodeGenerator for Var {
829
883
}
830
884
}
831
885
832
- ctx. options ( ) . for_each_callback_mut ( |cb| {
833
- cb. process_attributes (
834
- & AttributeInfo {
835
- name : & canonical_name,
836
- kind : AttributeItemKind :: Var ,
837
- } ,
838
- & mut attrs,
839
- ) ;
840
- } ) ;
841
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
842
- let attrs = parse_tokens ( attrs) ;
886
+ let attrs = process_attributes (
887
+ result,
888
+ item,
889
+ ctx,
890
+ attrs,
891
+ AttributeItemKind :: Var ,
892
+ ) ;
843
893
844
894
let maybe_mut = if self . is_const ( ) {
845
895
quote ! { }
@@ -1068,15 +1118,17 @@ impl CodeGenerator for Type {
1068
1118
// Only apply attributes through type aliases when they are relevant to compilation
1069
1119
attrs. extend (
1070
1120
parse_tokens ( inner_attrs)
1071
- . into_iter ( )
1072
- . map ( |attr| parse_quote ! { #attr } )
1073
- . filter_map ( |attr : Attribute |{
1074
- if attr. path ( ) . is_ident ( "cfg" ) || attr. path ( ) . is_ident ( "link" ) {
1075
- Some ( attr. to_token_stream ( ) . to_string ( ) )
1076
- } else {
1077
- None
1078
- }
1079
- } )
1121
+ . into_iter ( )
1122
+ . map ( |attr| parse_quote ! { #attr } )
1123
+ . filter_map ( |attr : Attribute | {
1124
+ if attr. path ( ) . is_ident ( "cfg" ) ||
1125
+ attr. path ( ) . is_ident ( "link" )
1126
+ {
1127
+ Some ( attr. to_token_stream ( ) . to_string ( ) )
1128
+ } else {
1129
+ None
1130
+ }
1131
+ } ) ,
1080
1132
) ;
1081
1133
}
1082
1134
@@ -1088,28 +1140,18 @@ impl CodeGenerator for Type {
1088
1140
attrs. insert ( attributes:: doc ( comment) . to_string ( ) ) ;
1089
1141
}
1090
1142
1091
- // Allow the callbacks to process our attributes
1092
- ctx. options ( ) . for_each_callback_mut ( |cb| {
1093
- cb. process_attributes (
1094
- & AttributeInfo {
1095
- name : & name,
1096
- // FIXME: Introduce a TypeAlias variant with extra information similar
1097
- // to DiscoveredItem::Alias, indicating this is merely an alias
1098
- // and not a new type definition.
1099
- kind : AttributeItemKind :: Struct ,
1100
- } ,
1101
- & mut attrs,
1102
- ) ;
1103
- } ) ;
1104
-
1105
- // Store the final attributes of this item
1106
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
1143
+ let attrs = process_attributes (
1144
+ result,
1145
+ item,
1146
+ ctx,
1147
+ attrs,
1148
+ AttributeItemKind :: Struct ,
1149
+ ) ;
1107
1150
1108
- let attrs = parse_tokens ( attrs) ;
1109
1151
let mut tokens = quote ! {
1110
1152
#( #attrs ) *
1111
1153
} ;
1112
-
1154
+
1113
1155
// We prefer using `pub use` over `pub type` because of:
1114
1156
// https://github.com/rust-lang/rust/issues/26264
1115
1157
if matches ! ( inner_rust_type, syn:: Type :: Path ( _) ) &&
@@ -2608,21 +2650,18 @@ impl CodeGenerator for CompInfo {
2608
2650
}
2609
2651
2610
2652
attrs. extend ( item. annotations ( ) . attributes ( ) . iter ( ) . cloned ( ) ) ;
2611
- ctx. options ( ) . for_each_callback_mut ( |cb| {
2612
- cb. process_attributes (
2613
- & AttributeInfo {
2614
- name : & canonical_name,
2615
- kind : if is_rust_union {
2616
- AttributeItemKind :: Union
2617
- } else {
2618
- AttributeItemKind :: Struct
2619
- } ,
2620
- } ,
2621
- & mut attrs,
2622
- ) ;
2623
- } ) ;
2624
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
2625
- let attrs = parse_tokens ( attrs) ;
2653
+
2654
+ let attrs = process_attributes (
2655
+ result,
2656
+ item,
2657
+ ctx,
2658
+ attrs,
2659
+ if is_rust_union {
2660
+ AttributeItemKind :: Union
2661
+ } else {
2662
+ AttributeItemKind :: Struct
2663
+ } ,
2664
+ ) ;
2626
2665
2627
2666
let mut tokens = if is_rust_union {
2628
2667
quote ! {
@@ -3234,19 +3273,13 @@ impl Method {
3234
3273
attrs. insert ( attributes:: must_use ( ) . to_string ( ) ) ;
3235
3274
}
3236
3275
3237
- ctx. options ( ) . for_each_callback_mut ( |cb| {
3238
- cb. process_attributes (
3239
- & AttributeInfo {
3240
- name : & canonical_name,
3241
- kind : AttributeItemKind :: Function ( FunctionKind :: Method (
3242
- self . kind ( ) ,
3243
- ) ) ,
3244
- } ,
3245
- & mut attrs,
3246
- ) ;
3247
- } ) ;
3248
- result. set_attributes ( function_item. id ( ) , attrs. clone ( ) ) ;
3249
- let attrs = parse_tokens ( attrs) ;
3276
+ let attrs = process_attributes (
3277
+ result,
3278
+ function_item,
3279
+ ctx,
3280
+ attrs,
3281
+ AttributeItemKind :: Function ( FunctionKind :: Method ( self . kind ( ) ) ) ,
3282
+ ) ;
3250
3283
3251
3284
let name = ctx. rust_ident ( & name) ;
3252
3285
methods. push ( quote ! {
@@ -3859,20 +3892,21 @@ impl CodeGenerator for Enum {
3859
3892
// add them to the end of the list.
3860
3893
attrs. extend ( item. annotations ( ) . attributes ( ) . iter ( ) . cloned ( ) ) ;
3861
3894
3862
- ctx. options ( ) . for_each_callback_mut ( |cb| {
3863
- cb. process_attributes (
3864
- & AttributeInfo {
3865
- name : & name,
3866
- kind : AttributeItemKind :: Enum ,
3867
- } ,
3868
- & mut attrs,
3869
- ) ;
3870
- } ) ;
3871
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
3895
+ let attrs = process_attributes (
3896
+ result,
3897
+ item,
3898
+ ctx,
3899
+ attrs,
3900
+ AttributeItemKind :: Enum ,
3901
+ ) ;
3872
3902
3873
- let attrs = parse_tokens ( attrs) ;
3874
- let mut builder =
3875
- EnumBuilder :: new ( & name, attrs. clone ( ) , repr, variation, has_typedef) ;
3903
+ let mut builder = EnumBuilder :: new (
3904
+ & name,
3905
+ attrs. clone ( ) ,
3906
+ repr,
3907
+ variation,
3908
+ has_typedef,
3909
+ ) ;
3876
3910
3877
3911
// A map where we keep a value -> variant relation.
3878
3912
let mut seen_values = HashMap :: < _ , Ident > :: default ( ) ;
@@ -4820,18 +4854,14 @@ impl CodeGenerator for Function {
4820
4854
. unsafe_extern_blocks
4821
4855
. then ( || quote ! ( unsafe ) ) ;
4822
4856
4823
- ctx. options ( ) . for_each_callback_mut ( |cb| {
4824
- cb. process_attributes (
4825
- & AttributeInfo {
4826
- name : & name,
4827
- kind : AttributeItemKind :: Function ( self . kind ( ) ) ,
4828
- } ,
4829
- & mut attrs,
4830
- ) ;
4831
- } ) ;
4832
- result. set_attributes ( item. id ( ) , attrs. clone ( ) ) ;
4857
+ let attrs = process_attributes (
4858
+ result,
4859
+ item,
4860
+ ctx,
4861
+ attrs,
4862
+ AttributeItemKind :: Function ( FunctionKind :: Function ) ,
4863
+ ) ;
4833
4864
4834
- let attrs = parse_tokens ( attrs) ;
4835
4865
let tokens = quote ! {
4836
4866
#wasm_link_attribute
4837
4867
#safety extern #abi {
0 commit comments