12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
- use crate :: GenerateCode ;
16
15
use derive_more:: From ;
16
+ #[ cfg( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ]
17
+ use ir:: IsDocAttribute ;
17
18
use proc_macro2:: TokenStream as TokenStream2 ;
19
+ use quote:: quote;
18
20
use syn:: spanned:: Spanned ;
21
+ #[ cfg( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ]
22
+ use syn:: Fields ;
23
+
24
+ #[ cfg( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ]
25
+ use crate :: generator:: sol;
26
+ use crate :: GenerateCode ;
19
27
20
28
/// Generates code for the event item.
21
29
#[ derive( From , Copy , Clone ) ]
@@ -38,6 +46,12 @@ impl GenerateCode for Event<'_> {
38
46
. map ( |hex_s| quote:: quote! { #[ ink( signature_topic = #hex_s) ] } ) ;
39
47
let cfg_attrs = self . item . get_cfg_attrs ( item. span ( ) ) ;
40
48
49
+ #[ cfg( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ]
50
+ let sol_event_metadata = self . solidity_event_metadata ( ) ;
51
+
52
+ #[ cfg( not( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ) ]
53
+ let sol_event_metadata = quote ! { } ;
54
+
41
55
quote:: quote! (
42
56
#( #cfg_attrs ) *
43
57
#[ cfg_attr( feature = "std" , derive( :: ink:: EventMetadata ) ) ]
@@ -46,6 +60,82 @@ impl GenerateCode for Event<'_> {
46
60
#anonymous
47
61
#signature_topic
48
62
#item
63
+
64
+ #sol_event_metadata
49
65
)
50
66
}
51
67
}
68
+
69
+ impl Event < ' _ > {
70
+ /// Generates Solidity ABI compatible metadata for ink! event.
71
+ #[ cfg( all( feature = "std" , any( ink_abi = "sol" , ink_abi = "all" ) ) ) ]
72
+ fn solidity_event_metadata ( & self ) -> TokenStream2 {
73
+ let item = self . item . item ( ) ;
74
+ let ident = & item. ident ;
75
+ let name = ident. to_string ( ) ;
76
+ let is_anonymous = self . item . anonymous ( ) ;
77
+
78
+ let fields = match & item. fields {
79
+ Fields :: Named ( fields) => fields,
80
+ Fields :: Unnamed ( _) | Fields :: Unit => unreachable ! ( "Expected named fields" ) ,
81
+ } ;
82
+ let params = fields. named . iter ( ) . map ( |field| {
83
+ let ty = & field. ty ;
84
+ let sol_ty = sol:: utils:: sol_type ( ty) ;
85
+ let ident = field. ident . as_ref ( ) . expect ( "Expected a named field" ) ;
86
+ let name = ident. to_string ( ) ;
87
+ let is_topic = field. attrs . iter ( ) . any ( |attr| {
88
+ let is_topic_arg = || {
89
+ attr. parse_nested_meta ( |meta| {
90
+ if meta. path . is_ident ( "topic" ) {
91
+ Ok ( ( ) )
92
+ } else {
93
+ Err ( meta. error ( "Not a topic arg" ) )
94
+ }
95
+ } )
96
+ . is_ok ( )
97
+ } ;
98
+ attr. path ( ) . is_ident ( "ink" ) && is_topic_arg ( )
99
+ } ) ;
100
+ let docs = field
101
+ . attrs
102
+ . iter ( )
103
+ . filter_map ( |attr| attr. extract_docs ( ) )
104
+ . collect :: < Vec < _ > > ( )
105
+ . join ( "\n " ) ;
106
+
107
+ quote ! {
108
+ :: ink:: metadata:: sol:: EventParamMetadata {
109
+ name: #name,
110
+ ty: #sol_ty,
111
+ is_topic: #is_topic,
112
+ docs: #docs,
113
+ }
114
+ }
115
+ } ) ;
116
+
117
+ let docs = item
118
+ . attrs
119
+ . iter ( )
120
+ . filter_map ( |attr| attr. extract_docs ( ) )
121
+ . collect :: < Vec < _ > > ( )
122
+ . join ( "\n " ) ;
123
+
124
+ quote ! {
125
+ const _: ( ) = {
126
+ // Register Solidity ABI compatible metadata function for event in distributed slice
127
+ // for collecting all events referenced in the contract binary.
128
+ #[ :: ink:: linkme:: distributed_slice( :: ink:: CONTRACT_EVENTS_SOL ) ]
129
+ #[ linkme( crate = :: ink:: linkme) ]
130
+ static EVENT_METADATA_SOL : fn ( ) -> :: ink:: metadata:: sol:: EventMetadata = || {
131
+ :: ink:: metadata:: sol:: EventMetadata {
132
+ name: #name,
133
+ is_anonymous: #is_anonymous,
134
+ params: vec![ #( #params ) , * ] ,
135
+ docs: #docs,
136
+ }
137
+ } ;
138
+ } ;
139
+ }
140
+ }
141
+ }
0 commit comments