frame_support_procedural/pallet/expand/
event.rs1use crate::{
19 deprecation::extract_or_return_allow_attrs,
20 pallet::{parse::event::PalletEventDepositAttr, Def},
21 COUNTER,
22};
23use frame_support_procedural_tools::get_doc_literals;
24use syn::{spanned::Spanned, Ident};
25
26pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream {
31 let count = COUNTER.with(|counter| counter.borrow_mut().inc());
32
33 let (event, macro_ident) = if let Some(event) = &def.event {
34 let ident = Ident::new(&format!("__is_event_part_defined_{}", count), event.attr_span);
35 (event, ident)
36 } else {
37 let macro_ident =
38 Ident::new(&format!("__is_event_part_defined_{}", count), def.item.span());
39
40 return quote::quote! {
41 #[doc(hidden)]
42 pub mod __substrate_event_check {
43 #[macro_export]
44 #[doc(hidden)]
45 macro_rules! #macro_ident {
46 ($pallet_name:ident) => {
47 compile_error!(concat!(
48 "`",
49 stringify!($pallet_name),
50 "` does not have #[pallet::event] defined, perhaps you should \
51 remove `Event` from construct_runtime?",
52 ));
53 }
54 }
55
56 #[doc(hidden)]
57 pub use #macro_ident as is_event_part_defined;
58 }
59 }
60 };
61
62 let event_where_clause = &event.where_clause;
63
64 let completed_where_clause =
68 super::merge_where_clauses(&[&event.where_clause, &def.config.where_clause]);
69
70 let event_ident = &event.event;
71 let frame_system = &def.frame_system;
72 let frame_support = &def.frame_support;
73 let event_use_gen = &event.gen_kind.type_use_gen(event.attr_span);
74 let event_impl_gen = &event.gen_kind.type_impl_gen(event.attr_span);
75 let event_item = {
76 let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[event.index];
77 if let syn::Item::Enum(item) = item {
78 item
79 } else {
80 unreachable!("Checked by event parser")
81 }
82 };
83
84 if event.gen_kind.is_generic() {
86 let variant = syn::parse_quote!(
87 #[doc(hidden)]
88 #[codec(skip)]
89 __Ignore(
90 ::core::marker::PhantomData<(#event_use_gen)>,
91 #frame_support::Never,
92 )
93 );
94
95 event_item.variants.push(variant);
97 }
98
99 let deprecation = match crate::deprecation::get_deprecation_enum(
100 "e::quote! {#frame_support},
101 event_item.variants.iter().enumerate().map(|(index, item)| {
102 let index = crate::deprecation::variant_index_for_deprecation(index as u8, item);
103
104 (index, item.attrs.as_ref())
105 }),
106 ) {
107 Ok(deprecation) => deprecation,
108 Err(e) => return e.into_compile_error(),
109 };
110
111 if get_doc_literals(&event_item.attrs).is_empty() {
112 event_item
113 .attrs
114 .push(syn::parse_quote!(#[doc = "The `Event` enum of this pallet"]));
115 }
116
117 event_item.attrs.push(syn::parse_quote!(
119 #[derive(
120 #frame_support::CloneNoBound,
121 #frame_support::EqNoBound,
122 #frame_support::PartialEqNoBound,
123 #frame_support::DebugNoBound,
124 #frame_support::__private::codec::Encode,
125 #frame_support::__private::codec::Decode,
126 #frame_support::__private::codec::DecodeWithMemTracking,
127 #frame_support::__private::scale_info::TypeInfo,
128 )]
129 ));
130
131 let capture_docs = if cfg!(feature = "no-metadata-docs") { "never" } else { "always" };
132
133 event_item.attrs.push(syn::parse_quote!(
135 #[scale_info(skip_type_params(#event_use_gen), capture_docs = #capture_docs)]
136 ));
137
138 let maybe_allow_attrs: Vec<syn::Attribute> =
140 extract_or_return_allow_attrs(&event_item.attrs).collect();
141
142 let deposit_event = if let Some(deposit_event) = &event.deposit_event {
143 let event_use_gen = &event.gen_kind.type_use_gen(event.attr_span);
144 let type_impl_gen = &def.type_impl_generics(event.attr_span);
145 let type_use_gen = &def.type_use_generics(event.attr_span);
146 let pallet_ident = &def.pallet_struct.pallet;
147
148 let PalletEventDepositAttr { fn_vis, fn_span, .. } = deposit_event;
149
150 quote::quote_spanned!(*fn_span =>
151 impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause {
152 #(#maybe_allow_attrs)*
153 #fn_vis fn deposit_event(event: Event<#event_use_gen>) {
154 let event = <
155 <T as #frame_system::Config>::RuntimeEvent as
156 From<Event<#event_use_gen>>
157 >::from(event);
158
159 let event = <
160 <T as #frame_system::Config>::RuntimeEvent as
161 Into<<T as #frame_system::Config>::RuntimeEvent>
162 >::into(event);
163
164 <#frame_system::Pallet<T>>::deposit_event(event)
165 }
166 }
167 )
168 } else {
169 Default::default()
170 };
171
172 quote::quote_spanned!(event.attr_span =>
173 #[doc(hidden)]
174 pub mod __substrate_event_check {
175 #[macro_export]
176 #[doc(hidden)]
177 macro_rules! #macro_ident {
178 ($pallet_name:ident) => {};
179 }
180
181 #[doc(hidden)]
182 pub use #macro_ident as is_event_part_defined;
183 }
184
185 #deposit_event
186
187 #(#maybe_allow_attrs)*
188 impl<#event_impl_gen> From<#event_ident<#event_use_gen>> for () #event_where_clause {
189 fn from(_: #event_ident<#event_use_gen>) {}
190 }
191
192 #(#maybe_allow_attrs)*
193 impl<#event_impl_gen> #event_ident<#event_use_gen> #event_where_clause {
194 #[allow(dead_code)]
195 #[doc(hidden)]
196 pub fn event_metadata<W: #frame_support::__private::scale_info::TypeInfo + 'static>() -> #frame_support::__private::metadata_ir::PalletEventMetadataIR {
197 #frame_support::__private::metadata_ir::PalletEventMetadataIR {
198 ty: #frame_support::__private::scale_info::meta_type::<W>(),
199 deprecation_info: #deprecation,
200 }
201 }
202 }
203 )
204}