mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 20:47:56 +00:00
Allow usage of path in construct_runtime! (#8801)
* Allow usage of path in construct_runtime! * Fix whitespace * Fix whitespace * Make expand_runtime_metadata accept slice instead of Iterator * Include Call and Event in construct_runtime for testing * Migrate impl_outer_event to proc macro * Fix integrity_test_works * Update UI test expectations * Factor in module path while generating enum variant or fn names * Use ParseStream::lookahead for more helpful error messages * Remove generating outer_event_metadata * Ensure pallets with different paths but same last path segment can coexist * Remove unnecessary generated function * Migrate decl_outer_config to proc macro * Add default_filter test for expand_outer_origin * Allow crate, self and super keywords to appear in pallet path * Add UI test for specifying empty pallet paths in construct_runtime
This commit is contained in:
@@ -16,12 +16,14 @@
|
||||
// limitations under the License.
|
||||
|
||||
use frame_support_procedural_tools::syn_ext as ext;
|
||||
use proc_macro2::Span;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use std::collections::HashSet;
|
||||
use syn::{
|
||||
ext::IdentExt,
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token, Error, Ident, Result, Token,
|
||||
token, Error, Ident, Path, PathArguments, PathSegment, Result, Token,
|
||||
};
|
||||
|
||||
mod keyword {
|
||||
@@ -154,7 +156,7 @@ pub struct PalletDeclaration {
|
||||
pub name: Ident,
|
||||
/// Optional fixed index (e.g. `MyPallet ... = 3,`)
|
||||
pub index: Option<u8>,
|
||||
pub pallet: Ident,
|
||||
pub pallet: PalletPath,
|
||||
pub instance: Option<Ident>,
|
||||
pub pallet_parts: Vec<PalletPart>,
|
||||
}
|
||||
@@ -164,17 +166,16 @@ impl Parse for PalletDeclaration {
|
||||
let name = input.parse()?;
|
||||
let _: Token![:] = input.parse()?;
|
||||
let pallet = input.parse()?;
|
||||
let instance = if input.peek(Token![::]) && input.peek3(Token![<]) {
|
||||
let _: Token![::] = input.parse()?;
|
||||
let instance = if input.peek(Token![<]) {
|
||||
let _: Token![<] = input.parse()?;
|
||||
let res = Some(input.parse()?);
|
||||
let _: Token![>] = input.parse()?;
|
||||
let _: Token![::] = input.parse()?;
|
||||
res
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let _: Token![::] = input.parse()?;
|
||||
let pallet_parts = parse_pallet_parts(input)?;
|
||||
|
||||
let index = if input.peek(Token![=]) {
|
||||
@@ -198,6 +199,84 @@ impl Parse for PalletDeclaration {
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct representing a path to a pallet. `PalletPath` is almost identical to the standard
|
||||
/// Rust path with a few restrictions:
|
||||
/// - No leading colons allowed
|
||||
/// - Path segments can only consist of identifers; angle-bracketed or parenthesized segments will
|
||||
/// result in a parsing error (except when specifying instances)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PalletPath {
|
||||
pub inner: Path,
|
||||
}
|
||||
|
||||
impl Parse for PalletPath {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
while lookahead.peek(Ident) {
|
||||
let ident = input.parse()?;
|
||||
segments.push(PathSegment { ident, arguments: PathArguments::None });
|
||||
let _: Token![::] = input.parse()?;
|
||||
lookahead = input.lookahead1();
|
||||
}
|
||||
|
||||
if !lookahead.peek(token::Brace) && !lookahead.peek(Token![<]) {
|
||||
return Err(lookahead.error());
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
inner: Path {
|
||||
leading_colon: None,
|
||||
segments,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PalletPath {
|
||||
/// Return the snake-cased module name for this path.
|
||||
pub fn mod_name(&self) -> Ident {
|
||||
let mut iter = self.inner.segments.iter();
|
||||
let mut mod_name = match &iter.next().expect("Path should always have 1 segment; qed").ident {
|
||||
ident if ident == "self" || ident == "super" || ident == "crate" => {
|
||||
// Skip `crate`, `self` and `super` quasi-keywords when creating the module name
|
||||
iter.next()
|
||||
.expect("There must be a path segment pointing to a pallet following \
|
||||
`crate`, `self` or `super`; qed")
|
||||
.ident
|
||||
.clone()
|
||||
}
|
||||
ident => ident.clone(),
|
||||
};
|
||||
|
||||
for segment in iter {
|
||||
mod_name = quote::format_ident!("{}_{}", mod_name, segment.ident);
|
||||
}
|
||||
|
||||
mod_name
|
||||
}
|
||||
}
|
||||
|
||||
impl quote::ToTokens for PalletPath {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
self.inner.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse [`PalletPart`]'s from a braces enclosed list that is split by commas, e.g.
|
||||
///
|
||||
/// `{ Call, Event }`
|
||||
@@ -271,11 +350,6 @@ impl PalletPartKeyword {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name as `Ident`.
|
||||
fn ident(&self) -> Ident {
|
||||
Ident::new(self.name(), self.span())
|
||||
}
|
||||
|
||||
/// Returns `true` if this pallet part is allowed to have generic arguments.
|
||||
fn allows_generic(&self) -> bool {
|
||||
Self::all_generic_arg().iter().any(|n| *n == self.name())
|
||||
@@ -341,11 +415,6 @@ impl PalletPart {
|
||||
pub fn name(&self) -> &'static str {
|
||||
self.keyword.name()
|
||||
}
|
||||
|
||||
/// The name of this pallet part as `Ident`.
|
||||
pub fn ident(&self) -> Ident {
|
||||
self.keyword.ident()
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_kind(
|
||||
|
||||
Reference in New Issue
Block a user