Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -30,56 +30,61 @@ pub fn derive_clone_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
let impl_ = match input.data {
syn::Data::Struct(struct_) => match struct_.fields {
syn::Fields::Named(named) => {
let fields = named.named.iter()
.map(|i| &i.ident)
.map(|i| quote::quote_spanned!(i.span() =>
let fields = named.named.iter().map(|i| &i.ident).map(|i| {
quote::quote_spanned!(i.span() =>
#i: core::clone::Clone::clone(&self.#i)
));
)
});
quote::quote!( Self { #( #fields, )* } )
},
syn::Fields::Unnamed(unnamed) => {
let fields = unnamed.unnamed.iter().enumerate()
.map(|(i, _)| syn::Index::from(i))
.map(|i| quote::quote_spanned!(i.span() =>
core::clone::Clone::clone(&self.#i)
));
let fields =
unnamed.unnamed.iter().enumerate().map(|(i, _)| syn::Index::from(i)).map(|i| {
quote::quote_spanned!(i.span() =>
core::clone::Clone::clone(&self.#i)
)
});
quote::quote!( Self ( #( #fields, )* ) )
},
syn::Fields::Unit => {
quote::quote!( Self )
}
quote::quote!(Self)
},
},
syn::Data::Enum(enum_) => {
let variants = enum_.variants.iter()
.map(|variant| {
let ident = &variant.ident;
match &variant.fields {
syn::Fields::Named(named) => {
let captured = named.named.iter().map(|i| &i.ident);
let cloned = captured.clone()
.map(|i| quote::quote_spanned!(i.span() =>
#i: core::clone::Clone::clone(#i)
));
quote::quote!(
Self::#ident { #( ref #captured, )* } => Self::#ident { #( #cloned, )*}
let variants = enum_.variants.iter().map(|variant| {
let ident = &variant.ident;
match &variant.fields {
syn::Fields::Named(named) => {
let captured = named.named.iter().map(|i| &i.ident);
let cloned = captured.clone().map(|i| {
quote::quote_spanned!(i.span() =>
#i: core::clone::Clone::clone(#i)
)
},
syn::Fields::Unnamed(unnamed) => {
let captured = unnamed.unnamed.iter().enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}", i), f.span()));
let cloned = captured.clone()
.map(|i| quote::quote_spanned!(i.span() =>
core::clone::Clone::clone(#i)
));
quote::quote!(
Self::#ident ( #( ref #captured, )* ) => Self::#ident ( #( #cloned, )*)
});
quote::quote!(
Self::#ident { #( ref #captured, )* } => Self::#ident { #( #cloned, )*}
)
},
syn::Fields::Unnamed(unnamed) => {
let captured = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}", i), f.span()));
let cloned = captured.clone().map(|i| {
quote::quote_spanned!(i.span() =>
core::clone::Clone::clone(#i)
)
},
syn::Fields::Unit => quote::quote!( Self::#ident => Self::#ident ),
}
});
});
quote::quote!(
Self::#ident ( #( ref #captured, )* ) => Self::#ident ( #( #cloned, )*)
)
},
syn::Fields::Unit => quote::quote!( Self::#ident => Self::#ident ),
}
});
quote::quote!(match self {
#( #variants, )*
@@ -99,5 +104,6 @@ pub fn derive_clone_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
}
}
};
).into()
)
.into()
}
@@ -30,16 +30,16 @@ pub fn expand_outer_dispatch(
let mut query_call_part_macros = Vec::new();
let mut pallet_names = Vec::new();
let pallets_with_call = pallet_decls
.iter()
.filter(|decl| decl.exists_part("Call"));
let pallets_with_call = pallet_decls.iter().filter(|decl| decl.exists_part("Call"));
for pallet_declaration in pallets_with_call {
let name = &pallet_declaration.name;
let path = &pallet_declaration.path;
let index = pallet_declaration.index;
variant_defs.extend(quote!(#[codec(index = #index)] #name( #scrate::dispatch::CallableCallFor<#name, #runtime> ),));
variant_defs.extend(
quote!(#[codec(index = #index)] #name( #scrate::dispatch::CallableCallFor<#name, #runtime> ),),
);
variant_patterns.push(quote!(Call::#name(call)));
pallet_names.push(name);
query_call_part_macros.push(quote! {
@@ -18,7 +18,7 @@
use crate::construct_runtime::Pallet;
use inflector::Inflector;
use proc_macro2::TokenStream;
use quote::{ToTokens, format_ident, quote};
use quote::{format_ident, quote, ToTokens};
use syn::Ident;
pub fn expand_outer_config(
@@ -37,15 +37,18 @@ pub fn expand_outer_config(
let pallet_name = &decl.name;
let path_str = path.into_token_stream().to_string();
let config = format_ident!("{}Config", pallet_name);
let field_name = &Ident::new(
&pallet_name.to_string().to_snake_case(),
decl.name.span(),
);
let field_name =
&Ident::new(&pallet_name.to_string().to_snake_case(), decl.name.span());
let part_is_generic = !pallet_entry.generics.params.is_empty();
types.extend(expand_config_types(runtime, decl, &config, part_is_generic));
fields.extend(quote!(pub #field_name: #config,));
build_storage_calls.extend(expand_config_build_storage_call(scrate, runtime, decl, &field_name));
build_storage_calls.extend(expand_config_build_storage_call(
scrate,
runtime,
decl,
&field_name,
));
query_genesis_config_part_macros.push(quote! {
#path::__substrate_genesis_config_check::is_genesis_config_defined!(#pallet_name);
#[cfg(feature = "std")]
@@ -97,15 +100,15 @@ fn expand_config_types(
let path = &decl.path;
match (decl.instance.as_ref(), part_is_generic) {
(Some(inst), true) => quote!{
(Some(inst), true) => quote! {
#[cfg(any(feature = "std", test))]
pub type #config = #path::GenesisConfig<#runtime, #path::#inst>;
},
(None, true) => quote!{
(None, true) => quote! {
#[cfg(any(feature = "std", test))]
pub type #config = #path::GenesisConfig<#runtime>;
},
(_, false) => quote!{
(_, false) => quote! {
#[cfg(any(feature = "std", test))]
pub type #config = #path::GenesisConfig;
},
@@ -125,7 +128,7 @@ fn expand_config_build_storage_call(
quote!(#path::__InherentHiddenInstance)
};
quote!{
quote! {
#scrate::sp_runtime::BuildModuleGenesisStorage::
<#runtime, #instance>::build_module_genesis_storage(&self.#field_name, storage)?;
}
@@ -43,7 +43,7 @@ pub fn expand_outer_event(
be constructed: pallet `{}` must have generic `Event`",
pallet_name,
);
return Err(syn::Error::new(pallet_name.span(), msg));
return Err(syn::Error::new(pallet_name.span(), msg))
}
let part_is_generic = !generics.params.is_empty();
@@ -54,7 +54,13 @@ pub fn expand_outer_event(
(None, false) => quote!(#path::Event),
};
event_variants.extend(expand_event_variant(runtime, pallet_decl, index, instance, generics));
event_variants.extend(expand_event_variant(
runtime,
pallet_decl,
index,
instance,
generics,
));
event_conversions.extend(expand_event_conversion(scrate, pallet_decl, &pallet_event));
query_event_part_macros.push(quote! {
#path::__substrate_event_check::is_event_part_defined!(#pallet_name);
@@ -94,16 +100,16 @@ fn expand_event_variant(
match instance {
Some(inst) if part_is_generic => {
quote!(#[codec(index = #index)] #variant_name(#path::Event<#runtime, #path::#inst>),)
}
},
Some(inst) => {
quote!(#[codec(index = #index)] #variant_name(#path::Event<#path::#inst>),)
}
},
None if part_is_generic => {
quote!(#[codec(index = #index)] #variant_name(#path::Event<#runtime>),)
}
},
None => {
quote!(#[codec(index = #index)] #variant_name(#path::Event),)
}
},
}
}
@@ -114,7 +120,7 @@ fn expand_event_conversion(
) -> TokenStream {
let variant_name = &pallet.name;
quote!{
quote! {
impl From<#pallet_event> for Event {
fn from(x: #pallet_event) -> Self {
Event::#variant_name(x)
@@ -15,10 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License
use proc_macro2::TokenStream;
use crate::construct_runtime::Pallet;
use syn::{Ident, TypePath};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Ident, TypePath};
pub fn expand_runtime_metadata(
runtime: &Ident,
@@ -48,7 +48,7 @@ pub fn expand_runtime_metadata(
let constants = expand_pallet_metadata_constants(runtime, scrate, decl);
let errors = expand_pallet_metadata_errors(runtime, scrate, decl);
quote!{
quote! {
#scrate::metadata::ModuleMetadata {
name: #scrate::metadata::DecodeDifferent::Encode(stringify!(#name)),
index: #index,
@@ -62,7 +62,7 @@ pub fn expand_runtime_metadata(
})
.collect::<Vec<_>>();
quote!{
quote! {
impl #runtime {
pub fn metadata() -> #scrate::metadata::RuntimeMetadataPrefixed {
#scrate::metadata::RuntimeMetadataLastVersion {
@@ -94,7 +94,7 @@ fn expand_pallet_metadata_storage(
let instance = decl.instance.as_ref().into_iter();
let path = &decl.path;
quote!{
quote! {
Some(#scrate::metadata::DecodeDifferent::Encode(
#scrate::metadata::FnEncode(
#path::Pallet::<#runtime #(, #path::#instance)*>::storage_metadata
@@ -116,7 +116,7 @@ fn expand_pallet_metadata_calls(
let instance = decl.instance.as_ref().into_iter();
let path = &decl.path;
quote!{
quote! {
Some(#scrate::metadata::DecodeDifferent::Encode(
#scrate::metadata::FnEncode(
#path::Pallet::<#runtime #(, #path::#instance)*>::call_functions
@@ -136,8 +136,12 @@ fn expand_pallet_metadata_events(
) -> TokenStream {
if filtered_names.contains(&"Event") {
let path = &decl.path;
let part_is_generic =
!decl.find_part("Event").expect("Event part exists; qed").generics.params.is_empty();
let part_is_generic = !decl
.find_part("Event")
.expect("Event part exists; qed")
.generics
.params
.is_empty();
let pallet_event = match (decl.instance.as_ref(), part_is_generic) {
(Some(inst), true) => quote!(#path::Event::<#runtime, #path::#inst>),
(Some(inst), false) => quote!(#path::Event::<#path::#inst>),
@@ -145,7 +149,7 @@ fn expand_pallet_metadata_events(
(None, false) => quote!(#path::Event),
};
quote!{
quote! {
Some(#scrate::metadata::DecodeDifferent::Encode(
#scrate::metadata::FnEncode(#pallet_event::metadata)
))
@@ -163,7 +167,7 @@ fn expand_pallet_metadata_constants(
let path = &decl.path;
let instance = decl.instance.as_ref().into_iter();
quote!{
quote! {
#scrate::metadata::DecodeDifferent::Encode(
#scrate::metadata::FnEncode(
#path::Pallet::<#runtime #(, #path::#instance)*>::module_constants_metadata
@@ -180,7 +184,7 @@ fn expand_pallet_metadata_errors(
let path = &decl.path;
let instance = decl.instance.as_ref().into_iter();
quote!{
quote! {
#scrate::metadata::DecodeDifferent::Encode(
#scrate::metadata::FnEncode(
<#path::Pallet::<#runtime #(, #path::#instance)*> as #scrate::metadata::ModuleErrorMetadata>::metadata
@@ -18,7 +18,7 @@
use crate::construct_runtime::{Pallet, SYSTEM_PALLET_NAME};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{token, Ident, Generics};
use syn::{token, Generics, Ident};
pub fn expand_outer_origin(
runtime: &Ident,
@@ -26,13 +26,14 @@ pub fn expand_outer_origin(
pallets_token: token::Brace,
scrate: &TokenStream,
) -> syn::Result<TokenStream> {
let system_pallet = pallets.iter()
.find(|decl| decl.name == SYSTEM_PALLET_NAME)
.ok_or_else(|| syn::Error::new(
pallets_token.span,
"`System` pallet declaration is missing. \
let system_pallet =
pallets.iter().find(|decl| decl.name == SYSTEM_PALLET_NAME).ok_or_else(|| {
syn::Error::new(
pallets_token.span,
"`System` pallet declaration is missing. \
Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event<T>},`",
))?;
)
})?;
let mut caller_variants = TokenStream::new();
let mut pallet_conversions = TokenStream::new();
@@ -52,15 +53,23 @@ pub fn expand_outer_origin(
be constructed: pallet `{}` must have generic `Origin`",
name
);
return Err(syn::Error::new(name.span(), msg));
return Err(syn::Error::new(name.span(), msg))
}
caller_variants.extend(
expand_origin_caller_variant(runtime, pallet_decl, index, instance, generics),
);
pallet_conversions.extend(
expand_origin_pallet_conversions(scrate, runtime, pallet_decl, instance, generics),
);
caller_variants.extend(expand_origin_caller_variant(
runtime,
pallet_decl,
index,
instance,
generics,
));
pallet_conversions.extend(expand_origin_pallet_conversions(
scrate,
runtime,
pallet_decl,
instance,
generics,
));
query_origin_part_macros.push(quote! {
#path::__substrate_origin_check::is_origin_part_defined!(#name);
});
@@ -270,16 +279,16 @@ fn expand_origin_caller_variant(
match instance {
Some(inst) if part_is_generic => {
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#runtime, #path::#inst>),)
}
},
Some(inst) => {
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#path::#inst>),)
}
},
None if part_is_generic => {
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#runtime>),)
}
},
None => {
quote!(#[codec(index = #index)] #variant_name(#path::Origin),)
}
},
}
}
@@ -301,7 +310,7 @@ fn expand_origin_pallet_conversions(
None => quote!(#path::Origin),
};
quote!{
quote! {
impl From<#pallet_origin> for OriginCaller {
fn from(x: #pallet_origin) -> Self {
OriginCaller::#variant_name(x)
@@ -18,14 +18,15 @@
mod expand;
mod parse;
use frame_support_procedural_tools::syn_ext as ext;
use frame_support_procedural_tools::{generate_crate_access, generate_hidden_includes};
use frame_support_procedural_tools::{
generate_crate_access, generate_hidden_includes, syn_ext as ext,
};
use parse::{PalletDeclaration, PalletPart, PalletPath, RuntimeDefinition, WhereSection};
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{Ident, Result};
use std::collections::HashMap;
use syn::{Ident, Result};
/// The fixed name of the system pallet.
const SYSTEM_PALLET_NAME: &str = "System";
@@ -65,48 +66,44 @@ fn complete_pallets(decl: impl Iterator<Item = PalletDeclaration>) -> syn::Resul
let mut last_index: Option<u8> = None;
let mut names = HashMap::new();
decl
.map(|pallet| {
let final_index = match pallet.index {
Some(i) => i,
None => last_index.map_or(Some(0), |i| i.checked_add(1))
.ok_or_else(|| {
let msg = "Pallet index doesn't fit into u8, index is 256";
syn::Error::new(pallet.name.span(), msg)
})?,
};
decl.map(|pallet| {
let final_index = match pallet.index {
Some(i) => i,
None => last_index.map_or(Some(0), |i| i.checked_add(1)).ok_or_else(|| {
let msg = "Pallet index doesn't fit into u8, index is 256";
syn::Error::new(pallet.name.span(), msg)
})?,
};
last_index = Some(final_index);
last_index = Some(final_index);
if let Some(used_pallet) = indices.insert(final_index, pallet.name.clone()) {
let msg = format!(
"Pallet indices are conflicting: Both pallets {} and {} are at index {}",
used_pallet,
pallet.name,
final_index,
);
let mut err = syn::Error::new(used_pallet.span(), &msg);
err.combine(syn::Error::new(pallet.name.span(), msg));
return Err(err);
}
if let Some(used_pallet) = indices.insert(final_index, pallet.name.clone()) {
let msg = format!(
"Pallet indices are conflicting: Both pallets {} and {} are at index {}",
used_pallet, pallet.name, final_index,
);
let mut err = syn::Error::new(used_pallet.span(), &msg);
err.combine(syn::Error::new(pallet.name.span(), msg));
return Err(err)
}
if let Some(used_pallet) = names.insert(pallet.name.clone(), pallet.name.span()) {
let msg = "Two pallets with the same name!";
if let Some(used_pallet) = names.insert(pallet.name.clone(), pallet.name.span()) {
let msg = "Two pallets with the same name!";
let mut err = syn::Error::new(used_pallet, &msg);
err.combine(syn::Error::new(pallet.name.span(), &msg));
return Err(err);
}
let mut err = syn::Error::new(used_pallet, &msg);
err.combine(syn::Error::new(pallet.name.span(), &msg));
return Err(err)
}
Ok(Pallet {
name: pallet.name,
index: final_index,
path: pallet.path,
instance: pallet.instance,
pallet_parts: pallet.pallet_parts,
})
Ok(Pallet {
name: pallet.name,
index: final_index,
path: pallet.path,
instance: pallet.instance,
pallet_parts: pallet.pallet_parts,
})
.collect()
})
.collect()
}
pub fn construct_runtime(input: TokenStream) -> TokenStream {
@@ -119,17 +116,9 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {
fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream2> {
let RuntimeDefinition {
name,
where_section: WhereSection {
block,
node_block,
unchecked_extrinsic,
..
},
where_section: WhereSection { block, node_block, unchecked_extrinsic, .. },
pallets:
ext::Braces {
content: ext::Punctuated { inner: pallets, .. },
token: pallets_token,
},
ext::Braces { content: ext::Punctuated { inner: pallets, .. }, token: pallets_token },
..
} = definition;
@@ -148,13 +137,8 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
let dispatch = expand::expand_outer_dispatch(&name, &pallets, &scrate);
let metadata = expand::expand_runtime_metadata(&name, &pallets, &scrate, &unchecked_extrinsic);
let outer_config = expand::expand_outer_config(&name, &pallets, &scrate);
let inherent = expand::expand_outer_inherent(
&name,
&block,
&unchecked_extrinsic,
&pallets,
&scrate,
);
let inherent =
expand::expand_outer_inherent(&name, &block, &unchecked_extrinsic, &pallets, &scrate);
let validate_unsigned = expand::expand_outer_validate_unsigned(&name, &pallets, &scrate);
let integrity_test = decl_integrity_test(&scrate);
@@ -210,12 +194,7 @@ fn decl_all_pallets<'a>(
let type_name = &pallet_declaration.name;
let pallet = &pallet_declaration.path;
let mut generics = vec![quote!(#runtime)];
generics.extend(
pallet_declaration
.instance
.iter()
.map(|name| quote!(#pallet::#name)),
);
generics.extend(pallet_declaration.instance.iter().map(|name| quote!(#pallet::#name)));
let type_decl = quote!(
pub type #type_name = #pallet::Pallet <#(#generics),*>;
);
@@ -224,11 +203,13 @@ fn decl_all_pallets<'a>(
}
// Make nested tuple structure like (((Babe, Consensus), Grandpa), ...)
// But ignore the system pallet.
let all_pallets = names.iter()
let all_pallets = names
.iter()
.filter(|n| **n != SYSTEM_PALLET_NAME)
.fold(TokenStream2::default(), |combined, name| quote!((#name, #combined)));
let all_pallets_with_system = names.iter()
let all_pallets_with_system = names
.iter()
.fold(TokenStream2::default(), |combined, name| quote!((#name, #combined)));
quote!(
@@ -258,8 +239,7 @@ fn decl_pallet_runtime_setup(
let names = pallet_declarations.iter().map(|d| &d.name);
let names2 = pallet_declarations.iter().map(|d| &d.name);
let name_strings = pallet_declarations.iter().map(|d| d.name.to_string());
let indices = pallet_declarations.iter()
.map(|pallet| pallet.index as usize);
let indices = pallet_declarations.iter().map(|pallet| pallet.index as usize);
quote!(
/// Provides an implementation of `PalletInfo` to provide information
@@ -77,9 +77,9 @@ impl Parse for WhereSection {
definitions.push(definition);
if !input.peek(Token![,]) {
if !input.peek(token::Brace) {
return Err(input.error("Expected `,` or `{`"));
return Err(input.error("Expected `,` or `{`"))
}
break;
break
}
input.parse::<Token![,]>()?;
}
@@ -87,23 +87,14 @@ impl Parse for WhereSection {
let node_block = remove_kind(input, WhereKind::NodeBlock, &mut definitions)?.value;
let unchecked_extrinsic =
remove_kind(input, WhereKind::UncheckedExtrinsic, &mut definitions)?.value;
if let Some(WhereDefinition {
ref kind_span,
ref kind,
..
}) = definitions.first()
{
if let Some(WhereDefinition { ref kind_span, ref kind, .. }) = definitions.first() {
let msg = format!(
"`{:?}` was declared above. Please use exactly one declaration for `{:?}`.",
kind, kind
);
return Err(Error::new(*kind_span, msg));
return Err(Error::new(*kind_span, msg))
}
Ok(Self {
block,
node_block,
unchecked_extrinsic,
})
Ok(Self { block, node_block, unchecked_extrinsic })
}
}
@@ -127,17 +118,11 @@ impl Parse for WhereDefinition {
let (kind_span, kind) = if lookahead.peek(keyword::Block) {
(input.parse::<keyword::Block>()?.span(), WhereKind::Block)
} else if lookahead.peek(keyword::NodeBlock) {
(
input.parse::<keyword::NodeBlock>()?.span(),
WhereKind::NodeBlock,
)
(input.parse::<keyword::NodeBlock>()?.span(), WhereKind::NodeBlock)
} else if lookahead.peek(keyword::UncheckedExtrinsic) {
(
input.parse::<keyword::UncheckedExtrinsic>()?.span(),
WhereKind::UncheckedExtrinsic,
)
(input.parse::<keyword::UncheckedExtrinsic>()?.span(), WhereKind::UncheckedExtrinsic)
} else {
return Err(lookahead.error());
return Err(lookahead.error())
};
Ok(Self {
@@ -187,13 +172,7 @@ impl Parse for PalletDeclaration {
None
};
let parsed = Self {
name,
path,
instance,
pallet_parts,
index,
};
let parsed = Self { name, path, instance, pallet_parts, index };
Ok(parsed)
}
@@ -214,17 +193,17 @@ impl Parse for PalletPath {
let mut lookahead = input.lookahead1();
let mut segments = Punctuated::new();
if lookahead.peek(Token![crate])
|| lookahead.peek(Token![self])
|| lookahead.peek(Token![super])
|| lookahead.peek(Ident)
if lookahead.peek(Token![crate]) ||
lookahead.peek(Token![self]) ||
lookahead.peek(Token![super]) ||
lookahead.peek(Ident)
{
let ident = input.call(Ident::parse_any)?;
segments.push(PathSegment { ident, arguments: PathArguments::None });
let _: Token![::] = input.parse()?;
lookahead = input.lookahead1();
} else {
return Err(lookahead.error());
return Err(lookahead.error())
}
while lookahead.peek(Ident) {
@@ -235,15 +214,10 @@ impl Parse for PalletPath {
}
if !lookahead.peek(token::Brace) && !lookahead.peek(Token![<]) {
return Err(lookahead.error());
return Err(lookahead.error())
}
Ok(Self {
inner: Path {
leading_colon: None,
segments,
}
})
Ok(Self { inner: Path { leading_colon: None, segments } })
}
}
@@ -257,7 +231,7 @@ impl quote::ToTokens for PalletPath {
///
/// `{ Call, Event }`
fn parse_pallet_parts(input: ParseStream) -> Result<Vec<PalletPart>> {
let pallet_parts :ext::Braces<ext::Punctuated<PalletPart, Token![,]>> = input.parse()?;
let pallet_parts: ext::Braces<ext::Punctuated<PalletPart, Token![,]>> = input.parse()?;
let mut resolved = HashSet::new();
for part in pallet_parts.content.inner.iter() {
@@ -266,7 +240,7 @@ fn parse_pallet_parts(input: ParseStream) -> Result<Vec<PalletPart>> {
"`{}` was already declared before. Please remove the duplicate declaration",
part.name(),
);
return Err(Error::new(part.keyword.span(), msg));
return Err(Error::new(part.keyword.span(), msg))
}
}
@@ -371,13 +345,10 @@ impl Parse for PalletPart {
keyword.name(),
valid_generics,
);
return Err(syn::Error::new(keyword.span(), msg));
return Err(syn::Error::new(keyword.span(), msg))
}
Ok(Self {
keyword,
generics,
})
Ok(Self { keyword, generics })
}
}
@@ -30,9 +30,10 @@ pub fn derive_debug_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
let impl_ = match input.data {
syn::Data::Struct(struct_) => match struct_.fields {
syn::Fields::Named(named) => {
let fields = named.named.iter()
.map(|i| &i.ident)
.map(|i| quote::quote_spanned!(i.span() => .field(stringify!(#i), &self.#i) ));
let fields =
named.named.iter().map(|i| &i.ident).map(
|i| quote::quote_spanned!(i.span() => .field(stringify!(#i), &self.#i) ),
);
quote::quote!(
fmt.debug_struct(stringify!(#input_ident))
@@ -41,7 +42,10 @@ pub fn derive_debug_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
)
},
syn::Fields::Unnamed(unnamed) => {
let fields = unnamed.unnamed.iter().enumerate()
let fields = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, _)| syn::Index::from(i))
.map(|i| quote::quote_spanned!(i.span() => .field(&self.#i) ));
@@ -51,46 +55,50 @@ pub fn derive_debug_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
.finish()
)
},
syn::Fields::Unit => quote::quote!( fmt.write_str(stringify!(#input_ident)) ),
syn::Fields::Unit => quote::quote!(fmt.write_str(stringify!(#input_ident))),
},
syn::Data::Enum(enum_) => {
let variants = enum_.variants.iter()
.map(|variant| {
let ident = &variant.ident;
let full_variant_str = format!("{}::{}", input_ident, ident);
match &variant.fields {
syn::Fields::Named(named) => {
let captured = named.named.iter().map(|i| &i.ident);
let debugged = captured.clone()
.map(|i| quote::quote_spanned!(i.span() =>
.field(stringify!(#i), &#i)
));
quote::quote!(
Self::#ident { #( ref #captured, )* } => {
fmt.debug_struct(#full_variant_str)
#( #debugged )*
.finish()
}
let variants = enum_.variants.iter().map(|variant| {
let ident = &variant.ident;
let full_variant_str = format!("{}::{}", input_ident, ident);
match &variant.fields {
syn::Fields::Named(named) => {
let captured = named.named.iter().map(|i| &i.ident);
let debugged = captured.clone().map(|i| {
quote::quote_spanned!(i.span() =>
.field(stringify!(#i), &#i)
)
},
syn::Fields::Unnamed(unnamed) => {
let captured = unnamed.unnamed.iter().enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}", i), f.span()));
let debugged = captured.clone()
.map(|i| quote::quote_spanned!(i.span() => .field(&#i)));
quote::quote!(
Self::#ident ( #( ref #captured, )* ) => {
fmt.debug_tuple(#full_variant_str)
#( #debugged )*
.finish()
}
)
},
syn::Fields::Unit => quote::quote!(
Self::#ident => fmt.write_str(#full_variant_str)
),
}
});
});
quote::quote!(
Self::#ident { #( ref #captured, )* } => {
fmt.debug_struct(#full_variant_str)
#( #debugged )*
.finish()
}
)
},
syn::Fields::Unnamed(unnamed) => {
let captured = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}", i), f.span()));
let debugged = captured
.clone()
.map(|i| quote::quote_spanned!(i.span() => .field(&#i)));
quote::quote!(
Self::#ident ( #( ref #captured, )* ) => {
fmt.debug_tuple(#full_variant_str)
#( #debugged )*
.finish()
}
)
},
syn::Fields::Unit => quote::quote!(
Self::#ident => fmt.write_str(#full_variant_str)
),
}
});
quote::quote!(match *self {
#( #variants, )*
@@ -110,5 +118,6 @@ pub fn derive_debug_no_bound(input: proc_macro::TokenStream) -> proc_macro::Toke
}
}
};
).into()
)
.into()
}
@@ -30,56 +30,60 @@ pub fn derive_default_no_bound(input: proc_macro::TokenStream) -> proc_macro::To
let impl_ = match input.data {
syn::Data::Struct(struct_) => match struct_.fields {
syn::Fields::Named(named) => {
let fields = named.named.iter()
.map(|i| &i.ident)
.map(|i| quote::quote_spanned!(i.span() =>
let fields = named.named.iter().map(|i| &i.ident).map(|i| {
quote::quote_spanned!(i.span() =>
#i: core::default::Default::default()
));
)
});
quote::quote!( Self { #( #fields, )* } )
},
syn::Fields::Unnamed(unnamed) => {
let fields = unnamed.unnamed.iter().enumerate()
.map(|(i, _)| syn::Index::from(i))
.map(|i| quote::quote_spanned!(i.span() =>
core::default::Default::default()
));
let fields =
unnamed.unnamed.iter().enumerate().map(|(i, _)| syn::Index::from(i)).map(|i| {
quote::quote_spanned!(i.span() =>
core::default::Default::default()
)
});
quote::quote!( Self ( #( #fields, )* ) )
},
syn::Fields::Unit => {
quote::quote!( Self )
}
quote::quote!(Self)
},
},
syn::Data::Enum(enum_) => {
syn::Data::Enum(enum_) =>
if let Some(first_variant) = enum_.variants.first() {
let variant_ident = &first_variant.ident;
match &first_variant.fields {
syn::Fields::Named(named) => {
let fields = named.named.iter()
.map(|i| &i.ident)
.map(|i| quote::quote_spanned!(i.span() =>
let fields = named.named.iter().map(|i| &i.ident).map(|i| {
quote::quote_spanned!(i.span() =>
#i: core::default::Default::default()
));
)
});
quote::quote!( #name :: #ty_generics :: #variant_ident { #( #fields, )* } )
},
syn::Fields::Unnamed(unnamed) => {
let fields = unnamed.unnamed.iter().enumerate()
let fields = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, _)| syn::Index::from(i))
.map(|i| quote::quote_spanned!(i.span() =>
core::default::Default::default()
));
.map(|i| {
quote::quote_spanned!(i.span() =>
core::default::Default::default()
)
});
quote::quote!( #name :: #ty_generics :: #variant_ident ( #( #fields, )* ) )
},
syn::Fields::Unit => quote::quote!( #name :: #ty_generics :: #variant_ident ),
}
} else {
quote::quote!( Self )
}
},
quote::quote!(Self)
},
syn::Data::Union(_) => {
let msg = "Union type not supported by `derive(CloneNoBound)`";
return syn::Error::new(input.span(), msg).to_compile_error().into()
@@ -94,5 +98,6 @@ pub fn derive_default_no_bound(input: proc_macro::TokenStream) -> proc_macro::To
}
}
};
).into()
)
.into()
}
@@ -1,18 +1,17 @@
use proc_macro::TokenStream;
use crate::COUNTER;
use proc_macro::TokenStream;
pub fn generate_dummy_part_checker(input: TokenStream) -> TokenStream {
if !input.is_empty() {
return syn::Error::new(proc_macro2::Span::call_site(), "No arguments expected")
.to_compile_error().into()
.to_compile_error()
.into()
}
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
let no_op_macro_ident = syn::Ident::new(
&format!("__dummy_part_checker_{}", count),
proc_macro2::Span::call_site(),
);
let no_op_macro_ident =
syn::Ident::new(&format!("__dummy_part_checker_{}", count), proc_macro2::Span::call_site());
quote::quote!(
#[macro_export]
@@ -58,5 +57,6 @@ pub fn generate_dummy_part_checker(input: TokenStream) -> TokenStream {
#[doc(hidden)]
pub use #no_op_macro_ident as is_origin_part_defined;
}
).into()
)
.into()
}
@@ -16,14 +16,14 @@
// limitations under the License.
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, format_ident, quote};
use quote::{format_ident, quote, ToTokens};
use syn::{Ident, Result};
const MAX_IDENTS: usize = 18;
pub fn impl_key_prefix_for_tuples(input: proc_macro::TokenStream) -> Result<TokenStream> {
if !input.is_empty() {
return Err(syn::Error::new(Span::call_site(), "No arguments expected"));
return Err(syn::Error::new(Span::call_site(), "No arguments expected"))
}
let mut all_trait_impls = TokenStream::new();
@@ -36,13 +36,17 @@ pub fn impl_key_prefix_for_tuples(input: proc_macro::TokenStream) -> Result<Toke
for prefix_count in 1..i {
let (prefixes, suffixes) = current_tuple.split_at(prefix_count);
let hashers = current_tuple.iter().map(|ident| format_ident!("Hasher{}", ident)).collect::<Vec<_>>();
let kargs = prefixes.iter().map(|ident| format_ident!("KArg{}", ident)).collect::<Vec<_>>();
let hashers = current_tuple
.iter()
.map(|ident| format_ident!("Hasher{}", ident))
.collect::<Vec<_>>();
let kargs =
prefixes.iter().map(|ident| format_ident!("KArg{}", ident)).collect::<Vec<_>>();
let partial_keygen = generate_keygen(prefixes);
let suffix_keygen = generate_keygen(suffixes);
let suffix_tuple = generate_tuple(suffixes);
let trait_impls = quote!{
let trait_impls = quote! {
impl<
#(#current_tuple: FullCodec,)*
#(#hashers: StorageHasher,)*
+29 -22
View File
@@ -19,21 +19,21 @@
#![recursion_limit = "512"]
mod storage;
mod clone_no_bound;
mod construct_runtime;
mod debug_no_bound;
mod default_no_bound;
mod dummy_part_checker;
mod key_prefix;
mod pallet;
mod pallet_version;
mod transactional;
mod debug_no_bound;
mod clone_no_bound;
mod partial_eq_no_bound;
mod default_no_bound;
mod key_prefix;
mod dummy_part_checker;
mod storage;
mod transactional;
pub(crate) use storage::INHERENT_INSTANCE_NAME;
use proc_macro::TokenStream;
use std::cell::RefCell;
pub(crate) use storage::INHERENT_INSTANCE_NAME;
thread_local! {
/// A global counter, can be used to generate a relatively unique identifier.
@@ -200,14 +200,14 @@ impl Counter {
///
/// // Your storage items
/// }
/// add_extra_genesis {
/// config(genesis_field): GenesisFieldType;
/// config(genesis_field2): GenesisFieldType;
/// ...
/// build(|_: &Self| {
/// // Modification of storage
/// })
/// }
/// add_extra_genesis {
/// config(genesis_field): GenesisFieldType;
/// config(genesis_field2): GenesisFieldType;
/// ...
/// build(|_: &Self| {
/// // Modification of storage
/// })
/// }
/// }
/// ```
///
@@ -219,7 +219,7 @@ impl Counter {
/// ...,
/// Example: example::{Pallet, Storage, ..., Config<T>},
/// ...,
/// }
/// }
/// );
/// ```
///
@@ -413,7 +413,8 @@ pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream {
}
}
};
).into()
)
.into()
}
#[cfg(feature = "std")]
@@ -444,7 +445,8 @@ pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream {
const _: () = {
impl #impl_generics core::cmp::Eq for #name #ty_generics #where_clause {}
};
).into()
)
.into()
}
/// derive `Default` but do no bound any generic. Docs are at `frame_support::DefaultNoBound`.
@@ -455,12 +457,15 @@ pub fn derive_default_no_bound(input: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
transactional::require_transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into())
transactional::require_transactional(attr, input)
.unwrap_or_else(|e| e.to_compile_error().into())
}
#[proc_macro]
pub fn crate_to_pallet_version(input: TokenStream) -> TokenStream {
pallet_version::crate_to_pallet_version(input).unwrap_or_else(|e| e.to_compile_error()).into()
pallet_version::crate_to_pallet_version(input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
/// The number of module instances supported by the runtime, starting at index 1,
@@ -471,7 +476,9 @@ pub(crate) const NUMBER_OF_INSTANCE: u8 = 16;
/// It implements the trait `HasKeyPrefix` and `HasReversibleKeyPrefix` for tuple of `Key`.
#[proc_macro]
pub fn impl_key_prefix_for_tuples(input: TokenStream) -> TokenStream {
key_prefix::impl_key_prefix_for_tuples(input).unwrap_or_else(syn::Error::into_compile_error).into()
key_prefix::impl_key_prefix_for_tuples(input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
/// Internal macro use by frame_support to generate dummy part checker for old pallet declaration
@@ -15,9 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::Def;
use crate::{pallet::Def, COUNTER};
use frame_support_procedural_tools::clean_type_string;
use crate::COUNTER;
use syn::spanned::Spanned;
/// * Generate enum call and implement various trait on it.
@@ -31,7 +30,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
let docs = call.docs.clone();
(span, where_clause, methods, docs)
}
},
None => (def.item.span(), None, Vec::new(), Vec::new()),
};
let frame_support = &def.frame_support;
@@ -48,16 +47,20 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
let fn_doc = methods.iter().map(|method| &method.docs).collect::<Vec<_>>();
let args_name = methods.iter()
let args_name = methods
.iter()
.map(|method| method.args.iter().map(|(_, name, _)| name.clone()).collect::<Vec<_>>())
.collect::<Vec<_>>();
let args_type = methods.iter()
let args_type = methods
.iter()
.map(|method| method.args.iter().map(|(_, _, type_)| type_.clone()).collect::<Vec<_>>())
.collect::<Vec<_>>();
let args_compact_attr = methods.iter().map(|method| {
method.args.iter()
method
.args
.iter()
.map(|(is_compact, _, type_)| {
if *is_compact {
quote::quote_spanned!(type_.span() => #[codec(compact)] )
@@ -69,7 +72,9 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
});
let args_metadata_type = methods.iter().map(|method| {
method.args.iter()
method
.args
.iter()
.map(|(is_compact, _, type_)| {
let final_type = if *is_compact {
quote::quote_spanned!(type_.span() => Compact<#type_>)
@@ -84,14 +89,10 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
let default_docs = [syn::parse_quote!(
r"Contains one variant per dispatchable that can be called by an extrinsic."
)];
let docs = if docs.is_empty() {
&default_docs[..]
} else {
&docs[..]
};
let docs = if docs.is_empty() { &default_docs[..] } else { &docs[..] };
let maybe_compile_error = if def.call.is_none() {
quote::quote!{
quote::quote! {
compile_error!(concat!(
"`",
stringify!($pallet_name),
@@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, parse::helper::get_doc_literals};
use crate::pallet::{parse::helper::get_doc_literals, Def};
/// * Generate default rust doc
pub fn expand_config(def: &mut Def) -> proc_macro2::TokenStream {
@@ -71,58 +71,55 @@ pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream {
}
});
let consts = config_consts.chain(extra_consts)
.map(|const_| {
let const_type = &const_.type_;
let const_type_str = clean_type_string(&const_type.to_token_stream().to_string());
let ident = &const_.ident;
let ident_str = format!("{}", ident);
let doc = const_.doc.clone().into_iter();
let default_byte_impl = &const_.default_byte_impl;
let default_byte_getter = syn::Ident::new(
&format!("{}DefaultByteGetter", ident),
ident.span()
let consts = config_consts.chain(extra_consts).map(|const_| {
let const_type = &const_.type_;
let const_type_str = clean_type_string(&const_type.to_token_stream().to_string());
let ident = &const_.ident;
let ident_str = format!("{}", ident);
let doc = const_.doc.clone().into_iter();
let default_byte_impl = &const_.default_byte_impl;
let default_byte_getter =
syn::Ident::new(&format!("{}DefaultByteGetter", ident), ident.span());
quote::quote!({
#[allow(non_upper_case_types)]
#[allow(non_camel_case_types)]
struct #default_byte_getter<#type_decl_gen>(
#frame_support::sp_std::marker::PhantomData<(#type_use_gen)>
);
quote::quote!({
#[allow(non_upper_case_types)]
#[allow(non_camel_case_types)]
struct #default_byte_getter<#type_decl_gen>(
#frame_support::sp_std::marker::PhantomData<(#type_use_gen)>
);
impl<#type_impl_gen> #frame_support::dispatch::DefaultByte for
#default_byte_getter<#type_use_gen>
#completed_where_clause
{
fn default_byte(&self) -> #frame_support::sp_std::vec::Vec<u8> {
#default_byte_impl
}
impl<#type_impl_gen> #frame_support::dispatch::DefaultByte for
#default_byte_getter<#type_use_gen>
#completed_where_clause
{
fn default_byte(&self) -> #frame_support::sp_std::vec::Vec<u8> {
#default_byte_impl
}
}
unsafe impl<#type_impl_gen> Send for #default_byte_getter<#type_use_gen>
#completed_where_clause
{}
unsafe impl<#type_impl_gen> Sync for #default_byte_getter<#type_use_gen>
#completed_where_clause
{}
unsafe impl<#type_impl_gen> Send for #default_byte_getter<#type_use_gen>
#completed_where_clause
{}
unsafe impl<#type_impl_gen> Sync for #default_byte_getter<#type_use_gen>
#completed_where_clause
{}
#frame_support::dispatch::ModuleConstantMetadata {
name: #frame_support::dispatch::DecodeDifferent::Encode(#ident_str),
ty: #frame_support::dispatch::DecodeDifferent::Encode(#const_type_str),
value: #frame_support::dispatch::DecodeDifferent::Encode(
#frame_support::dispatch::DefaultByteGetter(
&#default_byte_getter::<#type_use_gen>(
#frame_support::sp_std::marker::PhantomData
)
#frame_support::dispatch::ModuleConstantMetadata {
name: #frame_support::dispatch::DecodeDifferent::Encode(#ident_str),
ty: #frame_support::dispatch::DecodeDifferent::Encode(#const_type_str),
value: #frame_support::dispatch::DecodeDifferent::Encode(
#frame_support::dispatch::DefaultByteGetter(
&#default_byte_getter::<#type_use_gen>(
#frame_support::sp_std::marker::PhantomData
)
),
documentation: #frame_support::dispatch::DecodeDifferent::Encode(
&[ #( #doc ),* ]
),
}
})
});
)
),
documentation: #frame_support::dispatch::DecodeDifferent::Encode(
&[ #( #doc ),* ]
),
}
})
});
quote::quote!(
impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause{
@@ -15,16 +15,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, parse::helper::get_doc_literals};
use crate::pallet::{parse::helper::get_doc_literals, Def};
/// * impl various trait on Error
/// * impl ModuleErrorMetadata for Error
pub fn expand_error(def: &mut Def) -> proc_macro2::TokenStream {
let error = if let Some(error) = &def.error {
error
} else {
return Default::default()
};
let error = if let Some(error) = &def.error { error } else { return Default::default() };
let error_ident = &error.error;
let frame_support = &def.frame_support;
@@ -41,27 +37,24 @@ pub fn expand_error(def: &mut Def) -> proc_macro2::TokenStream {
)
);
let as_u8_matches = error.variants.iter().enumerate()
.map(|(i, (variant, _))| {
quote::quote_spanned!(error.attr_span => Self::#variant => #i as u8,)
});
let as_u8_matches = error.variants.iter().enumerate().map(
|(i, (variant, _))| quote::quote_spanned!(error.attr_span => Self::#variant => #i as u8,),
);
let as_str_matches = error.variants.iter()
.map(|(variant, _)| {
let variant_str = format!("{}", variant);
quote::quote_spanned!(error.attr_span => Self::#variant => #variant_str,)
});
let as_str_matches = error.variants.iter().map(|(variant, _)| {
let variant_str = format!("{}", variant);
quote::quote_spanned!(error.attr_span => Self::#variant => #variant_str,)
});
let metadata = error.variants.iter()
.map(|(variant, doc)| {
let variant_str = format!("{}", variant);
quote::quote_spanned!(error.attr_span =>
#frame_support::error::ErrorMetadata {
name: #frame_support::error::DecodeDifferent::Encode(#variant_str),
documentation: #frame_support::error::DecodeDifferent::Encode(&[ #( #doc, )* ]),
},
)
});
let metadata = error.variants.iter().map(|(variant, doc)| {
let variant_str = format!("{}", variant);
quote::quote_spanned!(error.attr_span =>
#frame_support::error::ErrorMetadata {
name: #frame_support::error::DecodeDifferent::Encode(#variant_str),
documentation: #frame_support::error::DecodeDifferent::Encode(&[ #( #doc, )* ]),
},
)
});
let error_item = {
let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[error.index];
@@ -15,8 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, parse::helper::get_doc_literals};
use crate::COUNTER;
use crate::{
pallet::{parse::helper::get_doc_literals, Def},
COUNTER,
};
use syn::{spanned::Spanned, Ident};
/// * Add __Ignore variant on Event
@@ -29,10 +31,8 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream {
let ident = Ident::new(&format!("__is_event_part_defined_{}", count), event.attr_span);
(event, ident)
} else {
let macro_ident = Ident::new(
&format!("__is_event_part_defined_{}", count),
def.item.span(),
);
let macro_ident =
Ident::new(&format!("__is_event_part_defined_{}", count), def.item.span());
return quote::quote! {
#[doc(hidden)]
@@ -49,42 +49,39 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream {
));
}
}
#[doc(hidden)]
pub use #macro_ident as is_event_part_defined;
}
};
}
};
let event_where_clause = &event.where_clause;
// NOTE: actually event where clause must be a subset of config where clause because of
// `type Event: From<Event<Self>>`. But we merge either way for potential better error message
let completed_where_clause = super::merge_where_clauses(&[
&event.where_clause,
&def.config.where_clause,
]);
let completed_where_clause =
super::merge_where_clauses(&[&event.where_clause, &def.config.where_clause]);
let event_ident = &event.event;
let frame_system = &def.frame_system;
let frame_support = &def.frame_support;
let event_use_gen = &event.gen_kind.type_use_gen(event.attr_span);
let event_impl_gen= &event.gen_kind.type_impl_gen(event.attr_span);
let metadata = event.metadata.iter()
.map(|(ident, args, docs)| {
let name = format!("{}", ident);
quote::quote_spanned!(event.attr_span =>
#frame_support::event::EventMetadata {
name: #frame_support::event::DecodeDifferent::Encode(#name),
arguments: #frame_support::event::DecodeDifferent::Encode(&[
#( #args, )*
]),
documentation: #frame_support::event::DecodeDifferent::Encode(&[
#( #docs, )*
]),
},
)
});
let event_impl_gen = &event.gen_kind.type_impl_gen(event.attr_span);
let metadata = event.metadata.iter().map(|(ident, args, docs)| {
let name = format!("{}", ident);
quote::quote_spanned!(event.attr_span =>
#frame_support::event::EventMetadata {
name: #frame_support::event::DecodeDifferent::Encode(#name),
arguments: #frame_support::event::DecodeDifferent::Encode(&[
#( #args, )*
]),
documentation: #frame_support::event::DecodeDifferent::Encode(&[
#( #docs, )*
]),
},
)
});
let event_item = {
let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[event.index];
@@ -166,7 +163,7 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream {
macro_rules! #macro_ident {
($pallet_name:ident) => {};
}
#[doc(hidden)]
pub use #macro_ident as is_event_part_defined;
}
@@ -40,8 +40,8 @@ pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream {
let gen_cfg_use_gen = genesis_config.gen_kind.type_use_gen(genesis_build.attr_span);
let genesis_build_item = &mut def.item.content.as_mut()
.expect("Checked by def parser").1[genesis_build.index];
let genesis_build_item =
&mut def.item.content.as_mut().expect("Checked by def parser").1[genesis_build.index];
let genesis_build_item_impl = if let syn::Item::Impl(impl_) = genesis_build_item {
impl_
@@ -15,9 +15,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, parse::helper::get_doc_literals};
use crate::COUNTER;
use syn::{Ident, spanned::Spanned};
use crate::{
pallet::{parse::helper::get_doc_literals, Def},
COUNTER,
};
use syn::{spanned::Spanned, Ident};
/// * add various derive trait on GenesisConfig struct.
pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
@@ -37,15 +39,11 @@ pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
(genesis_config, def_macro_ident, std_macro_ident)
} else {
let def_macro_ident = Ident::new(
&format!("__is_genesis_config_defined_{}", count),
def.item.span(),
);
let def_macro_ident =
Ident::new(&format!("__is_genesis_config_defined_{}", count), def.item.span());
let std_macro_ident = Ident::new(
&format!("__is_std_enabled_for_genesis_{}", count),
def.item.span(),
);
let std_macro_ident =
Ident::new(&format!("__is_std_enabled_for_genesis_{}", count), def.item.span());
return quote::quote! {
#[doc(hidden)]
@@ -74,18 +72,18 @@ pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
#[doc(hidden)]
pub use #std_macro_ident as is_std_enabled_for_genesis;
}
};
}
};
let frame_support = &def.frame_support;
let genesis_config_item = &mut def.item.content.as_mut()
.expect("Checked by def parser").1[genesis_config.index];
let genesis_config_item =
&mut def.item.content.as_mut().expect("Checked by def parser").1[genesis_config.index];
let serde_crate = format!("{}::serde", frame_support);
match genesis_config_item {
syn::Item::Enum(syn::ItemEnum { attrs, ..}) |
syn::Item::Enum(syn::ItemEnum { attrs, .. }) |
syn::Item::Struct(syn::ItemStruct { attrs, .. }) |
syn::Item::Type(syn::ItemType { attrs, .. }) => {
if get_doc_literals(&attrs).is_empty() {
@@ -59,7 +59,7 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream {
let hooks_impl = if def.hooks.is_none() {
let frame_system = &def.frame_system;
quote::quote!{
quote::quote! {
impl<#type_impl_gen>
#frame_support::traits::Hooks<<T as #frame_system::Config>::BlockNumber>
for Pallet<#type_use_gen> {}
@@ -15,11 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::Def;
use crate::{pallet::Def, COUNTER};
use proc_macro2::TokenStream;
use quote::quote;
use crate::COUNTER;
use syn::{Ident, spanned::Spanned};
use syn::{spanned::Spanned, Ident};
pub fn expand_inherents(def: &mut Def) -> TokenStream {
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
@@ -48,7 +47,7 @@ pub fn expand_inherents(def: &mut Def) -> TokenStream {
#maybe_compile_error
}
}
#[doc(hidden)]
pub use #macro_ident as is_inherent_part_defined;
}
@@ -15,9 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{pallet::Def, NUMBER_OF_INSTANCE};
use proc_macro2::Span;
use crate::pallet::Def;
use crate::NUMBER_OF_INSTANCE;
/// * Provide inherent instance to be used by construct_runtime
/// * Provide Instance1 ..= Instance16 for instantiable pallet
@@ -25,7 +24,9 @@ pub fn expand_instances(def: &mut Def) -> proc_macro2::TokenStream {
let frame_support = &def.frame_support;
let inherent_ident = syn::Ident::new(crate::INHERENT_INSTANCE_NAME, Span::call_site());
let instances = if def.config.has_instance {
(1..=NUMBER_OF_INSTANCE).map(|i| syn::Ident::new(&format!("Instance{}", i), Span::call_site())).collect()
(1..=NUMBER_OF_INSTANCE)
.map(|i| syn::Ident::new(&format!("Instance{}", i), Span::call_site()))
.collect()
} else {
vec![]
};
@@ -15,24 +15,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
mod constants;
mod pallet_struct;
mod call;
mod config;
mod constants;
mod error;
mod event;
mod storage;
mod hooks;
mod store_trait;
mod inherent;
mod instances;
mod genesis_build;
mod genesis_config;
mod type_value;
mod hooks;
mod inherent;
mod instances;
mod origin;
mod pallet_struct;
mod storage;
mod store_trait;
mod type_value;
mod validate_unsigned;
use crate::pallet::{Def, parse::helper::get_doc_literals};
use crate::pallet::{parse::helper::get_doc_literals, Def};
use quote::ToTokens;
/// Merge where clause together, `where` token span is taken from the first not none one.
@@ -97,7 +97,11 @@ pub fn expand(mut def: Def) -> proc_macro2::TokenStream {
#validate_unsigned
);
def.item.content.as_mut().expect("This is checked by parsing").1
def.item
.content
.as_mut()
.expect("This is checked by parsing")
.1
.push(syn::Item::Verbatim(new_items));
def.item.into_token_stream()
@@ -18,7 +18,7 @@
use crate::{pallet::Def, COUNTER};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Ident, spanned::Spanned};
use syn::{spanned::Spanned, Ident};
pub fn expand_origins(def: &mut Def) -> TokenStream {
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
@@ -47,7 +47,7 @@ pub fn expand_origins(def: &mut Def) -> TokenStream {
#maybe_compile_error
}
}
#[doc(hidden)]
pub use #macro_ident as is_origin_part_defined;
}
@@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, expand::merge_where_clauses, parse::helper::get_doc_literals};
use crate::pallet::{expand::merge_where_clauses, parse::helper::get_doc_literals, Def};
/// * Add derive trait on Pallet
/// * Implement GetPalletVersion on Pallet
@@ -104,29 +104,25 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream {
// Depending on the flag `generate_storage_info` we use partial or full storage info from
// storage.
let (
storage_info_span,
storage_info_trait,
storage_info_method,
) = if let Some(span) = def.pallet_struct.generate_storage_info {
(
span,
quote::quote_spanned!(span => StorageInfoTrait),
quote::quote_spanned!(span => storage_info),
)
} else {
let span = def.pallet_struct.attr_span;
(
span,
quote::quote_spanned!(span => PartialStorageInfoTrait),
quote::quote_spanned!(span => partial_storage_info),
)
};
let (storage_info_span, storage_info_trait, storage_info_method) =
if let Some(span) = def.pallet_struct.generate_storage_info {
(
span,
quote::quote_spanned!(span => StorageInfoTrait),
quote::quote_spanned!(span => storage_info),
)
} else {
let span = def.pallet_struct.attr_span;
(
span,
quote::quote_spanned!(span => PartialStorageInfoTrait),
quote::quote_spanned!(span => partial_storage_info),
)
};
let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::<Vec<_>>();
let storage_cfg_attrs = &def.storages.iter()
.map(|storage| &storage.cfg_attrs)
.collect::<Vec<_>>();
let storage_cfg_attrs =
&def.storages.iter().map(|storage| &storage.cfg_attrs).collect::<Vec<_>>();
let storage_info = quote::quote_spanned!(storage_info_span =>
impl<#type_impl_gen> #frame_support::traits::StorageInfoTrait
@@ -15,8 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::{Def, parse::storage::StorageDef};
use crate::pallet::parse::storage::{Metadata, QueryKind, StorageGenerics};
use crate::pallet::{
parse::storage::{Metadata, QueryKind, StorageDef, StorageGenerics},
Def,
};
use frame_support_procedural_tools::clean_type_string;
use std::collections::HashSet;
@@ -30,10 +32,7 @@ fn prefix_ident(storage: &StorageDef) -> syn::Ident {
/// Check for duplicated storage prefixes. This step is necessary since users can specify an
/// alternative storage prefix using the #[pallet::storage_prefix] syntax, and we need to ensure
/// that the prefix specified by the user is not a duplicate of an existing one.
fn check_prefix_duplicates(
storage_def: &StorageDef,
set: &mut HashSet<String>,
) -> syn::Result<()> {
fn check_prefix_duplicates(storage_def: &StorageDef, set: &mut HashSet<String>) -> syn::Result<()> {
let prefix = storage_def.prefix();
if !set.insert(prefix.clone()) {
@@ -41,7 +40,7 @@ fn check_prefix_duplicates(
storage_def.prefix_span(),
format!("Duplicate storage prefixes found for `{}`", prefix),
);
return Err(err);
return Err(err)
}
Ok(())
@@ -85,10 +84,8 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
let default_query_kind: syn::Type =
syn::parse_quote!(#frame_support::storage::types::OptionQuery);
let default_on_empty: syn::Type =
syn::parse_quote!(#frame_support::traits::GetDefault);
let default_max_values: syn::Type =
syn::parse_quote!(#frame_support::traits::GetDefault);
let default_on_empty: syn::Type = syn::parse_quote!(#frame_support::traits::GetDefault);
let default_max_values: syn::Type = syn::parse_quote!(#frame_support::traits::GetDefault);
if let Some(named_generics) = storage_def.named_generics.clone() {
args.args.clear();
@@ -100,7 +97,7 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
args.args.push(syn::GenericArgument::Type(query_kind));
let on_empty = on_empty.unwrap_or_else(|| default_on_empty.clone());
args.args.push(syn::GenericArgument::Type(on_empty));
}
},
StorageGenerics::Map { hasher, key, value, query_kind, on_empty, max_values } => {
args.args.push(syn::GenericArgument::Type(hasher));
args.args.push(syn::GenericArgument::Type(key));
@@ -111,9 +108,16 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
args.args.push(syn::GenericArgument::Type(on_empty));
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
args.args.push(syn::GenericArgument::Type(max_values));
}
},
StorageGenerics::DoubleMap {
hasher1, key1, hasher2, key2, value, query_kind, on_empty, max_values,
hasher1,
key1,
hasher2,
key2,
value,
query_kind,
on_empty,
max_values,
} => {
args.args.push(syn::GenericArgument::Type(hasher1));
args.args.push(syn::GenericArgument::Type(key1));
@@ -126,8 +130,8 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
args.args.push(syn::GenericArgument::Type(on_empty));
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
args.args.push(syn::GenericArgument::Type(max_values));
}
StorageGenerics::NMap { keygen, value, query_kind, on_empty, max_values, } => {
},
StorageGenerics::NMap { keygen, value, query_kind, on_empty, max_values } => {
args.args.push(syn::GenericArgument::Type(keygen));
args.args.push(syn::GenericArgument::Type(value));
let query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
@@ -136,7 +140,7 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
args.args.push(syn::GenericArgument::Type(on_empty));
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
args.args.push(syn::GenericArgument::Type(max_values));
}
},
}
} else {
args.args[0] = syn::parse_quote!( #prefix_ident<#type_use_gen> );
@@ -154,118 +158,116 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
/// * generate metadatas
pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
if let Err(e) = process_generics(def) {
return e.into_compile_error().into();
return e.into_compile_error().into()
}
let frame_support = &def.frame_support;
let frame_system = &def.frame_system;
let pallet_ident = &def.pallet_struct.pallet;
let entries = def.storages.iter().map(|storage| {
let docs = &storage.docs;
let entries = def.storages.iter()
.map(|storage| {
let docs = &storage.docs;
let ident = &storage.ident;
let gen = &def.type_use_generics(storage.attr_span);
let full_ident = quote::quote_spanned!(storage.attr_span => #ident<#gen> );
let ident = &storage.ident;
let gen = &def.type_use_generics(storage.attr_span);
let full_ident = quote::quote_spanned!(storage.attr_span => #ident<#gen> );
let cfg_attrs = &storage.cfg_attrs;
let cfg_attrs = &storage.cfg_attrs;
let metadata_trait = match &storage.metadata {
Metadata::Value { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageValueMetadata
),
Metadata::Map { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageMapMetadata
),
Metadata::DoubleMap { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageDoubleMapMetadata
),
Metadata::NMap { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageNMapMetadata
),
};
let metadata_trait = match &storage.metadata {
Metadata::Value { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageValueMetadata
),
Metadata::Map { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageMapMetadata
),
Metadata::DoubleMap { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageDoubleMapMetadata
),
Metadata::NMap { .. } => quote::quote_spanned!(storage.attr_span =>
#frame_support::storage::types::StorageNMapMetadata
),
};
let ty = match &storage.metadata {
Metadata::Value { value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::Plain(
#frame_support::metadata::DecodeDifferent::Encode(#value)
)
let ty = match &storage.metadata {
Metadata::Value { value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::Plain(
#frame_support::metadata::DecodeDifferent::Encode(#value)
)
},
Metadata::Map { key, value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
let key = clean_type_string(&quote::quote!(#key).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::Map {
hasher: <#full_ident as #metadata_trait>::HASHER,
key: #frame_support::metadata::DecodeDifferent::Encode(#key),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
unused: false,
}
)
},
Metadata::DoubleMap { key1, key2, value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
let key1 = clean_type_string(&quote::quote!(#key1).to_string());
let key2 = clean_type_string(&quote::quote!(#key2).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::DoubleMap {
hasher: <#full_ident as #metadata_trait>::HASHER1,
key2_hasher: <#full_ident as #metadata_trait>::HASHER2,
key1: #frame_support::metadata::DecodeDifferent::Encode(#key1),
key2: #frame_support::metadata::DecodeDifferent::Encode(#key2),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
}
)
},
Metadata::NMap { keys, value, .. } => {
let keys = keys
.iter()
.map(|key| clean_type_string(&quote::quote!(#key).to_string()))
.collect::<Vec<_>>();
let value = clean_type_string(&quote::quote!(#value).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::NMap {
keys: #frame_support::metadata::DecodeDifferent::Encode(&[
#( #keys, )*
]),
hashers: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::HASHERS,
),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
}
)
}
};
)
},
Metadata::Map { key, value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
let key = clean_type_string(&quote::quote!(#key).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::Map {
hasher: <#full_ident as #metadata_trait>::HASHER,
key: #frame_support::metadata::DecodeDifferent::Encode(#key),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
unused: false,
}
)
},
Metadata::DoubleMap { key1, key2, value } => {
let value = clean_type_string(&quote::quote!(#value).to_string());
let key1 = clean_type_string(&quote::quote!(#key1).to_string());
let key2 = clean_type_string(&quote::quote!(#key2).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::DoubleMap {
hasher: <#full_ident as #metadata_trait>::HASHER1,
key2_hasher: <#full_ident as #metadata_trait>::HASHER2,
key1: #frame_support::metadata::DecodeDifferent::Encode(#key1),
key2: #frame_support::metadata::DecodeDifferent::Encode(#key2),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
}
)
},
Metadata::NMap { keys, value, .. } => {
let keys = keys
.iter()
.map(|key| clean_type_string(&quote::quote!(#key).to_string()))
.collect::<Vec<_>>();
let value = clean_type_string(&quote::quote!(#value).to_string());
quote::quote_spanned!(storage.attr_span =>
#frame_support::metadata::StorageEntryType::NMap {
keys: #frame_support::metadata::DecodeDifferent::Encode(&[
#( #keys, )*
]),
hashers: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::HASHERS,
),
value: #frame_support::metadata::DecodeDifferent::Encode(#value),
}
)
},
};
quote::quote_spanned!(storage.attr_span =>
#(#cfg_attrs)* #frame_support::metadata::StorageEntryMetadata {
name: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::NAME
),
modifier: <#full_ident as #metadata_trait>::MODIFIER,
ty: #ty,
default: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::DEFAULT
),
documentation: #frame_support::metadata::DecodeDifferent::Encode(&[
#( #docs, )*
]),
}
)
});
quote::quote_spanned!(storage.attr_span =>
#(#cfg_attrs)* #frame_support::metadata::StorageEntryMetadata {
name: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::NAME
),
modifier: <#full_ident as #metadata_trait>::MODIFIER,
ty: #ty,
default: #frame_support::metadata::DecodeDifferent::Encode(
<#full_ident as #metadata_trait>::DEFAULT
),
documentation: #frame_support::metadata::DecodeDifferent::Encode(&[
#( #docs, )*
]),
}
)
});
let getters = def.storages.iter()
.map(|storage| if let Some(getter) = &storage.getter {
let completed_where_clause = super::merge_where_clauses(&[
&storage.where_clause,
&def.config.where_clause,
]);
let docs = storage.docs.iter()
let getters = def.storages.iter().map(|storage| {
if let Some(getter) = &storage.getter {
let completed_where_clause =
super::merge_where_clauses(&[&storage.where_clause, &def.config.where_clause]);
let docs = storage
.docs
.iter()
.map(|d| quote::quote_spanned!(storage.attr_span => #[doc = #d]));
let ident = &storage.ident;
@@ -365,11 +367,12 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
}
}
)
}
},
}
} else {
Default::default()
});
}
});
let prefix_structs = def.storages.iter().map(|storage_def| {
let type_impl_gen = &def.type_impl_generics(storage_def.attr_span);
@@ -22,11 +22,8 @@ use syn::spanned::Spanned;
/// * generate Store trait with all storages,
/// * implement Store trait for Pallet.
pub fn expand_store_trait(def: &mut Def) -> proc_macro2::TokenStream {
let (trait_vis, trait_store) = if let Some(store) = &def.pallet_struct.store {
store
} else {
return Default::default()
};
let (trait_vis, trait_store) =
if let Some(store) = &def.pallet_struct.store { store } else { return Default::default() };
let type_impl_gen = &def.type_impl_generics(trait_store.span());
let type_use_gen = &def.type_use_generics(trait_store.span());
@@ -37,7 +34,8 @@ pub fn expand_store_trait(def: &mut Def) -> proc_macro2::TokenStream {
let completed_where_clause = super::merge_where_clauses(&where_clauses);
let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::<Vec<_>>();
let storage_cfg_attrs = &def.storages.iter().map(|storage| &storage.cfg_attrs).collect::<Vec<_>>();
let storage_cfg_attrs =
&def.storages.iter().map(|storage| &storage.cfg_attrs).collect::<Vec<_>>();
quote::quote_spanned!(trait_store.span() =>
#trait_vis trait #trait_store {
@@ -15,15 +15,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::pallet::Def;
use crate::{pallet::Def, COUNTER};
use proc_macro2::TokenStream;
use quote::quote;
use crate::COUNTER;
use syn::{Ident, spanned::Spanned};
use syn::{spanned::Spanned, Ident};
pub fn expand_validate_unsigned(def: &mut Def) -> TokenStream {
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
let macro_ident = Ident::new(&format!("__is_validate_unsigned_part_defined_{}", count), def.item.span());
let macro_ident =
Ident::new(&format!("__is_validate_unsigned_part_defined_{}", count), def.item.span());
let maybe_compile_error = if def.validate_unsigned.is_none() {
quote! {
@@ -48,7 +48,7 @@ pub fn expand_validate_unsigned(def: &mut Def) -> TokenStream {
#maybe_compile_error
}
}
#[doc(hidden)]
pub use #macro_ident as is_validate_unsigned_part_defined;
}
@@ -25,21 +25,22 @@
//! This step will modify the ItemMod by adding some derive attributes or phantom data variants
//! to user defined types. And also crate new types and implement block.
mod parse;
mod expand;
mod parse;
pub use parse::Def;
use syn::spanned::Spanned;
pub fn pallet(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
if !attr.is_empty() {
let msg = "Invalid pallet macro call: expected no attributes, e.g. macro call must be just \
let msg =
"Invalid pallet macro call: expected no attributes, e.g. macro call must be just \
`#[frame_support::pallet]` or `#[pallet]`";
let span = proc_macro2::TokenStream::from(attr).span();
return syn::Error::new(span, msg).to_compile_error().into();
return syn::Error::new(span, msg).to_compile_error().into()
}
let item = syn::parse_macro_input!(item as syn::ItemMod);
@@ -75,9 +75,7 @@ impl syn::parse::Parse for FunctionAttr {
let weight_content;
syn::parenthesized!(weight_content in content);
Ok(FunctionAttr {
weight: weight_content.parse::<syn::Expr>()?,
})
Ok(FunctionAttr { weight: weight_content.parse::<syn::Expr>()? })
}
}
@@ -100,7 +98,6 @@ impl syn::parse::Parse for ArgAttrIsCompact {
/// Check the syntax is `OriginFor<T>`
pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> {
pub struct CheckDispatchableFirstArg;
impl syn::parse::Parse for CheckDispatchableFirstArg {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
@@ -113,13 +110,12 @@ pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> {
}
}
syn::parse2::<CheckDispatchableFirstArg>(ty.to_token_stream())
.map_err(|e| {
let msg = "Invalid type: expected `OriginFor<T>`";
let mut err = syn::Error::new(ty.span(), msg);
err.combine(e);
err
})?;
syn::parse2::<CheckDispatchableFirstArg>(ty.to_token_stream()).map_err(|e| {
let msg = "Invalid type: expected `OriginFor<T>`";
let mut err = syn::Error::new(ty.span(), msg);
err.combine(e);
err
})?;
Ok(())
}
@@ -128,12 +124,12 @@ impl CallDef {
pub fn try_from(
attr_span: proc_macro2::Span,
index: usize,
item: &mut syn::Item
item: &mut syn::Item,
) -> syn::Result<Self> {
let item = if let syn::Item::Impl(item) = item {
item
} else {
return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl"));
return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl"))
};
let mut instances = vec![];
@@ -158,18 +154,18 @@ impl CallDef {
_ => method.vis.span(),
};
return Err(syn::Error::new(span, msg));
return Err(syn::Error::new(span, msg))
}
match method.sig.inputs.first() {
None => {
let msg = "Invalid pallet::call, must have at least origin arg";
return Err(syn::Error::new(method.sig.span(), msg));
return Err(syn::Error::new(method.sig.span(), msg))
},
Some(syn::FnArg::Receiver(_)) => {
let msg = "Invalid pallet::call, first argument must be a typed argument, \
e.g. `origin: OriginFor<T>`";
return Err(syn::Error::new(method.sig.span(), msg));
return Err(syn::Error::new(method.sig.span(), msg))
},
Some(syn::FnArg::Typed(arg)) => {
check_dispatchable_first_arg_type(&*arg.ty)?;
@@ -181,7 +177,7 @@ impl CallDef {
} else {
let msg = "Invalid pallet::call, require return type \
DispatchResultWithPostInfo";
return Err(syn::Error::new(method.sig.span(), msg));
return Err(syn::Error::new(method.sig.span(), msg))
}
let mut call_var_attrs: Vec<FunctionAttr> =
@@ -193,7 +189,7 @@ impl CallDef {
} else {
"Invalid pallet::call, too many weight attributes given"
};
return Err(syn::Error::new(method.sig.span(), msg));
return Err(syn::Error::new(method.sig.span(), msg))
}
let weight = call_var_attrs.pop().unwrap().weight;
@@ -210,14 +206,14 @@ impl CallDef {
if arg_attrs.len() > 1 {
let msg = "Invalid pallet::call, argument has too many attributes";
return Err(syn::Error::new(arg.span(), msg));
return Err(syn::Error::new(arg.span(), msg))
}
let arg_ident = if let syn::Pat::Ident(pat) = &*arg.pat {
pat.ident.clone()
} else {
let msg = "Invalid pallet::call, argument must be ident";
return Err(syn::Error::new(arg.pat.span(), msg));
return Err(syn::Error::new(arg.pat.span(), msg))
};
args.push((!arg_attrs.is_empty(), arg_ident, arg.ty.clone()));
@@ -225,15 +221,10 @@ impl CallDef {
let docs = helper::get_doc_literals(&method.attrs);
methods.push(CallVariantDef {
name: method.sig.ident.clone(),
weight,
args,
docs,
});
methods.push(CallVariantDef { name: method.sig.ident.clone(), weight, args, docs });
} else {
let msg = "Invalid pallet::call, only method accepted";
return Err(syn::Error::new(impl_item.span(), msg));
return Err(syn::Error::new(impl_item.span(), msg))
}
}
@@ -17,8 +17,8 @@
use super::helper;
use core::convert::TryFrom;
use syn::spanned::Spanned;
use quote::ToTokens;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -66,23 +66,26 @@ impl TryFrom<&syn::TraitItemType> for ConstMetadataDef {
type Error = syn::Error;
fn try_from(trait_ty: &syn::TraitItemType) -> Result<Self, Self::Error> {
let err = |span, msg|
syn::Error::new(span, format!("Invalid usage of `#[pallet::constant]`: {}", msg));
let err = |span, msg| {
syn::Error::new(span, format!("Invalid usage of `#[pallet::constant]`: {}", msg))
};
let doc = helper::get_doc_literals(&trait_ty.attrs);
let ident = trait_ty.ident.clone();
let bound = trait_ty.bounds
let bound = trait_ty
.bounds
.iter()
.find_map(|b|
.find_map(|b| {
if let syn::TypeParamBound::Trait(tb) = b {
tb.path.segments
tb.path
.segments
.last()
.and_then(|s| if s.ident == "Get" { Some(s) } else { None } )
.and_then(|s| if s.ident == "Get" { Some(s) } else { None })
} else {
None
}
)
})
.ok_or_else(|| err(trait_ty.span(), "`Get<T>` trait bound not found"))?;
let type_arg = if let syn::PathArguments::AngleBracketed (ref ab) = bound.arguments {
let type_arg = if let syn::PathArguments::AngleBracketed(ref ab) = bound.arguments {
if ab.args.len() == 1 {
if let syn::GenericArgument::Type(ref ty) = ab.args[0] {
Ok(ty)
@@ -214,15 +217,15 @@ impl syn::parse::Parse for FromEventParse {
fn check_event_type(
frame_system: &syn::Ident,
trait_item: &syn::TraitItem,
trait_has_instance: bool
) -> syn::Result<bool> {
trait_has_instance: bool,
) -> syn::Result<bool> {
if let syn::TraitItem::Type(type_) = trait_item {
if type_.ident == "Event" {
// Check event has no generics
if !type_.generics.params.is_empty() || type_.generics.where_clause.is_some() {
let msg = "Invalid `type Event`, associated type `Event` is reserved and must have\
no generics nor where_clause";
return Err(syn::Error::new(trait_item.span(), msg));
return Err(syn::Error::new(trait_item.span(), msg))
}
// Check bound contains IsType and From
@@ -237,28 +240,28 @@ fn check_event_type(
bound: `IsType<<Self as {}::Config>::Event>`",
frame_system,
);
return Err(syn::Error::new(type_.span(), msg));
return Err(syn::Error::new(type_.span(), msg))
}
let from_event_bound = type_.bounds.iter().find_map(|s| {
syn::parse2::<FromEventParse>(s.to_token_stream()).ok()
});
let from_event_bound = type_
.bounds
.iter()
.find_map(|s| syn::parse2::<FromEventParse>(s.to_token_stream()).ok());
let from_event_bound = if let Some(b) = from_event_bound {
b
} else {
let msg = "Invalid `type Event`, associated type `Event` is reserved and must \
bound: `From<Event>` or `From<Event<Self>>` or `From<Event<Self, I>>`";
return Err(syn::Error::new(type_.span(), msg));
return Err(syn::Error::new(type_.span(), msg))
};
if from_event_bound.is_generic
&& (from_event_bound.has_instance != trait_has_instance)
if from_event_bound.is_generic && (from_event_bound.has_instance != trait_has_instance)
{
let msg = "Invalid `type Event`, associated type `Event` bounds inconsistent \
`From<Event..>`. Config and generic Event must be both with instance or \
without instance";
return Err(syn::Error::new(type_.span(), msg));
return Err(syn::Error::new(type_.span(), msg))
}
Ok(true)
@@ -272,16 +275,14 @@ fn check_event_type(
/// Replace ident `Self` by `T`
pub fn replace_self_by_t(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
input.into_iter()
input
.into_iter()
.map(|token_tree| match token_tree {
proc_macro2::TokenTree::Group(group) =>
proc_macro2::Group::new(
group.delimiter(),
replace_self_by_t(group.stream())
).into(),
proc_macro2::Group::new(group.delimiter(), replace_self_by_t(group.stream())).into(),
proc_macro2::TokenTree::Ident(ident) if ident == "Self" =>
proc_macro2::Ident::new("T", ident.span()).into(),
other => other
other => other,
})
.collect()
}
@@ -297,27 +298,27 @@ impl ConfigDef {
item
} else {
let msg = "Invalid pallet::config, expected trait definition";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
if !matches!(item.vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::config, trait must be public";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
syn::parse2::<keyword::Config>(item.ident.to_token_stream())?;
let where_clause = {
let stream = replace_self_by_t(item.generics.where_clause.to_token_stream());
syn::parse2::<Option<syn::WhereClause>>(stream)
.expect("Internal error: replacing `Self` by `T` should result in valid where
clause")
syn::parse2::<Option<syn::WhereClause>>(stream).expect(
"Internal error: replacing `Self` by `T` should result in valid where
clause",
)
};
if item.generics.params.len() > 1 {
let msg = "Invalid pallet::config, expected no more than one generic";
return Err(syn::Error::new(item.generics.params[2].span(), msg));
return Err(syn::Error::new(item.generics.params[2].span(), msg))
}
let has_instance = if item.generics.params.first().is_some() {
@@ -331,15 +332,15 @@ impl ConfigDef {
let mut consts_metadata = vec![];
for trait_item in &mut item.items {
// Parse for event
has_event_type = has_event_type
|| check_event_type(frame_system, trait_item, has_instance)?;
has_event_type =
has_event_type || check_event_type(frame_system, trait_item, has_instance)?;
// Parse for constant
let type_attrs_const: Vec<TypeAttrConst> = helper::take_item_pallet_attrs(trait_item)?;
if type_attrs_const.len() > 1 {
let msg = "Invalid attribute in pallet::config, only one attribute is expected";
return Err(syn::Error::new(type_attrs_const[1].span(), msg));
return Err(syn::Error::new(type_attrs_const[1].span(), msg))
}
if type_attrs_const.len() == 1 {
@@ -349,17 +350,17 @@ impl ConfigDef {
consts_metadata.push(constant);
},
_ => {
let msg = "Invalid pallet::constant in pallet::config, expected type trait \
let msg =
"Invalid pallet::constant in pallet::config, expected type trait \
item";
return Err(syn::Error::new(trait_item.span(), msg));
return Err(syn::Error::new(trait_item.span(), msg))
},
}
}
}
let attr: Option<DisableFrameSystemSupertraitCheck> = helper::take_first_item_pallet_attr(
&mut item.attrs
)?;
let attr: Option<DisableFrameSystemSupertraitCheck> =
helper::take_first_item_pallet_attr(&mut item.attrs)?;
let disable_system_supertrait_check = attr.is_some();
@@ -372,10 +373,9 @@ impl ConfigDef {
let found = if item.supertraits.is_empty() {
"none".to_string()
} else {
let mut found = item.supertraits.iter()
.fold(String::new(), |acc, s| {
format!("{}`{}`, ", acc, quote::quote!(#s).to_string())
});
let mut found = item.supertraits.iter().fold(String::new(), |acc, s| {
format!("{}`{}`, ", acc, quote::quote!(#s).to_string())
});
found.pop();
found.pop();
found
@@ -387,19 +387,11 @@ impl ConfigDef {
(try `pub trait Config: frame_system::Config {{ ...` or \
`pub trait Config<I: 'static>: frame_system::Config {{ ...`). \
To disable this check, use `#[pallet::disable_frame_system_supertrait_check]`",
frame_system,
found,
frame_system, found,
);
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
Ok(Self {
index,
has_instance,
consts_metadata,
has_event_type,
where_clause,
attr_span,
})
Ok(Self { index, has_instance, consts_metadata, has_event_type, where_clause, attr_span })
}
}
@@ -16,8 +16,8 @@
// limitations under the License.
use super::helper;
use syn::spanned::Spanned;
use quote::ToTokens;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -48,11 +48,11 @@ impl ErrorDef {
let item = if let syn::Item::Enum(item) = item {
item
} else {
return Err(syn::Error::new(item.span(), "Invalid pallet::error, expected item enum"));
return Err(syn::Error::new(item.span(), "Invalid pallet::error, expected item enum"))
};
if !matches!(item.vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::error, `Error` must be public";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
let mut instances = vec![];
@@ -60,34 +60,30 @@ impl ErrorDef {
if item.generics.where_clause.is_some() {
let msg = "Invalid pallet::error, where clause is not allowed on pallet error item";
return Err(syn::Error::new(item.generics.where_clause.as_ref().unwrap().span(), msg));
return Err(syn::Error::new(item.generics.where_clause.as_ref().unwrap().span(), msg))
}
let error = syn::parse2::<keyword::Error>(item.ident.to_token_stream())?;
let variants = item.variants.iter()
let variants = item
.variants
.iter()
.map(|variant| {
if !matches!(variant.fields, syn::Fields::Unit) {
let msg = "Invalid pallet::error, unexpected fields, must be `Unit`";
return Err(syn::Error::new(variant.fields.span(), msg));
return Err(syn::Error::new(variant.fields.span(), msg))
}
if variant.discriminant.is_some() {
let msg = "Invalid pallet::error, unexpected discriminant, discriminant \
are not supported";
let span = variant.discriminant.as_ref().unwrap().0.span();
return Err(syn::Error::new(span, msg));
return Err(syn::Error::new(span, msg))
}
Ok((variant.ident.clone(), helper::get_doc_literals(&variant.attrs)))
})
.collect::<Result<_, _>>()?;
Ok(ErrorDef {
attr_span,
index,
variants,
instances,
error,
})
Ok(ErrorDef { attr_span, index, variants, instances, error })
}
}
@@ -16,9 +16,9 @@
// limitations under the License.
use super::helper;
use syn::spanned::Spanned;
use quote::ToTokens;
use frame_support_procedural_tools::clean_type_string;
use quote::ToTokens;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -80,7 +80,7 @@ impl PalletEventAttr {
/// Parse for syntax `$Type = "$SomeString"`.
fn parse_event_metadata_element(
input: syn::parse::ParseStream
input: syn::parse::ParseStream,
) -> syn::Result<(syn::Type, String)> {
let typ = input.parse::<syn::Type>()?;
input.parse::<syn::Token![=]>()?;
@@ -118,7 +118,6 @@ impl syn::parse::Parse for PalletEventAttr {
generate_content.parse::<syn::Token![fn]>()?;
let fn_span = generate_content.parse::<keyword::deposit_event>()?.span();
Ok(PalletEventAttr::DepositEvent { fn_vis, span, fn_span })
} else {
Err(lookahead.error())
@@ -139,11 +138,10 @@ impl PalletEventAttrInfo {
match attr {
PalletEventAttr::Metadata { metadata: m, .. } if metadata.is_none() =>
metadata = Some(m),
PalletEventAttr::DepositEvent { fn_vis, fn_span, .. } if deposit_event.is_none() =>
PalletEventAttr::DepositEvent { fn_vis, fn_span, .. }
if deposit_event.is_none() =>
deposit_event = Some((fn_vis, fn_span)),
attr => {
return Err(syn::Error::new(attr.span(), "Duplicate attribute"));
}
attr => return Err(syn::Error::new(attr.span(), "Duplicate attribute")),
}
}
@@ -170,7 +168,7 @@ impl EventDef {
if !matches!(item.vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::event, `Error` must be public";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
let where_clause = item.generics.where_clause.clone();
@@ -182,10 +180,7 @@ impl EventDef {
instances.push(u);
} else {
// construct_runtime only allow non generic event for non instantiable pallet.
instances.push(helper::InstanceUsage {
has_instance: false,
span: item.ident.span(),
})
instances.push(helper::InstanceUsage { has_instance: false, span: item.ident.span() })
}
let has_instance = item.generics.type_params().any(|t| t.ident == "I");
@@ -195,13 +190,19 @@ impl EventDef {
let event = syn::parse2::<keyword::Event>(item.ident.to_token_stream())?;
let metadata = item.variants.iter()
let metadata = item
.variants
.iter()
.map(|variant| {
let name = variant.ident.clone();
let docs = helper::get_doc_literals(&variant.attrs);
let args = variant.fields.iter()
let args = variant
.fields
.iter()
.map(|field| {
metadata.iter().find(|m| m.0 == field.ty)
metadata
.iter()
.find(|m| m.0 == field.ty)
.map(|m| m.1.clone())
.unwrap_or_else(|| {
clean_type_string(&field.ty.to_token_stream().to_string())
@@ -52,14 +52,11 @@ pub struct ExtraConstantDef {
}
impl ExtraConstantsDef {
pub fn try_from(
index: usize,
item: &mut syn::Item
) -> syn::Result<Self> {
pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result<Self> {
let item = if let syn::Item::Impl(item) = item {
item
} else {
return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl"));
return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl"))
};
let mut instances = vec![];
@@ -78,28 +75,28 @@ impl ExtraConstantsDef {
method
} else {
let msg = "Invalid pallet::call, only method accepted";
return Err(syn::Error::new(impl_item.span(), msg));
return Err(syn::Error::new(impl_item.span(), msg))
};
if !method.sig.inputs.is_empty() {
let msg = "Invalid pallet::extra_constants, method must have 0 args";
return Err(syn::Error::new(method.sig.span(), msg));
return Err(syn::Error::new(method.sig.span(), msg))
}
if !method.sig.generics.params.is_empty() {
let msg = "Invalid pallet::extra_constants, method must have 0 generics";
return Err(syn::Error::new(method.sig.generics.params[0].span(), msg));
return Err(syn::Error::new(method.sig.generics.params[0].span(), msg))
}
if method.sig.generics.where_clause.is_some() {
let msg = "Invalid pallet::extra_constants, method must have no where clause";
return Err(syn::Error::new(method.sig.generics.where_clause.span(), msg));
return Err(syn::Error::new(method.sig.generics.where_clause.span(), msg))
}
let type_ = match &method.sig.output {
syn::ReturnType::Default => {
let msg = "Invalid pallet::extra_constants, method must have a return type";
return Err(syn::Error::new(method.span(), msg));
return Err(syn::Error::new(method.span(), msg))
},
syn::ReturnType::Type(_, type_) => *type_.clone(),
};
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// Definition for pallet genesis build implementation.
pub struct GenesisBuildDef {
@@ -40,24 +40,22 @@ impl GenesisBuildDef {
item
} else {
let msg = "Invalid pallet::genesis_build, expected item impl";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
let item_trait = &item.trait_.as_ref()
let item_trait = &item
.trait_
.as_ref()
.ok_or_else(|| {
let msg = "Invalid pallet::genesis_build, expected impl<..> GenesisBuild<..> \
for GenesisConfig<..>";
syn::Error::new(item.span(), msg)
})?.1;
})?
.1;
let mut instances = vec![];
instances.push(helper::check_genesis_builder_usage(&item_trait)?);
Ok(Self {
attr_span,
index,
instances,
where_clause: item.generics.where_clause.clone(),
})
Ok(Self { attr_span, index, instances, where_clause: item.generics.where_clause.clone() })
}
}
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// Definition for pallet genesis config type.
///
@@ -42,7 +42,7 @@ impl GenesisConfigDef {
syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics),
_ => {
let msg = "Invalid pallet::genesis_config, expected enum or struct";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
},
};
@@ -60,19 +60,14 @@ impl GenesisConfigDef {
if !matches!(vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::genesis_config, GenesisConfig must be public";
return Err(syn::Error::new(item_span, msg));
return Err(syn::Error::new(item_span, msg))
}
if ident != "GenesisConfig" {
let msg = "Invalid pallet::genesis_config, ident must `GenesisConfig`";
return Err(syn::Error::new(ident.span(), msg));
return Err(syn::Error::new(ident.span(), msg))
}
Ok(GenesisConfigDef {
index,
genesis_config: ident.clone(),
instances,
gen_kind,
})
Ok(GenesisConfigDef { index, genesis_config: ident.clone(), instances, gen_kind })
}
}
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use quote::ToTokens;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -47,20 +47,15 @@ pub trait MutItemAttrs {
}
/// Take the first pallet attribute (e.g. attribute like `#[pallet..]`) and decode it to `Attr`
pub fn take_first_item_pallet_attr<Attr>(item: &mut impl MutItemAttrs) -> syn::Result<Option<Attr>> where
pub fn take_first_item_pallet_attr<Attr>(item: &mut impl MutItemAttrs) -> syn::Result<Option<Attr>>
where
Attr: syn::parse::Parse,
{
let attrs = if let Some(attrs) = item.mut_item_attrs() {
attrs
} else {
return Ok(None)
};
let attrs = if let Some(attrs) = item.mut_item_attrs() { attrs } else { return Ok(None) };
if let Some(index) = attrs.iter()
.position(|attr|
attr.path.segments.first().map_or(false, |segment| segment.ident == "pallet")
)
{
if let Some(index) = attrs.iter().position(|attr| {
attr.path.segments.first().map_or(false, |segment| segment.ident == "pallet")
}) {
let pallet_attr = attrs.remove(index);
Ok(Some(syn::parse2(pallet_attr.into_token_stream())?))
} else {
@@ -69,7 +64,8 @@ pub fn take_first_item_pallet_attr<Attr>(item: &mut impl MutItemAttrs) -> syn::R
}
/// Take all the pallet attributes (e.g. attribute like `#[pallet..]`) and decode them to `Attr`
pub fn take_item_pallet_attrs<Attr>(item: &mut impl MutItemAttrs) -> syn::Result<Vec<Attr>> where
pub fn take_item_pallet_attrs<Attr>(item: &mut impl MutItemAttrs) -> syn::Result<Vec<Attr>>
where
Attr: syn::parse::Parse,
{
let mut pallet_attrs = Vec::new();
@@ -83,13 +79,16 @@ pub fn take_item_pallet_attrs<Attr>(item: &mut impl MutItemAttrs) -> syn::Result
/// Get all the cfg attributes (e.g. attribute like `#[cfg..]`) and decode them to `Attr`
pub fn get_item_cfg_attrs(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
attrs.iter().filter_map(|attr| {
if attr.path.segments.first().map_or(false, |segment| segment.ident == "cfg") {
Some(attr.clone())
} else {
None
}
}).collect::<Vec<_>>()
attrs
.iter()
.filter_map(|attr| {
if attr.path.segments.first().map_or(false, |segment| segment.ident == "cfg") {
Some(attr.clone())
} else {
None
}
})
.collect::<Vec<_>>()
}
impl MutItemAttrs for syn::Item {
@@ -116,7 +115,6 @@ impl MutItemAttrs for syn::Item {
}
}
impl MutItemAttrs for syn::TraitItem {
fn mut_item_attrs(&mut self) -> Option<&mut Vec<syn::Attribute>> {
match self {
@@ -143,7 +141,8 @@ impl MutItemAttrs for syn::ItemMod {
/// Return all doc attributes literals found.
pub fn get_doc_literals(attrs: &Vec<syn::Attribute>) -> Vec<syn::Lit> {
attrs.iter()
attrs
.iter()
.filter_map(|attr| {
if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() {
if meta.path.get_ident().map_or(false, |ident| ident == "doc") {
@@ -166,7 +165,7 @@ impl syn::parse::Parse for Unit {
syn::parenthesized!(content in input);
if !content.is_empty() {
let msg = "unexpected tokens, expected nothing inside parenthesis as `()`";
return Err(syn::Error::new(content.span(), msg));
return Err(syn::Error::new(content.span(), msg))
}
Ok(Self)
}
@@ -179,7 +178,7 @@ impl syn::parse::Parse for StaticLifetime {
let lifetime = input.parse::<syn::Lifetime>()?;
if lifetime.ident != "static" {
let msg = "unexpected tokens, expected `static`";
return Err(syn::Error::new(lifetime.ident.span(), msg));
return Err(syn::Error::new(lifetime.ident.span(), msg))
}
Ok(Self)
}
@@ -190,10 +189,7 @@ impl syn::parse::Parse for StaticLifetime {
/// `span` is used in case generics is empty (empty generics has span == call_site).
///
/// return the instance if found.
pub fn check_config_def_gen(
gen: &syn::Generics,
span: proc_macro2::Span,
) -> syn::Result<()> {
pub fn check_config_def_gen(gen: &syn::Generics, span: proc_macro2::Span) -> syn::Result<()> {
let expected = "expected `I: 'static = ()`";
pub struct CheckTraitDefGenerics;
impl syn::parse::Parse for CheckTraitDefGenerics {
@@ -208,13 +204,12 @@ pub fn check_config_def_gen(
}
}
syn::parse2::<CheckTraitDefGenerics>(gen.params.to_token_stream())
.map_err(|e| {
let msg = format!("Invalid generics: {}", expected);
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?;
syn::parse2::<CheckTraitDefGenerics>(gen.params.to_token_stream()).map_err(|e| {
let msg = format!("Invalid generics: {}", expected);
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?;
Ok(())
}
@@ -234,10 +229,7 @@ pub fn check_type_def_gen_no_bounds(
pub struct Checker(InstanceUsage);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut instance_usage = InstanceUsage {
has_instance: false,
span: input.span(),
};
let mut instance_usage = InstanceUsage { has_instance: false, span: input.span() };
input.parse::<keyword::T>()?;
if input.peek(syn::Token![,]) {
@@ -258,7 +250,8 @@ pub fn check_type_def_gen_no_bounds(
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?.0;
})?
.0;
Ok(i)
}
@@ -286,10 +279,7 @@ pub fn check_type_def_optional_gen(
return Ok(Self(None))
}
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
input.parse::<keyword::T>()?;
@@ -338,9 +328,13 @@ pub fn check_type_def_optional_gen(
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?.0
})?
.0
// Span can be call_site if generic is empty. Thus we replace it.
.map(|mut i| { i.span = span; i });
.map(|mut i| {
i.span = span;
i
});
Ok(i)
}
@@ -355,10 +349,7 @@ pub fn check_pallet_struct_usage(type_: &Box<syn::Type>) -> syn::Result<Instance
pub struct Checker(InstanceUsage);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
input.parse::<keyword::Pallet>()?;
input.parse::<syn::Token![<]>()?;
@@ -380,7 +371,8 @@ pub fn check_pallet_struct_usage(type_: &Box<syn::Type>) -> syn::Result<Instance
let mut err = syn::Error::new(type_.span(), msg);
err.combine(e);
err
})?.0;
})?
.0;
Ok(i)
}
@@ -392,18 +384,12 @@ pub fn check_pallet_struct_usage(type_: &Box<syn::Type>) -> syn::Result<Instance
/// `span` is used in case generics is empty (empty generics has span == call_site).
///
/// return whether it contains instance.
pub fn check_impl_gen(
gen: &syn::Generics,
span: proc_macro2::Span
) -> syn::Result<InstanceUsage> {
pub fn check_impl_gen(gen: &syn::Generics, span: proc_macro2::Span) -> syn::Result<InstanceUsage> {
let expected = "expected `impl<T: Config>` or `impl<T: Config<I>, I: 'static>`";
pub struct Checker(InstanceUsage);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
input.parse::<keyword::T>()?;
input.parse::<syn::Token![:]>()?;
@@ -428,7 +414,8 @@ pub fn check_impl_gen(
let mut err = syn::Error::new(span, format!("Invalid generics: {}", expected));
err.combine(e);
err
})?.0;
})?
.0;
Ok(i)
}
@@ -451,10 +438,7 @@ pub fn check_type_def_gen(
pub struct Checker(InstanceUsage);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
input.parse::<keyword::T>()?;
@@ -503,7 +487,8 @@ pub fn check_type_def_gen(
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?.0;
})?
.0;
// Span can be call_site if generic is empty. Thus we replace it.
i.span = span;
@@ -521,10 +506,7 @@ pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result<InstanceUsa
pub struct Checker(InstanceUsage);
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
input.parse::<keyword::GenesisBuild>()?;
input.parse::<syn::Token![<]>()?;
@@ -546,7 +528,8 @@ pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result<InstanceUsa
let mut err = syn::Error::new(type_.span(), msg);
err.combine(e);
err
})?.0;
})?
.0;
Ok(i)
}
@@ -575,10 +558,7 @@ pub fn check_type_value_gen(
input.parse::<syn::Token![:]>()?;
input.parse::<keyword::Config>()?;
let mut instance_usage = InstanceUsage {
span: input.span(),
has_instance: false,
};
let mut instance_usage = InstanceUsage { span: input.span(), has_instance: false };
if input.is_empty() {
return Ok(Self(Some(instance_usage)))
@@ -603,17 +583,19 @@ pub fn check_type_value_gen(
let mut err = syn::Error::new(span, msg);
err.combine(e);
err
})?.0
})?
.0
// Span can be call_site if generic is empty. Thus we replace it.
.map(|mut i| { i.span = span; i });
.map(|mut i| {
i.span = span;
i
});
Ok(i)
}
/// Check the keyword `DispatchResultWithPostInfo` or `DispatchResult`.
pub fn check_pallet_call_return_type(
type_: &syn::Type,
) -> syn::Result<()> {
pub fn check_pallet_call_return_type(type_: &syn::Type) -> syn::Result<()> {
pub struct Checker;
impl syn::parse::Parse for Checker {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// Implementation of the pallet hooks.
pub struct HooksDef {
@@ -42,30 +42,31 @@ impl HooksDef {
item
} else {
let msg = "Invalid pallet::hooks, expected item impl";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
let mut instances = vec![];
instances.push(helper::check_pallet_struct_usage(&item.self_ty)?);
instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?);
let item_trait = &item.trait_.as_ref()
let item_trait = &item
.trait_
.as_ref()
.ok_or_else(|| {
let msg = "Invalid pallet::hooks, expected impl<..> Hooks \
for Pallet<..>";
syn::Error::new(item.span(), msg)
})?.1;
})?
.1;
if item_trait.segments.len() != 1
|| item_trait.segments[0].ident != "Hooks"
{
if item_trait.segments.len() != 1 || item_trait.segments[0].ident != "Hooks" {
let msg = format!(
"Invalid pallet::hooks, expected trait to be `Hooks` found `{}`\
, you can import from `frame_support::pallet_prelude`",
quote::quote!(#item_trait)
);
return Err(syn::Error::new(item_trait.span(), msg));
return Err(syn::Error::new(item_trait.span(), msg))
}
let has_runtime_upgrade = item.items.iter().any(|i| match i {
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// The definition of the pallet inherent implementation.
pub struct InherentDef {
@@ -32,22 +32,22 @@ impl InherentDef {
item
} else {
let msg = "Invalid pallet::inherent, expected item impl";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
if item.trait_.is_none() {
let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() {
if last.ident != "ProvideInherent" {
let msg = "Invalid pallet::inherent, expected trait ProvideInherent";
return Err(syn::Error::new(last.span(), msg));
return Err(syn::Error::new(last.span(), msg))
}
} else {
let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
let mut instances = vec![];
@@ -19,24 +19,24 @@
//!
//! Parse the module into `Def` struct through `Def::try_from` function.
pub mod config;
pub mod pallet_struct;
pub mod hooks;
pub mod call;
pub mod config;
pub mod error;
pub mod origin;
pub mod inherent;
pub mod storage;
pub mod event;
pub mod helper;
pub mod genesis_config;
pub mod genesis_build;
pub mod validate_unsigned;
pub mod type_value;
pub mod extra_constants;
pub mod genesis_build;
pub mod genesis_config;
pub mod helper;
pub mod hooks;
pub mod inherent;
pub mod origin;
pub mod pallet_struct;
pub mod storage;
pub mod type_value;
pub mod validate_unsigned;
use syn::spanned::Spanned;
use frame_support_procedural_tools::generate_crate_access_2018;
use syn::spanned::Spanned;
/// Parsed definition of a pallet.
pub struct Def {
@@ -67,11 +67,14 @@ impl Def {
let frame_support = generate_crate_access_2018("frame-support")?;
let item_span = item.span();
let items = &mut item.content.as_mut()
let items = &mut item
.content
.as_mut()
.ok_or_else(|| {
let msg = "Invalid pallet definition, expected mod to be inlined.";
syn::Error::new(item_span, msg)
})?.1;
})?
.1;
let mut config = None;
let mut pallet_struct = None;
@@ -128,13 +131,12 @@ impl Def {
},
Some(PalletAttr::TypeValue(span)) =>
type_values.push(type_value::TypeValueDef::try_from(span, index, item)?),
Some(PalletAttr::ExtraConstants(_)) => {
Some(PalletAttr::ExtraConstants(_)) =>
extra_constants =
Some(extra_constants::ExtraConstantsDef::try_from(index, item)?)
},
Some(extra_constants::ExtraConstantsDef::try_from(index, item)?),
Some(attr) => {
let msg = "Invalid duplicated attribute";
return Err(syn::Error::new(attr.span(), msg));
return Err(syn::Error::new(attr.span(), msg))
},
None => (),
}
@@ -148,12 +150,13 @@ impl Def {
genesis_config.as_ref().map_or("unused", |_| "used"),
genesis_build.as_ref().map_or("unused", |_| "used"),
);
return Err(syn::Error::new(item_span, msg));
return Err(syn::Error::new(item_span, msg))
}
let def = Def {
item,
config: config.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::config]`"))?,
config: config
.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::config]`"))?,
pallet_struct: pallet_struct
.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::pallet]`"))?,
hooks,
@@ -181,10 +184,7 @@ impl Def {
/// Check that usage of trait `Event` is consistent with the definition, i.e. it is declared
/// and trait defines type Event, or not declared and no trait associated type.
fn check_event_usage(&self) -> syn::Result<()> {
match (
self.config.has_event_type,
self.event.is_some(),
) {
match (self.config.has_event_type, self.event.is_some()) {
(true, false) => {
let msg = "Invalid usage of Event, `Config` contains associated type `Event`, \
but enum `Event` is not declared (i.e. no use of `#[pallet::event]`). \
@@ -197,7 +197,7 @@ impl Def {
An Event associated type must be declare on trait `Config`.";
Err(syn::Error::new(proc_macro2::Span::call_site(), msg))
},
_ => Ok(())
_ => Ok(()),
}
}
@@ -235,19 +235,18 @@ impl Def {
instances.extend_from_slice(&extra_constants.instances[..]);
}
let mut errors = instances.into_iter()
.filter_map(|instances| {
if instances.has_instance == self.config.has_instance {
return None
}
let msg = if self.config.has_instance {
"Invalid generic declaration, trait is defined with instance but generic use none"
} else {
"Invalid generic declaration, trait is defined without instance but generic use \
let mut errors = instances.into_iter().filter_map(|instances| {
if instances.has_instance == self.config.has_instance {
return None
}
let msg = if self.config.has_instance {
"Invalid generic declaration, trait is defined with instance but generic use none"
} else {
"Invalid generic declaration, trait is defined without instance but generic use \
some"
};
Some(syn::Error::new(instances.span, msg))
});
};
Some(syn::Error::new(instances.span, msg))
});
if let Some(mut first_error) = errors.next() {
for error in errors {
@@ -351,7 +350,8 @@ impl GenericKind {
match self {
GenericKind::None => quote::quote!(),
GenericKind::Config => quote::quote_spanned!(span => T: Config),
GenericKind::ConfigAndInstance => quote::quote_spanned!(span => T: Config<I>, I: 'static),
GenericKind::ConfigAndInstance =>
quote::quote_spanned!(span => T: Config<I>, I: 'static),
}
}
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// Definition of the pallet origin type.
///
@@ -42,7 +42,7 @@ impl OriginDef {
syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics),
_ => {
let msg = "Invalid pallet::origin, expected enum or struct or type";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
},
};
@@ -54,27 +54,19 @@ impl OriginDef {
instances.push(u);
} else {
// construct_runtime only allow generic event for instantiable pallet.
instances.push(helper::InstanceUsage {
has_instance: false,
span: ident.span(),
})
instances.push(helper::InstanceUsage { has_instance: false, span: ident.span() })
}
if !matches!(vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::origin, Origin must be public";
return Err(syn::Error::new(item_span, msg));
return Err(syn::Error::new(item_span, msg))
}
if ident != "Origin" {
let msg = "Invalid pallet::origin, ident must `Origin`";
return Err(syn::Error::new(ident.span(), msg));
return Err(syn::Error::new(ident.span(), msg))
}
Ok(OriginDef {
index,
has_instance,
is_generic,
instances,
})
Ok(OriginDef { index, has_instance, is_generic, instances })
}
}
@@ -16,8 +16,8 @@
// limitations under the License.
use super::helper;
use syn::spanned::Spanned;
use quote::ToTokens;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -49,11 +49,7 @@ pub struct PalletStructDef {
/// * `#[pallet::generate_store($vis trait Store)]`
/// * `#[pallet::generate_storage_info]`
pub enum PalletStructAttr {
GenerateStore {
span: proc_macro2::Span,
vis: syn::Visibility,
keyword: keyword::Store,
},
GenerateStore { span: proc_macro2::Span, vis: syn::Visibility, keyword: keyword::Store },
GenerateStorageInfoTrait(proc_macro2::Span),
}
@@ -103,7 +99,7 @@ impl PalletStructDef {
item
} else {
let msg = "Invalid pallet::pallet, expected struct definition";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
let mut store = None;
@@ -115,12 +111,14 @@ impl PalletStructDef {
PalletStructAttr::GenerateStore { vis, keyword, .. } if store.is_none() => {
store = Some((vis, keyword));
},
PalletStructAttr::GenerateStorageInfoTrait(span) if generate_storage_info.is_none() => {
PalletStructAttr::GenerateStorageInfoTrait(span)
if generate_storage_info.is_none() =>
{
generate_storage_info = Some(span);
},
}
attr => {
let msg = "Unexpected duplicated attribute";
return Err(syn::Error::new(attr.span(), msg));
return Err(syn::Error::new(attr.span(), msg))
},
}
}
@@ -129,12 +127,12 @@ impl PalletStructDef {
if !matches!(item.vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::pallet, Pallet must be public";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
if item.generics.where_clause.is_some() {
let msg = "Invalid pallet::pallet, where clause not supported on Pallet declaration";
return Err(syn::Error::new(item.generics.where_clause.span(), msg));
return Err(syn::Error::new(item.generics.where_clause.span(), msg))
}
let mut instances = vec![];
@@ -16,9 +16,9 @@
// limitations under the License.
use super::helper;
use syn::spanned::Spanned;
use quote::ToTokens;
use std::collections::HashMap;
use syn::spanned::Spanned;
/// List of additional token to be used for parsing.
mod keyword {
@@ -69,11 +69,10 @@ impl syn::parse::Parse for PalletStorageAttr {
let renamed_prefix = content.parse::<syn::LitStr>()?;
// Ensure the renamed prefix is a proper Rust identifier
syn::parse_str::<syn::Ident>(&renamed_prefix.value())
.map_err(|_| {
let msg = format!("`{}` is not a valid identifier", renamed_prefix.value());
syn::Error::new(renamed_prefix.span(), msg)
})?;
syn::parse_str::<syn::Ident>(&renamed_prefix.value()).map_err(|_| {
let msg = format!("`{}` is not a valid identifier", renamed_prefix.value());
syn::Error::new(renamed_prefix.span(), msg)
})?;
Ok(Self::StorageName(renamed_prefix, attr_span))
} else {
@@ -86,16 +85,8 @@ impl syn::parse::Parse for PalletStorageAttr {
pub enum Metadata {
Value { value: syn::Type },
Map { value: syn::Type, key: syn::Type },
DoubleMap {
value: syn::Type,
key1: syn::Type,
key2: syn::Type
},
NMap {
keys: Vec<syn::Type>,
keygen: syn::Type,
value: syn::Type,
},
DoubleMap { value: syn::Type, key1: syn::Type, key2: syn::Type },
NMap { keys: Vec<syn::Type>, keygen: syn::Type, value: syn::Type },
}
pub enum QueryKind {
@@ -181,11 +172,8 @@ impl StorageGenerics {
Self::DoubleMap { value, key1, key2, .. } => Metadata::DoubleMap { value, key1, key2 },
Self::Map { value, key, .. } => Metadata::Map { value, key },
Self::Value { value, .. } => Metadata::Value { value },
Self::NMap { keygen, value, .. } => Metadata::NMap {
keys: collect_keys(&keygen)?,
keygen,
value,
},
Self::NMap { keygen, value, .. } =>
Metadata::NMap { keys: collect_keys(&keygen)?, keygen, value },
};
Ok(res)
@@ -194,11 +182,10 @@ impl StorageGenerics {
/// Return the query kind from the defined generics
fn query_kind(&self) -> Option<syn::Type> {
match &self {
Self::DoubleMap { query_kind, .. }
| Self::Map { query_kind, .. }
| Self::Value { query_kind, .. }
| Self::NMap { query_kind, .. }
=> query_kind.clone(),
Self::DoubleMap { query_kind, .. } |
Self::Map { query_kind, .. } |
Self::Value { query_kind, .. } |
Self::NMap { query_kind, .. } => query_kind.clone(),
}
}
}
@@ -225,7 +212,10 @@ fn check_generics(
let mut e = format!(
"`{}` expect generics {}and optional generics {}",
storage_type_name,
mandatory_generics.iter().map(|name| format!("`{}`, ", name)).collect::<String>(),
mandatory_generics
.iter()
.map(|name| format!("`{}`, ", name))
.collect::<String>(),
&optional_generics.iter().map(|name| format!("`{}`, ", name)).collect::<String>(),
);
e.pop();
@@ -235,14 +225,12 @@ fn check_generics(
};
for (gen_name, gen_binding) in map {
if !mandatory_generics.contains(&gen_name.as_str())
&& !optional_generics.contains(&gen_name.as_str())
if !mandatory_generics.contains(&gen_name.as_str()) &&
!optional_generics.contains(&gen_name.as_str())
{
let msg = format!(
"Invalid pallet::storage, Unexpected generic `{}` for `{}`. {}",
gen_name,
storage_type_name,
expectation,
gen_name, storage_type_name, expectation,
);
errors.push(syn::Error::new(gen_binding.span(), msg));
}
@@ -252,8 +240,7 @@ fn check_generics(
if !map.contains_key(&mandatory_generic.to_string()) {
let msg = format!(
"Invalid pallet::storage, cannot find `{}` generic, required for `{}`.",
mandatory_generic,
storage_type_name
mandatory_generic, storage_type_name
);
errors.push(syn::Error::new(args_span, msg));
}
@@ -284,7 +271,7 @@ fn process_named_generics(
let msg = "Invalid pallet::storage, Duplicated named generic";
let mut err = syn::Error::new(arg.ident.span(), msg);
err.combine(syn::Error::new(other.ident.span(), msg));
return Err(err);
return Err(err)
}
parsed.insert(arg.ident.to_string(), arg.clone());
}
@@ -300,15 +287,14 @@ fn process_named_generics(
)?;
StorageGenerics::Value {
value: parsed.remove("Value")
value: parsed
.remove("Value")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
query_kind: parsed.remove("QueryKind")
.map(|binding| binding.ty),
on_empty: parsed.remove("OnEmpty")
.map(|binding| binding.ty),
query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
}
}
},
StorageKind::Map => {
check_generics(
&parsed,
@@ -319,20 +305,23 @@ fn process_named_generics(
)?;
StorageGenerics::Map {
hasher: parsed.remove("Hasher")
hasher: parsed
.remove("Hasher")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
key: parsed.remove("Key")
key: parsed
.remove("Key")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
value: parsed.remove("Value")
value: parsed
.remove("Value")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
}
}
},
StorageKind::DoubleMap => {
check_generics(
&parsed,
@@ -343,26 +332,31 @@ fn process_named_generics(
)?;
StorageGenerics::DoubleMap {
hasher1: parsed.remove("Hasher1")
hasher1: parsed
.remove("Hasher1")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
key1: parsed.remove("Key1")
key1: parsed
.remove("Key1")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
hasher2: parsed.remove("Hasher2")
hasher2: parsed
.remove("Hasher2")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
key2: parsed.remove("Key2")
key2: parsed
.remove("Key2")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
value: parsed.remove("Value")
value: parsed
.remove("Value")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
}
}
},
StorageKind::NMap => {
check_generics(
&parsed,
@@ -373,17 +367,19 @@ fn process_named_generics(
)?;
StorageGenerics::NMap {
keygen: parsed.remove("Key")
keygen: parsed
.remove("Key")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
value: parsed.remove("Value")
value: parsed
.remove("Value")
.map(|binding| binding.ty)
.expect("checked above as mandatory generic"),
query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
}
}
},
};
let metadata = generics.metadata()?;
@@ -399,41 +395,32 @@ fn process_unnamed_generics(
args: &[syn::Type],
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>)> {
let retrieve_arg = |arg_pos| {
args.get(arg_pos)
.cloned()
.ok_or_else(|| {
let msg = format!(
"Invalid pallet::storage, unexpected number of generic argument, \
args.get(arg_pos).cloned().ok_or_else(|| {
let msg = format!(
"Invalid pallet::storage, unexpected number of generic argument, \
expect at least {} args, found {}.",
arg_pos + 1,
args.len(),
);
syn::Error::new(args_span, msg)
})
arg_pos + 1,
args.len(),
);
syn::Error::new(args_span, msg)
})
};
let prefix_arg = retrieve_arg(0)?;
syn::parse2::<syn::Token![_]>(prefix_arg.to_token_stream())
.map_err(|e| {
let msg = "Invalid pallet::storage, for unnamed generic arguments the type \
syn::parse2::<syn::Token![_]>(prefix_arg.to_token_stream()).map_err(|e| {
let msg = "Invalid pallet::storage, for unnamed generic arguments the type \
first generic argument must be `_`, the argument is then replaced by macro.";
let mut err = syn::Error::new(prefix_arg.span(), msg);
err.combine(e);
err
})?;
let mut err = syn::Error::new(prefix_arg.span(), msg);
err.combine(e);
err
})?;
let res = match storage {
StorageKind::Value => (
None,
Metadata::Value { value: retrieve_arg(1)? },
retrieve_arg(2).ok(),
),
StorageKind::Value =>
(None, Metadata::Value { value: retrieve_arg(1)? }, retrieve_arg(2).ok()),
StorageKind::Map => (
None,
Metadata::Map {
key: retrieve_arg(2)?,
value: retrieve_arg(3)?,
},
Metadata::Map { key: retrieve_arg(2)?, value: retrieve_arg(3)? },
retrieve_arg(4).ok(),
),
StorageKind::DoubleMap => (
@@ -448,15 +435,7 @@ fn process_unnamed_generics(
StorageKind::NMap => {
let keygen = retrieve_arg(1)?;
let keys = collect_keys(&keygen)?;
(
None,
Metadata::NMap {
keys,
keygen,
value: retrieve_arg(2)?,
},
retrieve_arg(3).ok(),
)
(None, Metadata::NMap { keys, keygen, value: retrieve_arg(2)? }, retrieve_arg(3).ok())
},
};
@@ -479,8 +458,8 @@ fn process_generics(
found `{}`.",
found,
);
return Err(syn::Error::new(segment.ident.span(), msg));
}
return Err(syn::Error::new(segment.ident.span(), msg))
},
};
let args_span = segment.arguments.span();
@@ -490,12 +469,14 @@ fn process_generics(
_ => {
let msg = "Invalid pallet::storage, invalid number of generic generic arguments, \
expect more that 0 generic arguments.";
return Err(syn::Error::new(segment.span(), msg));
}
return Err(syn::Error::new(segment.span(), msg))
},
};
if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::Type(_))) {
let args = args.args.iter()
let args = args
.args
.iter()
.map(|gen| match gen {
syn::GenericArgument::Type(gen) => gen.clone(),
_ => unreachable!("It is asserted above that all generics are types"),
@@ -503,7 +484,9 @@ fn process_generics(
.collect::<Vec<_>>();
process_unnamed_generics(&storage_kind, args_span, &args)
} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::Binding(_))) {
let args = args.args.iter()
let args = args
.args
.iter()
.map(|gen| match gen {
syn::GenericArgument::Binding(gen) => gen.clone(),
_ => unreachable!("It is asserted above that all generics are bindings"),
@@ -521,11 +504,7 @@ fn process_generics(
/// Parse the 2nd type argument to `StorageNMap` and return its keys.
fn collect_keys(keygen: &syn::Type) -> syn::Result<Vec<syn::Type>> {
if let syn::Type::Tuple(tup) = keygen {
tup
.elems
.iter()
.map(extract_key)
.collect::<syn::Result<Vec<_>>>()
tup.elems.iter().map(extract_key).collect::<syn::Result<Vec<_>>>()
} else {
Ok(vec![extract_key(keygen)?])
}
@@ -537,7 +516,7 @@ fn extract_key(ty: &syn::Type) -> syn::Result<syn::Type> {
typ
} else {
let msg = "Invalid pallet::storage, expected type path";
return Err(syn::Error::new(ty.span(), msg));
return Err(syn::Error::new(ty.span(), msg))
};
let key_struct = typ.path.segments.last().ok_or_else(|| {
@@ -546,28 +525,31 @@ fn extract_key(ty: &syn::Type) -> syn::Result<syn::Type> {
})?;
if key_struct.ident != "Key" && key_struct.ident != "NMapKey" {
let msg = "Invalid pallet::storage, expected Key or NMapKey struct";
return Err(syn::Error::new(key_struct.ident.span(), msg));
return Err(syn::Error::new(key_struct.ident.span(), msg))
}
let ty_params = if let syn::PathArguments::AngleBracketed(args) = &key_struct.arguments {
args
} else {
let msg = "Invalid pallet::storage, expected angle bracketed arguments";
return Err(syn::Error::new(key_struct.arguments.span(), msg));
return Err(syn::Error::new(key_struct.arguments.span(), msg))
};
if ty_params.args.len() != 2 {
let msg = format!("Invalid pallet::storage, unexpected number of generic arguments \
for Key struct, expected 2 args, found {}", ty_params.args.len());
return Err(syn::Error::new(ty_params.span(), msg));
let msg = format!(
"Invalid pallet::storage, unexpected number of generic arguments \
for Key struct, expected 2 args, found {}",
ty_params.args.len()
);
return Err(syn::Error::new(ty_params.span(), msg))
}
let key = match &ty_params.args[1] {
syn::GenericArgument::Type(key_ty) => key_ty.clone(),
_ => {
let msg = "Invalid pallet::storage, expected type";
return Err(syn::Error::new(ty_params.args[1].span(), msg));
}
return Err(syn::Error::new(ty_params.args[1].span(), msg))
},
};
Ok(key)
@@ -576,8 +558,7 @@ fn extract_key(ty: &syn::Type) -> syn::Result<syn::Type> {
impl StorageDef {
/// Return the storage prefix for this storage item
pub fn prefix(&self) -> String {
self
.rename_as
self.rename_as
.as_ref()
.map(syn::LitStr::value)
.unwrap_or(self.ident.to_string())
@@ -586,11 +567,7 @@ impl StorageDef {
/// Return either the span of the ident or the span of the literal in the
/// #[storage_prefix] attribute
pub fn prefix_span(&self) -> proc_macro2::Span {
self
.rename_as
.as_ref()
.map(syn::LitStr::span)
.unwrap_or(self.ident.span())
self.rename_as.as_ref().map(syn::LitStr::span).unwrap_or(self.ident.span())
}
pub fn try_from(
@@ -601,7 +578,7 @@ impl StorageDef {
let item = if let syn::Item::Type(item) = item {
item
} else {
return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expect item type."));
return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expect item type."))
};
let attrs: Vec<PalletStorageAttr> = helper::take_item_pallet_attrs(&mut item.attrs)?;
@@ -610,23 +587,19 @@ impl StorageDef {
.partition::<Vec<_>, _>(|attr| matches!(attr, PalletStorageAttr::Getter(..)));
if getters.len() > 1 {
let msg = "Invalid pallet::storage, multiple argument pallet::getter found";
return Err(syn::Error::new(getters[1].attr_span(), msg));
return Err(syn::Error::new(getters[1].attr_span(), msg))
}
if names.len() > 1 {
let msg = "Invalid pallet::storage, multiple argument pallet::storage_prefix found";
return Err(syn::Error::new(names[1].attr_span(), msg));
return Err(syn::Error::new(names[1].attr_span(), msg))
}
let getter = getters.pop().map(|attr| {
match attr {
PalletStorageAttr::Getter(ident, _) => ident,
_ => unreachable!(),
}
let getter = getters.pop().map(|attr| match attr {
PalletStorageAttr::Getter(ident, _) => ident,
_ => unreachable!(),
});
let rename_as = names.pop().map(|attr| {
match attr {
PalletStorageAttr::StorageName(lit, _) => lit,
_ => unreachable!(),
}
let rename_as = names.pop().map(|attr| match attr {
PalletStorageAttr::StorageName(lit, _) => lit,
_ => unreachable!(),
});
let cfg_attrs = helper::get_item_cfg_attrs(&item.attrs);
@@ -641,12 +614,12 @@ impl StorageDef {
typ
} else {
let msg = "Invalid pallet::storage, expected type path";
return Err(syn::Error::new(item.ty.span(), msg));
return Err(syn::Error::new(item.ty.span(), msg))
};
if typ.path.segments.len() != 1 {
let msg = "Invalid pallet::storage, expected type path with one segment";
return Err(syn::Error::new(item.ty.span(), msg));
return Err(syn::Error::new(item.ty.span(), msg))
}
let (named_generics, metadata, query_kind) = process_generics(&typ.path.segments[0])?;
@@ -654,11 +627,11 @@ impl StorageDef {
let query_kind = query_kind
.map(|query_kind| match query_kind {
syn::Type::Path(path)
if path.path.segments.last().map_or(false, |s| s.ident == "OptionQuery")
=> Some(QueryKind::OptionQuery),
if path.path.segments.last().map_or(false, |s| s.ident == "OptionQuery") =>
Some(QueryKind::OptionQuery),
syn::Type::Path(path)
if path.path.segments.last().map_or(false, |s| s.ident == "ValueQuery")
=> Some(QueryKind::ValueQuery),
if path.path.segments.last().map_or(false, |s| s.ident == "ValueQuery") =>
Some(QueryKind::ValueQuery),
_ => None,
})
.unwrap_or(Some(QueryKind::OptionQuery)); // This value must match the default generic.
@@ -667,7 +640,7 @@ impl StorageDef {
let msg = "Invalid pallet::storage, cannot generate getter because QueryKind is not \
identifiable. QueryKind must be `OptionQuery`, `ValueQuery`, or default one to be \
identifiable.";
return Err(syn::Error::new(getter.unwrap().span(), msg));
return Err(syn::Error::new(getter.unwrap().span(), msg))
}
Ok(StorageDef {
@@ -50,28 +50,31 @@ impl TypeValueDef {
item
} else {
let msg = "Invalid pallet::type_value, expected item fn";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
if !item.attrs.is_empty() {
let msg = "Invalid pallet::type_value, unexpected attribute";
return Err(syn::Error::new(item.attrs[0].span(), msg));
return Err(syn::Error::new(item.attrs[0].span(), msg))
}
if let Some(span) = item.sig.constness.as_ref().map(|t| t.span())
if let Some(span) = item
.sig
.constness
.as_ref()
.map(|t| t.span())
.or_else(|| item.sig.asyncness.as_ref().map(|t| t.span()))
.or_else(|| item.sig.unsafety.as_ref().map(|t| t.span()))
.or_else(|| item.sig.abi.as_ref().map(|t| t.span()))
.or_else(|| item.sig.variadic.as_ref().map(|t| t.span()))
{
let msg = "Invalid pallet::type_value, unexpected token";
return Err(syn::Error::new(span, msg));
return Err(syn::Error::new(span, msg))
}
if !item.sig.inputs.is_empty() {
let msg = "Invalid pallet::type_value, unexpected argument";
return Err(syn::Error::new(item.sig.inputs[0].span(), msg));
return Err(syn::Error::new(item.sig.inputs[0].span(), msg))
}
let vis = item.vis.clone();
@@ -81,7 +84,7 @@ impl TypeValueDef {
syn::ReturnType::Type(_, type_) => type_,
syn::ReturnType::Default => {
let msg = "Invalid pallet::type_value, expected return type";
return Err(syn::Error::new(item.sig.span(), msg));
return Err(syn::Error::new(item.sig.span(), msg))
},
};
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use syn::spanned::Spanned;
use super::helper;
use syn::spanned::Spanned;
/// The definition of the pallet validate unsigned implementation.
pub struct ValidateUnsignedDef {
@@ -32,24 +32,24 @@ impl ValidateUnsignedDef {
item
} else {
let msg = "Invalid pallet::validate_unsigned, expected item impl";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
};
if item.trait_.is_none() {
let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \
Pallet<..>";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() {
if last.ident != "ValidateUnsigned" {
let msg = "Invalid pallet::validate_unsigned, expected trait ValidateUnsigned";
return Err(syn::Error::new(last.span(), msg));
return Err(syn::Error::new(last.span(), msg))
}
} else {
let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \
Pallet<..>";
return Err(syn::Error::new(item.span(), msg));
return Err(syn::Error::new(item.span(), msg))
}
let mut instances = vec![];
@@ -17,10 +17,10 @@
//! Implementation of macros related to pallet versioning.
use proc_macro2::{TokenStream, Span};
use syn::{Result, Error};
use std::{env, str::FromStr};
use frame_support_procedural_tools::generate_crate_access_2018;
use proc_macro2::{Span, TokenStream};
use std::{env, str::FromStr};
use syn::{Error, Result};
/// Get the version from the given version environment variable.
///
@@ -30,41 +30,47 @@ pub fn derive_partial_eq_no_bound(input: proc_macro::TokenStream) -> proc_macro:
let impl_ = match input.data {
syn::Data::Struct(struct_) => match struct_.fields {
syn::Fields::Named(named) => {
let fields = named.named.iter()
let fields = named
.named
.iter()
.map(|i| &i.ident)
.map(|i| quote::quote_spanned!(i.span() => self.#i == other.#i ));
quote::quote!( true #( && #fields )* )
},
syn::Fields::Unnamed(unnamed) => {
let fields = unnamed.unnamed.iter().enumerate()
let fields = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, _)| syn::Index::from(i))
.map(|i| quote::quote_spanned!(i.span() => self.#i == other.#i ));
quote::quote!( true #( && #fields )* )
},
syn::Fields::Unit => {
quote::quote!( true )
}
quote::quote!(true)
},
},
syn::Data::Enum(enum_) => {
let variants = enum_.variants.iter()
.map(|variant| {
let variants =
enum_.variants.iter().map(|variant| {
let ident = &variant.ident;
match &variant.fields {
syn::Fields::Named(named) => {
let names = named.named.iter().map(|i| &i.ident);
let other_names = names.clone()
.enumerate()
.map(|(n, ident)|
syn::Ident::new(&format!("_{}", n), ident.span())
);
let other_names = names.clone().enumerate().map(|(n, ident)| {
syn::Ident::new(&format!("_{}", n), ident.span())
});
let capture = names.clone();
let other_capture = names.clone().zip(other_names.clone())
let other_capture = names
.clone()
.zip(other_names.clone())
.map(|(i, other_i)| quote::quote!(#i: #other_i));
let eq = names.zip(other_names)
.map(|(i, other_i)| quote::quote_spanned!(i.span() => #i == #other_i));
let eq = names.zip(other_names).map(
|(i, other_i)| quote::quote_spanned!(i.span() => #i == #other_i),
);
quote::quote!(
(
Self::#ident { #( #capture, )* },
@@ -73,12 +79,18 @@ pub fn derive_partial_eq_no_bound(input: proc_macro::TokenStream) -> proc_macro:
)
},
syn::Fields::Unnamed(unnamed) => {
let names = unnamed.unnamed.iter().enumerate()
let names = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}", i), f.span()));
let other_names = unnamed.unnamed.iter().enumerate()
.map(|(i, f)| syn::Ident::new(&format!("_{}_other", i), f.span()));
let eq = names.clone().zip(other_names.clone())
.map(|(i, other_i)| quote::quote_spanned!(i.span() => #i == #other_i));
let other_names =
unnamed.unnamed.iter().enumerate().map(|(i, f)| {
syn::Ident::new(&format!("_{}_other", i), f.span())
});
let eq = names.clone().zip(other_names.clone()).map(
|(i, other_i)| quote::quote_spanned!(i.span() => #i == #other_i),
);
quote::quote!(
(
Self::#ident ( #( #names, )* ),
@@ -122,5 +134,6 @@ pub fn derive_partial_eq_no_bound(input: proc_macro::TokenStream) -> proc_macro:
}
}
};
).into()
)
.into()
}
@@ -17,11 +17,11 @@
//! Builder logic definition used to build genesis storage.
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
use frame_support_procedural_tools::syn_ext as ext;
use proc_macro2::TokenStream;
use syn::spanned::Spanned;
use quote::{quote, quote_spanned};
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
use syn::spanned::Spanned;
/// Definition of builder blocks, each block insert some value in the storage.
/// They must be called inside externalities, and with `self` being the genesis config.
@@ -79,7 +79,7 @@ impl BuilderDef {
if let Some(data) = data {
blocks.push(match &line.storage_type {
StorageLineTypeDef::Simple(_) if line.is_option => {
quote!{{
quote! {{
#data
let v: Option<&#value_type>= data;
if let Some(v) = v {
@@ -88,7 +88,7 @@ impl BuilderDef {
}}
},
StorageLineTypeDef::Simple(_) if !line.is_option => {
quote!{{
quote! {{
#data
let v: &#value_type = data;
<#storage_struct as #scrate::#storage_trait>::put::<&#value_type>(v);
@@ -97,7 +97,7 @@ impl BuilderDef {
StorageLineTypeDef::Simple(_) => unreachable!(),
StorageLineTypeDef::Map(map) => {
let key = &map.key;
quote!{{
quote! {{
#data
let data: &#scrate::sp_std::vec::Vec<(#key, #value_type)> = data;
data.iter().for_each(|(k, v)| {
@@ -110,7 +110,7 @@ impl BuilderDef {
StorageLineTypeDef::DoubleMap(map) => {
let key1 = &map.key1;
let key2 = &map.key2;
quote!{{
quote! {{
#data
let data: &#scrate::sp_std::vec::Vec<(#key1, #key2, #value_type)> = data;
data.iter().for_each(|(k1, k2, v)| {
@@ -122,12 +122,8 @@ impl BuilderDef {
},
StorageLineTypeDef::NMap(map) => {
let key_tuple = map.to_key_tuple();
let key_arg = if map.keys.len() == 1 {
quote!((k,))
} else {
quote!(k)
};
quote!{{
let key_arg = if map.keys.len() == 1 { quote!((k,)) } else { quote!(k) };
quote! {{
#data
let data: &#scrate::sp_std::vec::Vec<(#key_tuple, #value_type)> = data;
data.iter().for_each(|(k, v)| {
@@ -148,10 +144,6 @@ impl BuilderDef {
});
}
Self {
blocks,
is_generic,
}
Self { blocks, is_generic }
}
}
@@ -17,11 +17,11 @@
//! Genesis config definition.
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
use frame_support_procedural_tools::syn_ext as ext;
use proc_macro2::TokenStream;
use syn::{spanned::Spanned, parse_quote};
use quote::quote;
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
use syn::{parse_quote, spanned::Spanned};
pub struct GenesisConfigFieldDef {
pub name: syn::Ident,
@@ -47,30 +47,28 @@ impl GenesisConfigDef {
pub fn from_def(def: &DeclStorageDefExt) -> syn::Result<Self> {
let fields = Self::get_genesis_config_field_defs(def)?;
let is_generic = fields.iter()
let is_generic = fields
.iter()
.any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic));
let (
genesis_struct_decl,
genesis_impl,
genesis_struct,
genesis_where_clause
) = if is_generic {
let runtime_generic = &def.module_runtime_generic;
let runtime_trait = &def.module_runtime_trait;
let optional_instance = &def.optional_instance;
let optional_instance_bound = &def.optional_instance_bound;
let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default;
let where_clause = &def.where_clause;
(
quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound_optional_default>),
quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound>),
quote!(<#runtime_generic, #optional_instance>),
where_clause.clone(),
)
} else {
(quote!(), quote!(), quote!(), None)
};
let (genesis_struct_decl, genesis_impl, genesis_struct, genesis_where_clause) =
if is_generic {
let runtime_generic = &def.module_runtime_generic;
let runtime_trait = &def.module_runtime_trait;
let optional_instance = &def.optional_instance;
let optional_instance_bound = &def.optional_instance_bound;
let optional_instance_bound_optional_default =
&def.optional_instance_bound_optional_default;
let where_clause = &def.where_clause;
(
quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound_optional_default>),
quote!(<#runtime_generic: #runtime_trait, #optional_instance_bound>),
quote!(<#runtime_generic, #optional_instance>),
where_clause.clone(),
)
} else {
(quote!(), quote!(), quote!(), None)
};
Ok(Self {
is_generic,
@@ -82,14 +80,14 @@ impl GenesisConfigDef {
})
}
fn get_genesis_config_field_defs(def: &DeclStorageDefExt)
-> syn::Result<Vec<GenesisConfigFieldDef>>
{
fn get_genesis_config_field_defs(
def: &DeclStorageDefExt,
) -> syn::Result<Vec<GenesisConfigFieldDef>> {
let mut config_field_defs = Vec::new();
for (config_field, line) in def.storage_lines.iter()
.filter_map(|line| line.config.as_ref().map(|config_field| (config_field.clone(), line)))
{
for (config_field, line) in def.storage_lines.iter().filter_map(|line| {
line.config.as_ref().map(|config_field| (config_field.clone(), line))
}) {
let value_type = &line.value_type;
let typ = match &line.storage_type {
@@ -107,18 +105,20 @@ impl GenesisConfigDef {
StorageLineTypeDef::NMap(map) => {
let key_tuple = map.to_key_tuple();
parse_quote!( Vec<(#key_tuple, #value_type)> )
}
},
};
let default = line.default_value.as_ref()
.map(|d| {
if line.is_option {
quote!( #d.unwrap_or_default() )
} else {
quote!( #d )
}
})
.unwrap_or_else(|| quote!( Default::default() ));
let default =
line.default_value
.as_ref()
.map(|d| {
if line.is_option {
quote!( #d.unwrap_or_default() )
} else {
quote!( #d )
}
})
.unwrap_or_else(|| quote!(Default::default()));
config_field_defs.push(GenesisConfigFieldDef {
name: config_field,
@@ -129,22 +129,26 @@ impl GenesisConfigDef {
}
for line in &def.extra_genesis_config_lines {
let attrs = line.attrs.iter()
let attrs = line
.attrs
.iter()
.map(|attr| {
let meta = attr.parse_meta()?;
if meta.path().is_ident("cfg") {
return Err(syn::Error::new(
meta.span(),
"extra genesis config items do not support `cfg` attribute"
));
"extra genesis config items do not support `cfg` attribute",
))
}
Ok(meta)
})
.collect::<syn::Result<_>>()?;
let default = line.default.as_ref().map(|e| quote!( #e ))
.unwrap_or_else(|| quote!( Default::default() ));
let default = line
.default
.as_ref()
.map(|e| quote!( #e ))
.unwrap_or_else(|| quote!(Default::default()));
config_field_defs.push(GenesisConfigFieldDef {
name: line.name.clone(),
@@ -18,14 +18,14 @@
//! Declaration of genesis config structure and implementation of build storage trait and
//! functions.
use proc_macro2::{TokenStream, Span};
use quote::quote;
use super::DeclStorageDefExt;
pub use genesis_config_def::GenesisConfigDef;
pub use builder_def::BuilderDef;
pub use genesis_config_def::GenesisConfigDef;
use proc_macro2::{Span, TokenStream};
use quote::quote;
mod genesis_config_def;
mod builder_def;
mod genesis_config_def;
const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance";
@@ -118,19 +118,16 @@ fn impl_build_storage(
let genesis_impl = &genesis_config.genesis_impl;
let genesis_where_clause = &genesis_config.genesis_where_clause;
let (
fn_generic,
fn_traitinstance,
fn_where_clause
) = if !genesis_config.is_generic && builders.is_generic {
(
quote!( <#runtime_generic: #runtime_trait, #optional_instance_bound> ),
quote!( #runtime_generic, #optional_instance ),
Some(&def.where_clause),
)
} else {
(quote!(), quote!(), None)
};
let (fn_generic, fn_traitinstance, fn_where_clause) =
if !genesis_config.is_generic && builders.is_generic {
(
quote!( <#runtime_generic: #runtime_trait, #optional_instance_bound> ),
quote!( #runtime_generic, #optional_instance ),
Some(&def.where_clause),
)
} else {
(quote!(), quote!(), None)
};
let builder_blocks = &builders.blocks;
@@ -138,7 +135,7 @@ fn impl_build_storage(
#scrate::sp_runtime::BuildModuleGenesisStorage<#runtime_generic, #inherent_instance>
);
quote!{
quote! {
#[cfg(feature = "std")]
impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause {
/// Build the storage for this module.
@@ -189,7 +186,7 @@ pub fn genesis_config_and_build_storage(def: &DeclStorageDefExt) -> TokenStream
decl_genesis_config_and_impl_default(scrate, &genesis_config);
let impl_build_storage = impl_build_storage(scrate, def, &genesis_config, &builders);
quote!{
quote! {
#decl_genesis_config_and_impl_default
#impl_build_storage
}
@@ -17,15 +17,17 @@
//! Implementation of getters on module structure.
use super::{DeclStorageDefExt, StorageLineTypeDef};
use proc_macro2::TokenStream;
use quote::quote;
use super::{DeclStorageDefExt, StorageLineTypeDef};
pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
let scrate = &def.hidden_crate;
let mut getters = TokenStream::new();
for (get_fn, line) in def.storage_lines.iter()
for (get_fn, line) in def
.storage_lines
.iter()
.filter_map(|line| line.getter.as_ref().map(|get_fn| (get_fn, line)))
{
let attrs = &line.doc_attrs;
@@ -35,7 +37,7 @@ pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
let getter = match &line.storage_type {
StorageLineTypeDef::Simple(value) => {
quote!{
quote! {
#( #[ #attrs ] )*
pub fn #get_fn() -> #value {
<#storage_struct as #scrate::#storage_trait>::get()
@@ -45,7 +47,7 @@ pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
StorageLineTypeDef::Map(map) => {
let key = &map.key;
let value = &map.value;
quote!{
quote! {
#( #[ #attrs ] )*
pub fn #get_fn<K: #scrate::codec::EncodeLike<#key>>(key: K) -> #value {
<#storage_struct as #scrate::#storage_trait>::get(key)
@@ -56,7 +58,7 @@ pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
let key1 = &map.key1;
let key2 = &map.key2;
let value = &map.value;
quote!{
quote! {
pub fn #get_fn<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> #value
where
KArg1: #scrate::codec::EncodeLike<#key1>,
@@ -69,7 +71,7 @@ pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
StorageLineTypeDef::NMap(map) => {
let keygen = map.to_keygen_struct(&def.hidden_crate);
let value = &map.value;
quote!{
quote! {
pub fn #get_fn<KArg>(key: KArg) -> #value
where
KArg: #scrate::storage::types::EncodeLikeTuple<
@@ -80,7 +82,7 @@ pub fn impl_getters(def: &DeclStorageDefExt) -> TokenStream {
<#storage_struct as #scrate::#storage_trait>::get(key)
}
}
}
},
};
getters.extend(getter);
}
@@ -18,10 +18,10 @@
//! Implementation of the trait instance and the instance structures implementing it.
//! (For not instantiable traits there is still the inherent instance implemented).
use proc_macro2::{TokenStream, Span};
use quote::quote;
use super::DeclStorageDefExt;
use crate::NUMBER_OF_INSTANCE;
use proc_macro2::{Span, TokenStream};
use quote::quote;
pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
@@ -52,14 +52,12 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
index: i,
}
})
.chain(
module_instance.instance_default.as_ref().map(|ident| InstanceDef {
prefix: String::new(),
instance_struct: ident.clone(),
doc: quote!(#[doc=r"Default module instance"]),
index: 0,
})
);
.chain(module_instance.instance_default.as_ref().map(|ident| InstanceDef {
prefix: String::new(),
instance_struct: ident.clone(),
doc: quote!(#[doc=r"Default module instance"]),
index: 0,
}));
for instance_def in instance_defs {
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def));
@@ -70,8 +68,8 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
let inherent_instance = syn::Ident::new(INHERENT_INSTANCE_NAME, Span::call_site());
// Implementation of inherent instance.
if let Some(default_instance) = def.module_instance.as_ref()
.and_then(|i| i.instance_default.as_ref())
if let Some(default_instance) =
def.module_instance.as_ref().and_then(|i| i.instance_default.as_ref())
{
impls.extend(quote! {
/// Hidden instance generated to be internally used when module is used without
@@ -97,10 +95,7 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
impls
}
fn reexport_instance_trait(
scrate: &TokenStream,
def: &DeclStorageDefExt,
) -> TokenStream {
fn reexport_instance_trait(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream {
if let Some(i) = def.module_instance.as_ref() {
let instance_trait = &i.instance_trait;
quote!(
@@ -17,17 +17,17 @@
//! Implementation of `storage_metadata` on module structure, used by construct_runtime.
use super::{DeclStorageDefExt, StorageLineDefExt, StorageLineTypeDef};
use frame_support_procedural_tools::clean_type_string;
use proc_macro2::TokenStream;
use quote::quote;
use super::{DeclStorageDefExt, StorageLineDefExt, StorageLineTypeDef};
fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> TokenStream {
let value_type = &line.value_type;
let value_type = clean_type_string(&quote!( #value_type ).to_string());
match &line.storage_type {
StorageLineTypeDef::Simple(_) => {
quote!{
quote! {
#scrate::metadata::StorageEntryType::Plain(
#scrate::metadata::DecodeDifferent::Encode(#value_type),
)
@@ -37,7 +37,7 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) ->
let hasher = map.hasher.into_metadata();
let key = &map.key;
let key = clean_type_string(&quote!(#key).to_string());
quote!{
quote! {
#scrate::metadata::StorageEntryType::Map {
hasher: #scrate::metadata::#hasher,
key: #scrate::metadata::DecodeDifferent::Encode(#key),
@@ -53,7 +53,7 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) ->
let key1 = clean_type_string(&quote!(#key1).to_string());
let key2 = &map.key2;
let key2 = clean_type_string(&quote!(#key2).to_string());
quote!{
quote! {
#scrate::metadata::StorageEntryType::DoubleMap {
hasher: #scrate::metadata::#hasher1,
key1: #scrate::metadata::DecodeDifferent::Encode(#key1),
@@ -64,15 +64,17 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) ->
}
},
StorageLineTypeDef::NMap(map) => {
let keys = map.keys
let keys = map
.keys
.iter()
.map(|key| clean_type_string(&quote!(#key).to_string()))
.collect::<Vec<_>>();
let hashers = map.hashers
let hashers = map
.hashers
.iter()
.map(|hasher| hasher.to_storage_hasher_struct())
.collect::<Vec<_>>();
quote!{
quote! {
#scrate::metadata::StorageEntryType::NMap {
keys: #scrate::metadata::DecodeDifferent::Encode(&[
#( #keys, )*
@@ -83,7 +85,7 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) ->
value: #scrate::metadata::DecodeDifferent::Encode(#value_type),
}
}
}
},
}
}
@@ -92,12 +94,17 @@ fn default_byte_getter(
line: &StorageLineDefExt,
def: &DeclStorageDefExt,
) -> (TokenStream, TokenStream) {
let default = line.default_value.as_ref().map(|d| quote!( #d ))
.unwrap_or_else(|| quote!( Default::default() ));
let default = line
.default_value
.as_ref()
.map(|d| quote!( #d ))
.unwrap_or_else(|| quote!(Default::default()));
let str_name = line.name.to_string();
let struct_name = syn::Ident::new(&("__GetByteStruct".to_string() + &str_name), line.name.span());
let cache_name = syn::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), line.name.span());
let struct_name =
syn::Ident::new(&("__GetByteStruct".to_string() + &str_name), line.name.span());
let cache_name =
syn::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), line.name.span());
let runtime_generic = &def.module_runtime_generic;
let runtime_trait = &def.module_runtime_trait;
@@ -177,10 +184,8 @@ pub fn impl_metadata(def: &DeclStorageDefExt) -> TokenStream {
let ty = storage_line_metadata_type(scrate, line);
let (
default_byte_getter_struct_def,
default_byte_getter_struct_instance,
) = default_byte_getter(scrate, line, def);
let (default_byte_getter_struct_def, default_byte_getter_struct_instance) =
default_byte_getter(scrate, line, def);
let mut docs = TokenStream::new();
for attr in line.attrs.iter().filter_map(|v| v.parse_meta().ok()) {
@@ -17,22 +17,22 @@
//! `decl_storage` input definition and expansion.
mod storage_struct;
mod storage_info;
mod parse;
mod store_trait;
mod getters;
mod metadata;
mod instance_trait;
mod genesis_config;
mod getters;
mod instance_trait;
mod metadata;
mod parse;
mod print_pallet_upgrade;
mod storage_info;
mod storage_struct;
mod store_trait;
pub(crate) use instance_trait::INHERENT_INSTANCE_NAME;
use quote::quote;
use frame_support_procedural_tools::{
generate_crate_access, generate_hidden_includes, syn_ext as ext
generate_crate_access, generate_hidden_includes, syn_ext as ext,
};
use quote::quote;
/// All information contained in input of decl_storage
pub struct DeclStorageDef {
@@ -115,34 +115,37 @@ pub struct DeclStorageDefExt {
impl From<DeclStorageDef> for DeclStorageDefExt {
fn from(mut def: DeclStorageDef) -> Self {
let hidden_crate_name = def.hidden_crate.as_ref().map(|i| i.to_string())
let hidden_crate_name = def
.hidden_crate
.as_ref()
.map(|i| i.to_string())
.unwrap_or_else(|| "decl_storage".to_string());
let hidden_crate = generate_crate_access(&hidden_crate_name, "frame-support");
let hidden_imports = generate_hidden_includes(&hidden_crate_name, "frame-support");
let storage_lines = def.storage_lines.drain(..).collect::<Vec<_>>();
let storage_lines = storage_lines.into_iter()
let storage_lines = storage_lines
.into_iter()
.map(|line| StorageLineDefExt::from_def(line, &def, &hidden_crate))
.collect();
let (
optional_instance,
optional_instance_bound,
optional_instance_bound_optional_default,
) = if let Some(instance) = def.module_instance.as_ref() {
let instance_generic = &instance.instance_generic;
let instance_trait= &instance.instance_trait;
let optional_equal_instance_default = instance.instance_default.as_ref()
.map(|d| quote!( = #d ));
(
Some(quote!(#instance_generic)),
Some(quote!(#instance_generic: #instance_trait)),
Some(quote!(#instance_generic: #instance_trait #optional_equal_instance_default)),
)
} else {
(None, None, None)
};
let (optional_instance, optional_instance_bound, optional_instance_bound_optional_default) =
if let Some(instance) = def.module_instance.as_ref() {
let instance_generic = &instance.instance_generic;
let instance_trait = &instance.instance_trait;
let optional_equal_instance_default =
instance.instance_default.as_ref().map(|d| quote!( = #d ));
(
Some(quote!(#instance_generic)),
Some(quote!(#instance_generic: #instance_trait)),
Some(
quote!(#instance_generic: #instance_trait #optional_equal_instance_default),
),
)
} else {
(None, None, None)
};
let module_runtime_generic = &def.module_runtime_generic;
let module_runtime_trait = &def.module_runtime_trait;
@@ -255,22 +258,20 @@ impl StorageLineDefExt {
hidden_crate: &proc_macro2::TokenStream,
) -> Self {
let is_generic = match &storage_def.storage_type {
StorageLineTypeDef::Simple(value) => {
ext::type_contains_ident(&value, &def.module_runtime_generic)
},
StorageLineTypeDef::Map(map) => {
ext::type_contains_ident(&map.key, &def.module_runtime_generic)
|| ext::type_contains_ident(&map.value, &def.module_runtime_generic)
}
StorageLineTypeDef::DoubleMap(map) => {
ext::type_contains_ident(&map.key1, &def.module_runtime_generic)
|| ext::type_contains_ident(&map.key2, &def.module_runtime_generic)
|| ext::type_contains_ident(&map.value, &def.module_runtime_generic)
}
StorageLineTypeDef::NMap(map) => {
map.keys.iter().any(|key| ext::type_contains_ident(key, &def.module_runtime_generic))
|| ext::type_contains_ident(&map.value, &def.module_runtime_generic)
}
StorageLineTypeDef::Simple(value) =>
ext::type_contains_ident(&value, &def.module_runtime_generic),
StorageLineTypeDef::Map(map) =>
ext::type_contains_ident(&map.key, &def.module_runtime_generic) ||
ext::type_contains_ident(&map.value, &def.module_runtime_generic),
StorageLineTypeDef::DoubleMap(map) =>
ext::type_contains_ident(&map.key1, &def.module_runtime_generic) ||
ext::type_contains_ident(&map.key2, &def.module_runtime_generic) ||
ext::type_contains_ident(&map.value, &def.module_runtime_generic),
StorageLineTypeDef::NMap(map) =>
map.keys
.iter()
.any(|key| ext::type_contains_ident(key, &def.module_runtime_generic)) ||
ext::type_contains_ident(&map.value, &def.module_runtime_generic),
};
let query_type = match &storage_def.storage_type {
@@ -280,15 +281,13 @@ impl StorageLineDefExt {
StorageLineTypeDef::NMap(map) => map.value.clone(),
};
let is_option = ext::extract_type_option(&query_type).is_some();
let value_type = ext::extract_type_option(&query_type).unwrap_or_else(|| query_type.clone());
let value_type =
ext::extract_type_option(&query_type).unwrap_or_else(|| query_type.clone());
let module_runtime_generic = &def.module_runtime_generic;
let module_runtime_trait = &def.module_runtime_trait;
let optional_storage_runtime_comma = if is_generic {
Some(quote!( #module_runtime_generic, ))
} else {
None
};
let optional_storage_runtime_comma =
if is_generic { Some(quote!( #module_runtime_generic, )) } else { None };
let optional_storage_runtime_bound_comma = if is_generic {
Some(quote!( #module_runtime_generic: #module_runtime_trait, ))
} else {
@@ -304,11 +303,8 @@ impl StorageLineDefExt {
#storage_name<#optional_storage_runtime_comma #optional_instance_generic>
);
let optional_storage_where_clause = if is_generic {
def.where_clause.as_ref().map(|w| quote!( #w ))
} else {
None
};
let optional_storage_where_clause =
if is_generic { def.where_clause.as_ref().map(|w| quote!( #w )) } else { None };
let storage_trait_truncated = match &storage_def.storage_type {
StorageLineTypeDef::Simple(_) => {
@@ -326,13 +322,15 @@ impl StorageLineDefExt {
StorageLineTypeDef::NMap(map) => {
let keygen = map.to_keygen_struct(hidden_crate);
quote!( StorageNMap<#keygen, #value_type> )
}
},
};
let storage_trait = quote!( storage::#storage_trait_truncated );
let storage_generator_trait = quote!( storage::generator::#storage_trait_truncated );
let doc_attrs = storage_def.attrs.iter()
let doc_attrs = storage_def
.attrs
.iter()
.filter_map(|a| a.parse_meta().ok())
.filter(|m| m.path().is_ident("doc"))
.collect();
@@ -396,27 +394,28 @@ impl NMapDef {
if self.keys.len() == 1 {
let hasher = &self.hashers[0].to_storage_hasher_struct();
let key = &self.keys[0];
return quote!( #scrate::storage::types::Key<#scrate::#hasher, #key> );
return quote!( #scrate::storage::types::Key<#scrate::#hasher, #key> )
}
let key_hasher = self.keys.iter().zip(&self.hashers).map(|(key, hasher)| {
let hasher = hasher.to_storage_hasher_struct();
quote!( #scrate::storage::types::Key<#scrate::#hasher, #key> )
})
.collect::<Vec<_>>();
let key_hasher = self
.keys
.iter()
.zip(&self.hashers)
.map(|(key, hasher)| {
let hasher = hasher.to_storage_hasher_struct();
quote!( #scrate::storage::types::Key<#scrate::#hasher, #key> )
})
.collect::<Vec<_>>();
quote!(( #(#key_hasher,)* ))
}
fn to_key_tuple(&self) -> proc_macro2::TokenStream {
if self.keys.len() == 1 {
let key = &self.keys[0];
return quote!(#key);
return quote!(#key)
}
let tuple = self.keys.iter().map(|key| {
quote!(#key)
})
.collect::<Vec<_>>();
let tuple = self.keys.iter().map(|key| quote!(#key)).collect::<Vec<_>>();
quote!(( #(#tuple,)* ))
}
}
@@ -442,25 +441,25 @@ pub enum HasherKind {
impl HasherKind {
fn to_storage_hasher_struct(&self) -> proc_macro2::TokenStream {
match self {
HasherKind::Blake2_256 => quote!( Blake2_256 ),
HasherKind::Blake2_128 => quote!( Blake2_128 ),
HasherKind::Blake2_128Concat => quote!( Blake2_128Concat ),
HasherKind::Twox256 => quote!( Twox256 ),
HasherKind::Twox128 => quote!( Twox128 ),
HasherKind::Twox64Concat => quote!( Twox64Concat ),
HasherKind::Identity => quote!( Identity ),
HasherKind::Blake2_256 => quote!(Blake2_256),
HasherKind::Blake2_128 => quote!(Blake2_128),
HasherKind::Blake2_128Concat => quote!(Blake2_128Concat),
HasherKind::Twox256 => quote!(Twox256),
HasherKind::Twox128 => quote!(Twox128),
HasherKind::Twox64Concat => quote!(Twox64Concat),
HasherKind::Identity => quote!(Identity),
}
}
fn into_metadata(&self) -> proc_macro2::TokenStream {
match self {
HasherKind::Blake2_256 => quote!( StorageHasher::Blake2_256 ),
HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ),
HasherKind::Blake2_128Concat => quote!( StorageHasher::Blake2_128Concat ),
HasherKind::Twox256 => quote!( StorageHasher::Twox256 ),
HasherKind::Twox128 => quote!( StorageHasher::Twox128 ),
HasherKind::Twox64Concat => quote!( StorageHasher::Twox64Concat ),
HasherKind::Identity => quote!( StorageHasher::Identity ),
HasherKind::Blake2_256 => quote!(StorageHasher::Blake2_256),
HasherKind::Blake2_128 => quote!(StorageHasher::Blake2_128),
HasherKind::Blake2_128Concat => quote!(StorageHasher::Blake2_128Concat),
HasherKind::Twox256 => quote!(StorageHasher::Twox256),
HasherKind::Twox128 => quote!(StorageHasher::Twox128),
HasherKind::Twox64Concat => quote!(StorageHasher::Twox64Concat),
HasherKind::Identity => quote!(StorageHasher::Identity),
}
}
}
@@ -502,5 +501,6 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr
#genesis_config
#storage_struct
#storage_info
).into()
)
.into()
}
@@ -17,8 +17,8 @@
//! Parsing of decl_storage input.
use frame_support_procedural_tools::{ToTokens, Parse, syn_ext as ext};
use syn::{Ident, Token, spanned::Spanned};
use frame_support_procedural_tools::{syn_ext as ext, Parse, ToTokens};
use syn::{spanned::Spanned, Ident, Token};
mod keyword {
syn::custom_keyword!(generate_storage_info);
@@ -367,48 +367,35 @@ fn get_module_instance(
it is now defined at frame_support::traits::Instance. Expect `Instance` found `{}`",
instantiable.as_ref().unwrap(),
);
return Err(syn::Error::new(instantiable.span(), msg));
return Err(syn::Error::new(instantiable.span(), msg))
}
match (instance, instantiable, default_instance) {
(Some(instance), Some(instantiable), default_instance) => {
(Some(instance), Some(instantiable), default_instance) =>
Ok(Some(super::ModuleInstanceDef {
instance_generic: instance,
instance_trait: instantiable,
instance_default: default_instance,
}))
},
})),
(None, None, None) => Ok(None),
(Some(instance), None, _) => Err(
syn::Error::new(
instance.span(),
format!(
"Expect instantiable trait bound for instance: {}. {}",
instance,
right_syntax,
)
)
),
(None, Some(instantiable), _) => Err(
syn::Error::new(
instantiable.span(),
format!(
"Expect instance generic for bound instantiable: {}. {}",
instantiable,
right_syntax,
)
)
),
(None, _, Some(default_instance)) => Err(
syn::Error::new(
default_instance.span(),
format!(
"Expect instance generic for default instance: {}. {}",
default_instance,
right_syntax,
)
)
),
(Some(instance), None, _) => Err(syn::Error::new(
instance.span(),
format!("Expect instantiable trait bound for instance: {}. {}", instance, right_syntax,),
)),
(None, Some(instantiable), _) => Err(syn::Error::new(
instantiable.span(),
format!(
"Expect instance generic for bound instantiable: {}. {}",
instantiable, right_syntax,
),
)),
(None, _, Some(default_instance)) => Err(syn::Error::new(
default_instance.span(),
format!(
"Expect instance generic for default instance: {}. {}",
default_instance, right_syntax,
),
)),
}
}
@@ -417,37 +404,37 @@ pub fn parse(input: syn::parse::ParseStream) -> syn::Result<super::DeclStorageDe
let def = StorageDefinition::parse(input)?;
let module_instance = get_module_instance(
def.mod_instance,
def.mod_instantiable,
def.mod_default_instance,
)?;
let module_instance =
get_module_instance(def.mod_instance, def.mod_instantiable, def.mod_default_instance)?;
let mut extra_genesis_config_lines = vec![];
let mut extra_genesis_build = None;
for line in def.extra_genesis.inner.into_iter()
for line in def
.extra_genesis
.inner
.into_iter()
.flat_map(|o| o.content.content.lines.inner.into_iter())
{
match line {
AddExtraGenesisLineEnum::AddExtraGenesisLine(def) => {
extra_genesis_config_lines.push(super::ExtraGenesisLineDef{
extra_genesis_config_lines.push(super::ExtraGenesisLineDef {
attrs: def.attrs.inner,
name: def.extra_field.content,
typ: def.extra_type,
default: def.default_value.inner.map(|o| o.expr),
});
}
},
AddExtraGenesisLineEnum::AddExtraGenesisBuild(def) => {
if extra_genesis_build.is_some() {
return Err(syn::Error::new(
def.span(),
"Only one build expression allowed for extra genesis"
"Only one build expression allowed for extra genesis",
))
}
extra_genesis_build = Some(def.expr.content);
}
},
}
}
@@ -496,68 +483,65 @@ fn parse_storage_line_defs(
};
if let Some(ref config) = config {
storage_lines.iter().filter_map(|sl| sl.config.as_ref()).try_for_each(|other_config| {
if other_config == config {
Err(syn::Error::new(
config.span(),
"`config()`/`get()` with the same name already defined.",
))
} else {
Ok(())
}
})?;
storage_lines.iter().filter_map(|sl| sl.config.as_ref()).try_for_each(
|other_config| {
if other_config == config {
Err(syn::Error::new(
config.span(),
"`config()`/`get()` with the same name already defined.",
))
} else {
Ok(())
}
},
)?;
}
let max_values = match &line.storage_type {
DeclStorageType::Map(_) | DeclStorageType::DoubleMap(_) | DeclStorageType::NMap(_) => {
line.max_values.inner.map(|i| i.expr.content)
},
DeclStorageType::Simple(_) => {
DeclStorageType::Map(_) | DeclStorageType::DoubleMap(_) | DeclStorageType::NMap(_) =>
line.max_values.inner.map(|i| i.expr.content),
DeclStorageType::Simple(_) =>
if let Some(max_values) = line.max_values.inner {
let msg = "unexpected max_values attribute for storage value.";
let span = max_values.max_values_keyword.span();
return Err(syn::Error::new(span, msg));
return Err(syn::Error::new(span, msg))
} else {
Some(syn::parse_quote!(1u32))
}
},
},
};
let span = line.storage_type.span();
let no_hasher_error = || syn::Error::new(
span,
"Default hasher has been removed, use explicit hasher(blake2_128_concat) instead."
);
let no_hasher_error = || {
syn::Error::new(
span,
"Default hasher has been removed, use explicit hasher(blake2_128_concat) instead.",
)
};
let storage_type = match line.storage_type {
DeclStorageType::Map(map) => super::StorageLineTypeDef::Map(
super::MapDef {
hasher: map.hasher.inner.ok_or_else(no_hasher_error)?.into(),
key: map.key,
value: map.value,
}
),
DeclStorageType::DoubleMap(map) => super::StorageLineTypeDef::DoubleMap(
Box::new(super::DoubleMapDef {
DeclStorageType::Map(map) => super::StorageLineTypeDef::Map(super::MapDef {
hasher: map.hasher.inner.ok_or_else(no_hasher_error)?.into(),
key: map.key,
value: map.value,
}),
DeclStorageType::DoubleMap(map) =>
super::StorageLineTypeDef::DoubleMap(Box::new(super::DoubleMapDef {
hasher1: map.hasher1.inner.ok_or_else(no_hasher_error)?.into(),
hasher2: map.hasher2.inner.ok_or_else(no_hasher_error)?.into(),
key1: map.key1,
key2: map.key2,
value: map.value,
})
),
DeclStorageType::NMap(map) => super::StorageLineTypeDef::NMap(
super::NMapDef {
hashers: map
.storage_keys
.inner
.iter()
.map(|pair| Ok(pair.hasher.inner.clone().ok_or_else(no_hasher_error)?.into()))
.collect::<Result<Vec<_>, syn::Error>>()?,
keys: map.storage_keys.inner.iter().map(|pair| pair.key.clone()).collect(),
value: map.value,
}
),
})),
DeclStorageType::NMap(map) => super::StorageLineTypeDef::NMap(super::NMapDef {
hashers: map
.storage_keys
.inner
.iter()
.map(|pair| Ok(pair.hasher.inner.clone().ok_or_else(no_hasher_error)?.into()))
.collect::<Result<Vec<_>, syn::Error>>()?,
keys: map.storage_keys.inner.iter().map(|pair| pair.key.clone()).collect(),
value: map.value,
}),
DeclStorageType::Simple(expr) => super::StorageLineTypeDef::Simple(expr),
};
@@ -1,6 +1,6 @@
use super::StorageLineTypeDef;
use quote::ToTokens;
use frame_support_procedural_tools::clean_type_string;
use quote::ToTokens;
/// Environment variable that tells us to print pallet upgrade helper.
const PRINT_PALLET_UPGRADE: &str = "PRINT_PALLET_UPGRADE";
@@ -10,7 +10,7 @@ fn check_print_pallet_upgrade() -> bool {
}
/// Convert visibilty as now objects are defined in a module.
fn convert_vis(vis: &syn::Visibility) -> &'static str{
fn convert_vis(vis: &syn::Visibility) -> &'static str {
match vis {
syn::Visibility::Inherited => "pub(super)",
syn::Visibility::Public(_) => "pub",
@@ -31,23 +31,13 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
let scrate = &quote::quote!(frame_support);
let config_gen = if def.optional_instance.is_some() {
"<I: 'static = ()>"
} else {
Default::default()
};
let config_gen =
if def.optional_instance.is_some() { "<I: 'static = ()>" } else { Default::default() };
let impl_gen = if def.optional_instance.is_some() {
"<T: Config<I>, I: 'static>"
} else {
"<T: Config>"
};
let impl_gen =
if def.optional_instance.is_some() { "<T: Config<I>, I: 'static>" } else { "<T: Config>" };
let decl_gen = if def.optional_instance.is_some() {
"<T, I=()>"
} else {
"<T>"
};
let decl_gen = if def.optional_instance.is_some() { "<T, I=()>" } else { "<T>" };
let full_decl_gen = if def.optional_instance.is_some() {
"<T: Config<I>, I: 'static = ()>"
@@ -55,17 +45,9 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
"<T: Config>"
};
let use_gen = if def.optional_instance.is_some() {
"<T, I>"
} else {
"<T>"
};
let use_gen = if def.optional_instance.is_some() { "<T, I>" } else { "<T>" };
let use_gen_tuple = if def.optional_instance.is_some() {
"<(T, I)>"
} else {
"<T>"
};
let use_gen_tuple = if def.optional_instance.is_some() { "<(T, I)>" } else { "<T>" };
let mut genesis_config = String::new();
let mut genesis_build = String::new();
@@ -80,17 +62,11 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
},
};
let genesis_config_impl_gen = if genesis_config_def.is_generic {
impl_gen
} else {
Default::default()
};
let genesis_config_impl_gen =
if genesis_config_def.is_generic { impl_gen } else { Default::default() };
let genesis_config_use_gen = if genesis_config_def.is_generic {
use_gen
} else {
Default::default()
};
let genesis_config_use_gen =
if genesis_config_def.is_generic { use_gen } else { Default::default() };
let genesis_config_decl_gen = if genesis_config_def.is_generic {
if def.optional_instance.is_some() {
@@ -105,26 +81,31 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
let mut genesis_config_decl_fields = String::new();
let mut genesis_config_default_fields = String::new();
for field in &genesis_config_def.fields {
genesis_config_decl_fields.push_str(&format!("
genesis_config_decl_fields.push_str(&format!(
"
{attrs}pub {name}: {typ},",
attrs = field.attrs.iter()
.fold(String::new(), |res, attr| {
format!("{}#[{}]
attrs = field.attrs.iter().fold(String::new(), |res, attr| {
format!(
"{}#[{}]
",
res, attr.to_token_stream())
}),
res,
attr.to_token_stream()
)
}),
name = field.name,
typ = to_cleaned_string(&field.typ),
));
genesis_config_default_fields.push_str(&format!("
genesis_config_default_fields.push_str(&format!(
"
{name}: {default},",
name = field.name,
default = to_cleaned_string(&field.default),
));
}
genesis_config = format!("
genesis_config = format!(
"
#[pallet::genesis_config]
pub struct GenesisConfig{genesis_config_decl_gen}
// TODO_MAYBE_WHERE_CLAUSE
@@ -147,16 +128,18 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
genesis_config_use_gen = genesis_config_use_gen,
);
let genesis_config_build = genesis_config_builder_def.blocks.iter()
.fold(String::new(), |res, block| {
format!("{}
let genesis_config_build =
genesis_config_builder_def.blocks.iter().fold(String::new(), |res, block| {
format!(
"{}
{}",
res,
to_cleaned_string(block),
)
});
genesis_build = format!("
genesis_build = format!(
"
#[pallet::genesis_build]
impl{impl_gen} GenesisBuild{use_gen} for GenesisConfig{genesis_config_use_gen}
// TODO_MAYBE_WHERE_CLAUSE
@@ -176,7 +159,8 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
let storage_vis = convert_vis(&line.visibility);
let getter = if let Some(getter) = &line.getter {
format!("
format!(
"
#[pallet::getter(fn {getter})]",
getter = getter
)
@@ -186,9 +170,12 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
let value_type = &line.value_type;
let default_value_type_value = line.default_value.as_ref()
let default_value_type_value = line
.default_value
.as_ref()
.map(|default_expr| {
format!("
format!(
"
#[pallet::type_value]
{storage_vis} fn DefaultFor{name} /* TODO_MAYBE_GENERICS */ () -> {value_type} {{
{default_expr}
@@ -212,13 +199,16 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
", ValueQuery"
};
let comma_default_value_getter_name = line.default_value.as_ref()
let comma_default_value_getter_name = line
.default_value
.as_ref()
.map(|_| format!(", DefaultFor{}", line.name))
.unwrap_or_else(String::new);
let typ = match &line.storage_type {
StorageLineTypeDef::Map(map) => {
format!("StorageMap<_, {hasher}, {key}, {value_type}{comma_query_kind}\
format!(
"StorageMap<_, {hasher}, {key}, {value_type}{comma_query_kind}\
{comma_default_value_getter_name}>",
hasher = &map.hasher.to_storage_hasher_struct(),
key = to_cleaned_string(&map.key),
@@ -228,7 +218,8 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
)
},
StorageLineTypeDef::DoubleMap(double_map) => {
format!("StorageDoubleMap<_, {hasher1}, {key1}, {hasher2}, {key2}, {value_type}\
format!(
"StorageDoubleMap<_, {hasher1}, {key1}, {hasher2}, {key2}, {value_type}\
{comma_query_kind}{comma_default_value_getter_name}>",
hasher1 = double_map.hasher1.to_storage_hasher_struct(),
key1 = to_cleaned_string(&double_map.key1),
@@ -240,16 +231,18 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
)
},
StorageLineTypeDef::NMap(map) => {
format!("StorageNMap<_, {keygen}, {value_type}{comma_query_kind}\
format!(
"StorageNMap<_, {keygen}, {value_type}{comma_query_kind}\
{comma_default_value_getter_name}>",
keygen = map.to_keygen_struct(&def.hidden_crate),
value_type = to_cleaned_string(&value_type),
comma_query_kind = comma_query_kind,
comma_default_value_getter_name = comma_default_value_getter_name,
)
}
},
StorageLineTypeDef::Simple(_) => {
format!("StorageValue<_, {value_type}{comma_query_kind}\
format!(
"StorageValue<_, {value_type}{comma_query_kind}\
{comma_default_value_getter_name}>",
value_type = to_cleaned_string(&value_type),
comma_query_kind = comma_query_kind,
@@ -265,7 +258,8 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
""
};
storages.push_str(&format!("
storages.push_str(&format!(
"
{default_value_type_value}{doc}
#[pallet::storage]{getter}
{storage_vis} type {name}{full_decl_gen} = {typ};{additional_comment}",
@@ -276,21 +270,21 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
full_decl_gen = full_decl_gen,
typ = typ,
additional_comment = additional_comment,
doc = line.doc_attrs.iter()
.fold(String::new(), |mut res, attr| {
if let syn::Meta::NameValue(name_value) = attr {
if name_value.path.is_ident("doc") {
if let syn::Lit::Str(string) = &name_value.lit {
res = format!("{}
doc = line.doc_attrs.iter().fold(String::new(), |mut res, attr| {
if let syn::Meta::NameValue(name_value) = attr {
if name_value.path.is_ident("doc") {
if let syn::Lit::Str(string) = &name_value.lit {
res = format!(
"{}
///{}",
res,
string.value(),
);
}
res,
string.value(),
);
}
}
res
}),
}
res
}),
));
}
@@ -308,7 +302,8 @@ pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) {
""
};
println!("
println!(
"
// Template for pallet upgrade for {pallet_name}
pub use pallet::*;
@@ -17,9 +17,9 @@
//! Implementation of trait `StorageInfoTrait` on module structure.
use super::DeclStorageDefExt;
use proc_macro2::TokenStream;
use quote::quote;
use super::DeclStorageDefExt;
pub fn impl_storage_info(def: &DeclStorageDefExt) -> TokenStream {
let scrate = &def.hidden_crate;
@@ -17,16 +17,15 @@
//! Implementation of storage structures and implementation of storage traits on them.
use proc_macro2::{TokenStream, Ident, Span};
use super::{instance_trait::INHERENT_INSTANCE_NAME, DeclStorageDefExt, StorageLineTypeDef};
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use super::{
DeclStorageDefExt, StorageLineTypeDef,
instance_trait::INHERENT_INSTANCE_NAME,
};
fn from_optional_value_to_query(is_option: bool, default: &Option<syn::Expr>) -> TokenStream {
let default = default.as_ref().map(|d| quote!( #d ))
.unwrap_or_else(|| quote!( Default::default() ));
let default = default
.as_ref()
.map(|d| quote!( #d ))
.unwrap_or_else(|| quote!(Default::default()));
if !is_option {
// raw type case
@@ -40,10 +39,10 @@ fn from_optional_value_to_query(is_option: bool, default: &Option<syn::Expr>) ->
fn from_query_to_optional_value(is_option: bool) -> TokenStream {
if !is_option {
// raw type case
quote!( Some(v) )
quote!(Some(v))
} else {
// Option<> type case
quote!( v )
quote!(v)
}
}
@@ -52,7 +51,6 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
let mut impls = TokenStream::new();
for line in &def.storage_lines {
// Propagate doc attributes.
let attrs = &line.doc_attrs;
@@ -60,7 +58,8 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
let optional_storage_runtime_comma = &line.optional_storage_runtime_comma;
let optional_storage_runtime_bound_comma = &line.optional_storage_runtime_bound_comma;
let optional_storage_where_clause = &line.optional_storage_where_clause;
let optional_instance_bound_optional_default = &def.optional_instance_bound_optional_default;
let optional_instance_bound_optional_default =
&def.optional_instance_bound_optional_default;
let optional_instance_bound = &def.optional_instance_bound;
let optional_instance = &def.optional_instance;
let name = &line.name;
@@ -87,10 +86,8 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
Ident::new(INHERENT_INSTANCE_NAME, Span::call_site())
};
let storage_name_bstr = syn::LitByteStr::new(
line.name.to_string().as_ref(),
line.name.span()
);
let storage_name_bstr =
syn::LitByteStr::new(line.name.to_string().as_ref(), line.name.span());
let storage_generator_trait = &line.storage_generator_trait;
let storage_struct = &line.storage_struct;
@@ -242,7 +239,7 @@ pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
}
}
)
}
},
};
let max_values = if let Some(max_values) = &line.max_values {
@@ -17,26 +17,26 @@
//! Declaration of store trait and implementation on module structure.
use super::DeclStorageDefExt;
use proc_macro2::TokenStream;
use quote::quote;
use super::DeclStorageDefExt;
pub fn decl_and_impl(def: &DeclStorageDefExt) -> TokenStream {
let decl_store_items = def.storage_lines.iter()
.map(|sline| &sline.name)
.fold(TokenStream::new(), |mut items, name| {
let decl_store_items = def.storage_lines.iter().map(|sline| &sline.name).fold(
TokenStream::new(),
|mut items, name| {
items.extend(quote!(type #name;));
items
});
},
);
let impl_store_items = def.storage_lines.iter()
.fold(TokenStream::new(), |mut items, line| {
let name = &line.name;
let storage_struct = &line.storage_struct;
let impl_store_items = def.storage_lines.iter().fold(TokenStream::new(), |mut items, line| {
let name = &line.name;
let storage_struct = &line.storage_struct;
items.extend(quote!(type #name = #storage_struct;));
items
});
items.extend(quote!(type #name = #storage_struct;));
items
});
let visibility = &def.visibility;
let store_trait = &def.store_trait;
@@ -15,10 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use frame_support_procedural_tools::generate_crate_access_2018;
use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemFn, Result};
use frame_support_procedural_tools::generate_crate_access_2018;
pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result<TokenStream> {
let ItemFn { attrs, vis, sig, block } = syn::parse(input)?;