mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-20 14:01:02 +00:00
Macros to use path instead of ident (#1474)
This commit is contained in:
@@ -92,7 +92,7 @@ impl CompositeDef {
|
||||
pub fn try_from(
|
||||
attr_span: proc_macro2::Span,
|
||||
index: usize,
|
||||
scrate: &proc_macro2::Ident,
|
||||
scrate: &syn::Path,
|
||||
item: &mut syn::Item,
|
||||
) -> syn::Result<Self> {
|
||||
let item = if let syn::Item::Enum(item) = item {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use super::helper;
|
||||
use frame_support_procedural_tools::get_doc_literals;
|
||||
use frame_support_procedural_tools::{get_doc_literals, is_using_frame_crate};
|
||||
use quote::ToTokens;
|
||||
use syn::{spanned::Spanned, token, Token};
|
||||
|
||||
@@ -165,24 +165,8 @@ pub struct PalletAttr {
|
||||
typ: PalletAttrType,
|
||||
}
|
||||
|
||||
pub struct ConfigBoundParse(syn::Ident);
|
||||
|
||||
impl syn::parse::Parse for ConfigBoundParse {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let ident = input.parse::<syn::Ident>()?;
|
||||
input.parse::<syn::Token![::]>()?;
|
||||
input.parse::<keyword::Config>()?;
|
||||
|
||||
if input.peek(syn::token::Lt) {
|
||||
input.parse::<syn::AngleBracketedGenericArguments>()?;
|
||||
}
|
||||
|
||||
Ok(Self(ident))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse for `IsType<<Sef as $ident::Config>::RuntimeEvent>` and retrieve `$ident`
|
||||
pub struct IsTypeBoundEventParse(syn::Ident);
|
||||
/// Parse for `IsType<<Self as $path>::RuntimeEvent>` and retrieve `$path`
|
||||
pub struct IsTypeBoundEventParse(syn::Path);
|
||||
|
||||
impl syn::parse::Parse for IsTypeBoundEventParse {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
@@ -191,15 +175,13 @@ impl syn::parse::Parse for IsTypeBoundEventParse {
|
||||
input.parse::<syn::Token![<]>()?;
|
||||
input.parse::<syn::Token![Self]>()?;
|
||||
input.parse::<syn::Token![as]>()?;
|
||||
let ident = input.parse::<syn::Ident>()?;
|
||||
input.parse::<syn::Token![::]>()?;
|
||||
input.parse::<keyword::Config>()?;
|
||||
let config_path = input.parse::<syn::Path>()?;
|
||||
input.parse::<syn::Token![>]>()?;
|
||||
input.parse::<syn::Token![::]>()?;
|
||||
input.parse::<keyword::RuntimeEvent>()?;
|
||||
input.parse::<syn::Token![>]>()?;
|
||||
|
||||
Ok(Self(ident))
|
||||
Ok(Self(config_path))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +219,7 @@ impl syn::parse::Parse for FromEventParse {
|
||||
/// Check if trait_item is `type RuntimeEvent`, if so checks its bounds are those expected.
|
||||
/// (Event type is reserved type)
|
||||
fn check_event_type(
|
||||
frame_system: &syn::Ident,
|
||||
frame_system: &syn::Path,
|
||||
trait_item: &syn::TraitItem,
|
||||
trait_has_instance: bool,
|
||||
) -> syn::Result<bool> {
|
||||
@@ -249,19 +231,16 @@ fn check_event_type(
|
||||
no generics nor where_clause";
|
||||
return Err(syn::Error::new(trait_item.span(), msg))
|
||||
}
|
||||
// Check bound contains IsType and From
|
||||
|
||||
// Check bound contains IsType and From
|
||||
let has_is_type_bound = type_.bounds.iter().any(|s| {
|
||||
syn::parse2::<IsTypeBoundEventParse>(s.to_token_stream())
|
||||
.map_or(false, |b| b.0 == *frame_system)
|
||||
.map_or(false, |b| has_expected_system_config(b.0, frame_system))
|
||||
});
|
||||
|
||||
if !has_is_type_bound {
|
||||
let msg = format!(
|
||||
"Invalid `type RuntimeEvent`, associated type `RuntimeEvent` is reserved and must \
|
||||
bound: `IsType<<Self as {}::Config>::RuntimeEvent>`",
|
||||
frame_system,
|
||||
);
|
||||
let msg = "Invalid `type RuntimeEvent`, associated type `RuntimeEvent` is reserved and must \
|
||||
bound: `IsType<<Self as frame_system::Config>::RuntimeEvent>`".to_string();
|
||||
return Err(syn::Error::new(type_.span(), msg))
|
||||
}
|
||||
|
||||
@@ -295,6 +274,43 @@ fn check_event_type(
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the path to `frame_system::Config` is valid, this is that the path is just
|
||||
/// `frame_system::Config` or when using the `frame` crate it is `frame::xyz::frame_system::Config`.
|
||||
fn has_expected_system_config(path: syn::Path, frame_system: &syn::Path) -> bool {
|
||||
// Check if `frame_system` is actually 'frame_system'.
|
||||
if path.segments.iter().all(|s| s.ident != "frame_system") {
|
||||
return false
|
||||
}
|
||||
|
||||
let mut expected_system_config =
|
||||
match (is_using_frame_crate(&path), is_using_frame_crate(&frame_system)) {
|
||||
(true, false) =>
|
||||
// We can't use the path to `frame_system` from `frame` if `frame_system` is not being
|
||||
// in scope through `frame`.
|
||||
return false,
|
||||
(false, true) =>
|
||||
// We know that the only valid frame_system path is one that is `frame_system`, as
|
||||
// `frame` re-exports it as such.
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame_system)).expect("is a valid path; qed"),
|
||||
(_, _) =>
|
||||
// They are either both `frame_system` or both `frame::xyz::frame_system`.
|
||||
frame_system.clone(),
|
||||
};
|
||||
|
||||
expected_system_config
|
||||
.segments
|
||||
.push(syn::PathSegment::from(syn::Ident::new("Config", path.span())));
|
||||
|
||||
// the parse path might be something like `frame_system::Config<...>`, so we
|
||||
// only compare the idents along the path.
|
||||
expected_system_config
|
||||
.segments
|
||||
.into_iter()
|
||||
.map(|ps| ps.ident)
|
||||
.collect::<Vec<_>>() ==
|
||||
path.segments.into_iter().map(|ps| ps.ident).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
/// Replace ident `Self` by `T`
|
||||
pub fn replace_self_by_t(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
|
||||
input
|
||||
@@ -311,7 +327,7 @@ pub fn replace_self_by_t(input: proc_macro2::TokenStream) -> proc_macro2::TokenS
|
||||
|
||||
impl ConfigDef {
|
||||
pub fn try_from(
|
||||
frame_system: &syn::Ident,
|
||||
frame_system: &syn::Path,
|
||||
attr_span: proc_macro2::Span,
|
||||
index: usize,
|
||||
item: &mut syn::Item,
|
||||
@@ -352,8 +368,8 @@ impl ConfigDef {
|
||||
};
|
||||
|
||||
let has_frame_system_supertrait = item.supertraits.iter().any(|s| {
|
||||
syn::parse2::<ConfigBoundParse>(s.to_token_stream())
|
||||
.map_or(false, |b| b.0 == *frame_system)
|
||||
syn::parse2::<syn::Path>(s.to_token_stream())
|
||||
.map_or(false, |b| has_expected_system_config(b, frame_system))
|
||||
});
|
||||
|
||||
let mut has_event_type = false;
|
||||
@@ -461,7 +477,8 @@ 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.to_token_stream(),
|
||||
found,
|
||||
);
|
||||
return Err(syn::Error::new(item.span(), msg))
|
||||
}
|
||||
@@ -477,3 +494,97 @@ impl ConfigDef {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn has_expected_system_config_works() {
|
||||
let frame_system = syn::parse2::<syn::Path>(quote::quote!(frame_system)).unwrap();
|
||||
let path = syn::parse2::<syn::Path>(quote::quote!(frame_system::Config)).unwrap();
|
||||
assert!(has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_works_with_assoc_type() {
|
||||
let frame_system = syn::parse2::<syn::Path>(quote::quote!(frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame_system::Config<RuntimeCall = Call>))
|
||||
.unwrap();
|
||||
assert!(has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_works_with_frame() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system)).unwrap();
|
||||
let path = syn::parse2::<syn::Path>(quote::quote!(frame_system::Config)).unwrap();
|
||||
assert!(has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_works_with_frame_full_path() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system::Config)).unwrap();
|
||||
assert!(has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_works_with_other_frame_full_path() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::xyz::frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::xyz::frame_system::Config)).unwrap();
|
||||
assert!(has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_does_not_works_with_mixed_frame_full_path() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::xyz::frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system::Config)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_does_not_works_with_other_mixed_frame_full_path() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::xyz::frame_system::Config)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_does_not_work_with_frame_full_path_if_not_frame_crate() {
|
||||
let frame_system = syn::parse2::<syn::Path>(quote::quote!(frame_system)).unwrap();
|
||||
let path =
|
||||
syn::parse2::<syn::Path>(quote::quote!(frame::deps::frame_system::Config)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_unexpected_frame_system() {
|
||||
let frame_system =
|
||||
syn::parse2::<syn::Path>(quote::quote!(framez::deps::frame_system)).unwrap();
|
||||
let path = syn::parse2::<syn::Path>(quote::quote!(frame_system::Config)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_unexpected_path() {
|
||||
let frame_system = syn::parse2::<syn::Path>(quote::quote!(frame_system)).unwrap();
|
||||
let path = syn::parse2::<syn::Path>(quote::quote!(frame_system::ConfigSystem)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_expected_system_config_not_frame_system() {
|
||||
let frame_system = syn::parse2::<syn::Path>(quote::quote!(something)).unwrap();
|
||||
let path = syn::parse2::<syn::Path>(quote::quote!(something::Config)).unwrap();
|
||||
assert!(!has_expected_system_config(path, &frame_system));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ pub mod type_value;
|
||||
pub mod validate_unsigned;
|
||||
|
||||
use composite::{keyword::CompositeKeyword, CompositeDef};
|
||||
use frame_support_procedural_tools::generate_crate_access_2018;
|
||||
use frame_support_procedural_tools::generate_access_from_frame_or_crate;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
/// Parsed definition of a pallet.
|
||||
@@ -60,15 +60,15 @@ pub struct Def {
|
||||
pub extra_constants: Option<extra_constants::ExtraConstantsDef>,
|
||||
pub composites: Vec<composite::CompositeDef>,
|
||||
pub type_values: Vec<type_value::TypeValueDef>,
|
||||
pub frame_system: syn::Ident,
|
||||
pub frame_support: syn::Ident,
|
||||
pub frame_system: syn::Path,
|
||||
pub frame_support: syn::Path,
|
||||
pub dev_mode: bool,
|
||||
}
|
||||
|
||||
impl Def {
|
||||
pub fn try_from(mut item: syn::ItemMod, dev_mode: bool) -> syn::Result<Self> {
|
||||
let frame_system = generate_crate_access_2018("frame-system")?;
|
||||
let frame_support = generate_crate_access_2018("frame-support")?;
|
||||
let frame_system = generate_access_from_frame_or_crate("frame-system")?;
|
||||
let frame_support = generate_access_from_frame_or_crate("frame-support")?;
|
||||
|
||||
let item_span = item.span();
|
||||
let items = &mut item
|
||||
|
||||
Reference in New Issue
Block a user