Globally upgrade to syn 2.x and latest quote and proc_macro2 1x versions (#13846)

* globally upgrade quote to latest 1.0.x (1.0.26)

* globally upgrade syn to final 1.0.x version (1.0.109)

* globally upgrade proc-macro2 to 1.0.56

* upgrade to syn v2.0.13 and fix everything except NestedMeta

* fix parse nested metadata code in decl_runtime_apis.rs

* Port more stuff to syn 2.0

* Make the rest compile

* Ignore error

* update to syn 2.0.14

---------

Co-authored-by: Bastian Köcher <info@kchr.de>
This commit is contained in:
Sam Johnson
2023-04-12 14:42:22 -04:00
committed by GitHub
parent 03c99fe003
commit b83bf4784e
62 changed files with 402 additions and 478 deletions
@@ -188,7 +188,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
.map(|c| &mut def.item.content.as_mut().expect("Checked by def parser").1[c.index])
{
item_impl.items.iter_mut().for_each(|i| {
if let syn::ImplItem::Method(method) = i {
if let syn::ImplItem::Fn(method) = i {
let block = &method.block;
method.block = syn::parse_quote! {{
// We execute all dispatchable in a new storage layer, allowing them
@@ -206,13 +206,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
method
.attrs
.iter()
.find(|attr| {
if let Ok(syn::Meta::List(syn::MetaList { path, .. })) = attr.parse_meta() {
path.segments.last().map(|seg| seg.ident == "allow").unwrap_or(false)
} else {
false
}
})
.find(|attr| attr.path().is_ident("allow"))
.map_or(proc_macro2::TokenStream::new(), |attr| attr.to_token_stream())
})
.collect::<Vec<_>>();
@@ -23,7 +23,7 @@ struct ConstDef {
/// The type in Get, e.g. `u32` in `type Foo: Get<u32>;`, but `Self` is replaced by `T`
pub type_: syn::Type,
/// The doc associated
pub doc: Vec<syn::Lit>,
pub doc: Vec<syn::Expr>,
/// default_byte implementation
pub default_byte_impl: proc_macro2::TokenStream,
/// Constant name for Metadata (optional)
@@ -16,54 +16,24 @@
// limitations under the License.
use crate::pallet::Def;
use derive_syn_parse::Parse;
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::{
parse::{self, Parse, ParseStream},
spanned::Spanned,
Attribute, Lit,
};
use syn::{spanned::Spanned, Attribute, Lit, LitStr};
const DOC: &'static str = "doc";
const PALLET_DOC: &'static str = "pallet_doc";
mod keywords {
syn::custom_keyword!(include_str);
}
/// Get the documentation file path from the `pallet_doc` attribute.
///
/// Supported format:
/// `#[pallet_doc(PATH)]`: The path of the file from which the documentation is loaded
fn parse_pallet_doc_value(attr: &Attribute) -> syn::Result<DocMetaValue> {
let span = attr.span();
let lit: syn::LitStr = attr.parse_args().map_err(|_| {
let msg = "The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc(\"PATH\")`";
syn::Error::new(attr.span(), msg)
})?;
let meta = attr.parse_meta()?;
let syn::Meta::List(metalist) = meta else {
let msg = "The `pallet_doc` attribute must receive arguments as a list. Supported format: `pallet_doc(PATH)`";
return Err(syn::Error::new(span, msg))
};
let paths: Vec<_> = metalist
.nested
.into_iter()
.map(|nested| {
let syn::NestedMeta::Lit(lit) = nested else {
let msg = "The `pallet_doc` received an unsupported argument. Supported format: `pallet_doc(PATH)`";
return Err(syn::Error::new(span, msg))
};
Ok(lit)
})
.collect::<syn::Result<_>>()?;
if paths.len() != 1 {
let msg = "The `pallet_doc` attribute must receive only one argument. Supported format: `pallet_doc(PATH)`";
return Err(syn::Error::new(span, msg))
}
Ok(DocMetaValue::Path(paths[0].clone()))
Ok(DocMetaValue::Path(lit))
}
/// Get the value from the `doc` comment attribute:
@@ -71,47 +41,22 @@ fn parse_pallet_doc_value(attr: &Attribute) -> syn::Result<DocMetaValue> {
/// Supported formats:
/// - `#[doc = "A doc string"]`: Documentation as a string literal
/// - `#[doc = include_str!(PATH)]`: Documentation obtained from a path
fn parse_doc_value(attr: &Attribute) -> Option<DocMetaValue> {
let Some(ident) = attr.path.get_ident() else {
return None
};
if ident != DOC {
return None
fn parse_doc_value(attr: &Attribute) -> syn::Result<Option<DocMetaValue>> {
if !attr.path().is_ident(DOC) {
return Ok(None)
}
let parser = |input: ParseStream| DocParser::parse(input);
let result = parse::Parser::parse2(parser, attr.tokens.clone()).ok()?;
let meta = attr.meta.require_name_value()?;
if let Some(lit) = result.lit {
Some(DocMetaValue::Lit(lit))
} else if let Some(include_doc) = result.include_doc {
Some(DocMetaValue::Path(include_doc.lit))
} else {
None
match &meta.value {
syn::Expr::Lit(lit) => Ok(Some(DocMetaValue::Lit(lit.lit.clone()))),
syn::Expr::Macro(mac) if mac.mac.path.is_ident("include_str") =>
Ok(Some(DocMetaValue::Path(mac.mac.parse_body()?))),
_ =>
Err(syn::Error::new(attr.span(), "Expected `= \"docs\"` or `= include_str!(\"PATH\")`")),
}
}
/// Parse the include_str attribute.
#[derive(Debug, Parse)]
struct IncludeDocParser {
_include_str: keywords::include_str,
_eq_token: syn::token::Bang,
#[paren]
_paren: syn::token::Paren,
#[inside(_paren)]
lit: Lit,
}
/// Parse the doc literal.
#[derive(Debug, Parse)]
struct DocParser {
_eq_token: syn::token::Eq,
#[peek(Lit)]
lit: Option<Lit>,
#[parse_if(lit.is_none())]
include_doc: Option<IncludeDocParser>,
}
/// Supported documentation tokens.
#[derive(Debug)]
enum DocMetaValue {
@@ -124,7 +69,7 @@ enum DocMetaValue {
/// The string literal represents the file `PATH`.
///
/// `#[doc = include_str!(PATH)]`
Path(Lit),
Path(LitStr),
}
impl ToTokens for DocMetaValue {
@@ -179,33 +124,39 @@ pub fn expand_documentation(def: &mut Def) -> proc_macro2::TokenStream {
let mut index = 0;
while index < def.item.attrs.len() {
let attr = &def.item.attrs[index];
if let Some(ident) = attr.path.get_ident() {
if ident == PALLET_DOC {
let elem = def.item.attrs.remove(index);
pallet_docs.push(elem);
// Do not increment the index, we have just removed the
// element from the attributes.
continue
}
if attr.path().get_ident().map_or(false, |i| *i == PALLET_DOC) {
pallet_docs.push(def.item.attrs.remove(index));
// Do not increment the index, we have just removed the
// element from the attributes.
continue
}
index += 1;
}
// Capture the `#[doc = include_str!("../README.md")]` and `#[doc = "Documentation"]`.
let mut docs: Vec<_> = def.item.attrs.iter().filter_map(parse_doc_value).collect();
let docs = match def
.item
.attrs
.iter()
.filter_map(|v| parse_doc_value(v).transpose())
.collect::<syn::Result<Vec<_>>>()
{
Ok(r) => r,
Err(err) => return err.into_compile_error(),
};
// Capture the `#[pallet_doc("../README.md")]`.
let pallet_docs: Vec<_> = match pallet_docs
let pallet_docs = match pallet_docs
.into_iter()
.map(|attr| parse_pallet_doc_value(&attr))
.collect::<syn::Result<_>>()
.collect::<syn::Result<Vec<_>>>()
{
Ok(docs) => docs,
Err(err) => return err.into_compile_error(),
};
docs.extend(pallet_docs);
let docs = docs.iter().chain(pallet_docs.iter());
quote::quote!(
impl<#type_impl_gen> #pallet_ident<#type_use_gen> #where_clauses{
@@ -384,10 +384,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
Option<#value>
),
QueryKind::ResultQuery(error_path, _) =>
QueryKind::ResultQuery(error_path, _) => {
quote::quote_spanned!(storage.attr_span =>
Result<#value, #error_path>
),
)
},
QueryKind::ValueQuery => quote::quote!(#value),
};
quote::quote_spanned!(storage.attr_span =>
@@ -407,10 +408,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
Option<#value>
),
QueryKind::ResultQuery(error_path, _) =>
QueryKind::ResultQuery(error_path, _) => {
quote::quote_spanned!(storage.attr_span =>
Result<#value, #error_path>
),
)
},
QueryKind::ValueQuery => quote::quote!(#value),
};
quote::quote_spanned!(storage.attr_span =>
@@ -432,10 +434,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
Option<#value>
),
QueryKind::ResultQuery(error_path, _) =>
QueryKind::ResultQuery(error_path, _) => {
quote::quote_spanned!(storage.attr_span =>
Result<#value, #error_path>
),
)
},
QueryKind::ValueQuery => quote::quote!(#value),
};
quote::quote_spanned!(storage.attr_span =>
@@ -457,10 +460,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
Option<#value>
),
QueryKind::ResultQuery(error_path, _) =>
QueryKind::ResultQuery(error_path, _) => {
quote::quote_spanned!(storage.attr_span =>
Result<#value, #error_path>
),
)
},
QueryKind::ValueQuery => quote::quote!(#value),
};
quote::quote_spanned!(storage.attr_span =>
@@ -484,10 +488,11 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
QueryKind::OptionQuery => quote::quote_spanned!(storage.attr_span =>
Option<#value>
),
QueryKind::ResultQuery(error_path, _) =>
QueryKind::ResultQuery(error_path, _) => {
quote::quote_spanned!(storage.attr_span =>
Result<#value, #error_path>
),
)
},
QueryKind::ValueQuery => quote::quote!(#value),
};
quote::quote_spanned!(storage.attr_span =>
@@ -45,7 +45,7 @@ pub struct CallDef {
/// The span of the pallet::call attribute.
pub attr_span: proc_macro2::Span,
/// Docs, specified on the impl Block.
pub docs: Vec<syn::Lit>,
pub docs: Vec<syn::Expr>,
}
/// Definition of dispatchable typically: `#[weight...] fn foo(origin .., param1: ...) -> ..`
@@ -62,7 +62,7 @@ pub struct CallVariantDef {
/// Whether an explicit call index was specified.
pub explicit_call_index: bool,
/// Docs, used for metadata.
pub docs: Vec<syn::Lit>,
pub docs: Vec<syn::Expr>,
/// Attributes annotated at the top of the dispatchable function.
pub attrs: Vec<syn::Attribute>,
}
@@ -173,7 +173,7 @@ impl CallDef {
let mut indices = HashMap::new();
let mut last_index: Option<u8> = None;
for item in &mut item_impl.items {
if let syn::ImplItem::Method(method) = item {
if let syn::ImplItem::Fn(method) = item {
if !matches!(method.vis, syn::Visibility::Public(_)) {
let msg = "Invalid pallet::call, dispatchable function must be public: \
`pub fn`";
@@ -32,14 +32,14 @@ pub mod keyword {
SlashReason(SlashReason),
}
impl Spanned for CompositeKeyword {
fn span(&self) -> proc_macro2::Span {
impl ToTokens for CompositeKeyword {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
use CompositeKeyword::*;
match self {
FreezeReason(inner) => inner.span(),
HoldReason(inner) => inner.span(),
LockId(inner) => inner.span(),
SlashReason(inner) => inner.span(),
FreezeReason(inner) => inner.to_tokens(tokens),
HoldReason(inner) => inner.to_tokens(tokens),
LockId(inner) => inner.to_tokens(tokens),
SlashReason(inner) => inner.to_tokens(tokens),
}
}
}
@@ -109,14 +109,11 @@ impl CompositeDef {
}
let has_derive_attr = item.attrs.iter().any(|attr| {
attr.parse_meta()
.ok()
.map(|meta| match meta {
syn::Meta::List(syn::MetaList { path, .. }) =>
path.get_ident().map(|ident| ident == "derive").unwrap_or(false),
_ => false,
})
.unwrap_or(false)
if let syn::Meta::List(syn::MetaList { path, .. }) = &attr.meta {
path.get_ident().map(|ident| ident == "derive").unwrap_or(false)
} else {
false
}
});
if !has_derive_attr {
@@ -61,7 +61,7 @@ pub struct ConstMetadataDef {
/// The type in Get, e.g. `u32` in `type Foo: Get<u32>;`, but `Self` is replaced by `T`
pub type_: syn::Type,
/// The doc associated
pub doc: Vec<syn::Lit>,
pub doc: Vec<syn::Expr>,
}
impl TryFrom<&syn::TraitItemType> for ConstMetadataDef {
@@ -124,23 +124,35 @@ impl syn::parse::Parse for DisableFrameSystemSupertraitCheck {
}
/// Parse for `#[pallet::constant]`
pub struct TypeAttrConst(proc_macro2::Span);
impl Spanned for TypeAttrConst {
fn span(&self) -> proc_macro2::Span {
self.0
}
pub struct TypeAttrConst {
pound_token: syn::Token![#],
bracket_token: syn::token::Bracket,
pallet_ident: syn::Ident,
path_sep_token: syn::token::PathSep,
constant_keyword: keyword::constant,
}
impl syn::parse::Parse for TypeAttrConst {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
input.parse::<syn::Token![#]>()?;
let pound_token = input.parse::<syn::Token![#]>()?;
let content;
syn::bracketed!(content in input);
content.parse::<syn::Ident>()?;
content.parse::<syn::Token![::]>()?;
let bracket_token = syn::bracketed!(content in input);
let pallet_ident = content.parse::<syn::Ident>()?;
let path_sep_token = content.parse::<syn::Token![::]>()?;
let constant_keyword = content.parse::<keyword::constant>()?;
Ok(TypeAttrConst(content.parse::<keyword::constant>()?.span()))
Ok(Self { pound_token, bracket_token, pallet_ident, path_sep_token, constant_keyword })
}
}
impl ToTokens for TypeAttrConst {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.pound_token.to_tokens(tokens);
self.bracket_token.surround(tokens, |tokens| {
self.pallet_ident.to_tokens(tokens);
self.path_sep_token.to_tokens(tokens);
self.constant_keyword.to_tokens(tokens);
})
}
}
@@ -37,7 +37,7 @@ pub struct ErrorDef {
/// The index of error item in pallet module.
pub index: usize,
/// Variants ident, optional field and doc literals (ordered as declaration order)
pub variants: Vec<(syn::Ident, Option<VariantField>, Vec<syn::Lit>)>,
pub variants: Vec<(syn::Ident, Option<VariantField>, Vec<syn::Expr>)>,
/// A set of usage of instance, must be check for consistency with trait.
pub instances: Vec<helper::InstanceUsage>,
/// The keyword error used (contains span).
@@ -50,7 +50,7 @@ pub struct ExtraConstantDef {
/// The type returned by the function
pub type_: syn::Type,
/// The doc associated
pub doc: Vec<syn::Lit>,
pub doc: Vec<syn::Expr>,
/// Optional MetaData Name
pub metadata_name: Option<syn::Ident>,
}
@@ -100,7 +100,7 @@ impl ExtraConstantsDef {
let mut extra_constants = vec![];
for impl_item in &mut item.items {
let method = if let syn::ImplItem::Method(method) = impl_item {
let method = if let syn::ImplItem::Fn(method) = impl_item {
method
} else {
let msg = "Invalid pallet::call, only method accepted";
@@ -54,7 +54,7 @@ where
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")
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())?))
@@ -82,7 +82,7 @@ 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") {
if attr.path().segments.first().map_or(false, |segment| segment.ident == "cfg") {
Some(attr.clone())
} else {
None
@@ -101,7 +101,6 @@ impl MutItemAttrs for syn::Item {
Self::ForeignMod(item) => Some(item.attrs.as_mut()),
Self::Impl(item) => Some(item.attrs.as_mut()),
Self::Macro(item) => Some(item.attrs.as_mut()),
Self::Macro2(item) => Some(item.attrs.as_mut()),
Self::Mod(item) => Some(item.attrs.as_mut()),
Self::Static(item) => Some(item.attrs.as_mut()),
Self::Struct(item) => Some(item.attrs.as_mut()),
@@ -119,7 +118,7 @@ impl MutItemAttrs for syn::TraitItem {
fn mut_item_attrs(&mut self) -> Option<&mut Vec<syn::Attribute>> {
match self {
Self::Const(item) => Some(item.attrs.as_mut()),
Self::Method(item) => Some(item.attrs.as_mut()),
Self::Fn(item) => Some(item.attrs.as_mut()),
Self::Type(item) => Some(item.attrs.as_mut()),
Self::Macro(item) => Some(item.attrs.as_mut()),
_ => None,
@@ -139,7 +138,7 @@ impl MutItemAttrs for syn::ItemMod {
}
}
impl MutItemAttrs for syn::ImplItemMethod {
impl MutItemAttrs for syn::ImplItemFn {
fn mut_item_attrs(&mut self) -> Option<&mut Vec<syn::Attribute>> {
Some(&mut self.attrs)
}
@@ -71,7 +71,7 @@ impl HooksDef {
}
let has_runtime_upgrade = item.items.iter().any(|i| match i {
syn::ImplItem::Method(method) => method.sig.ident == "on_runtime_upgrade",
syn::ImplItem::Fn(method) => method.sig.ident == "on_runtime_upgrade",
_ => false,
});
@@ -159,7 +159,7 @@ pub struct StorageDef {
/// The keys and value metadata of the storage.
pub metadata: Metadata,
/// The doc associated to the storage.
pub docs: Vec<syn::Lit>,
pub docs: Vec<syn::Expr>,
/// A set of usage of instance, must be check for consistency with config.
pub instances: Vec<helper::InstanceUsage>,
/// Optional getter to generate. If some then query_kind is ensured to be some as well.
@@ -270,7 +270,7 @@ enum StorageKind {
/// Check the generics in the `map` contains the generics in `gen` may contains generics in
/// `optional_gen`, and doesn't contains any other.
fn check_generics(
map: &HashMap<String, syn::Binding>,
map: &HashMap<String, syn::AssocType>,
mandatory_generics: &[&str],
optional_generics: &[&str],
storage_type_name: &str,
@@ -331,9 +331,9 @@ fn check_generics(
fn process_named_generics(
storage: &StorageKind,
args_span: proc_macro2::Span,
args: &[syn::Binding],
args: &[syn::AssocType],
) -> syn::Result<(Option<StorageGenerics>, Metadata, Option<syn::Type>, bool)> {
let mut parsed = HashMap::<String, syn::Binding>::new();
let mut parsed = HashMap::<String, syn::AssocType>::new();
// Ensure no duplicate.
for arg in args {
@@ -610,12 +610,12 @@ fn process_generics(
})
.collect::<Vec<_>>();
process_unnamed_generics(&storage_kind, args_span, &args, dev_mode)
} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::Binding(_))) {
} else if args.args.iter().all(|gen| matches!(gen, syn::GenericArgument::AssocType(_))) {
let args = args
.args
.iter()
.map(|gen| match gen {
syn::GenericArgument::Binding(gen) => gen.clone(),
syn::GenericArgument::AssocType(gen) => gen.clone(),
_ => unreachable!("It is asserted above that all generics are bindings"),
})
.collect::<Vec<_>>();
@@ -39,7 +39,7 @@ pub struct TypeValueDef {
/// The span of the pallet::type_value attribute.
pub attr_span: proc_macro2::Span,
/// Docs on the item.
pub docs: Vec<syn::Lit>,
pub docs: Vec<syn::Expr>,
}
impl TypeValueDef {
@@ -57,9 +57,9 @@ impl TypeValueDef {
let mut docs = vec![];
for attr in &item.attrs {
if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() {
if let syn::Meta::NameValue(meta) = &attr.meta {
if meta.path.get_ident().map_or(false, |ident| ident == "doc") {
docs.push(meta.lit);
docs.push(meta.value.clone());
continue
}
}