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