// This file is part of Substrate. // Copyright (C) 2017-2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // tag::description[] //! Extension to syn types, mainly for parsing // end::description[] use frame_support_procedural_tools_derive::{Parse, ToTokens}; use proc_macro2::{TokenStream, TokenTree}; use quote::ToTokens; use std::iter::once; use syn::{ parse::{Parse, ParseStream, Result}, visit::{self, Visit}, Ident, }; /// stop parsing here getting remaining token as content /// Warn duplicate stream (part of) #[derive(Parse, ToTokens, Debug)] pub struct StopParse { pub inner: TokenStream, } // inner macro really dependant on syn naming convention, do not export macro_rules! groups_impl { ($name:ident, $tok:ident, $deli:ident, $parse:ident) => { #[derive(Debug)] pub struct $name
{
pub token: syn::token::$tok,
pub content: P,
}
impl {
fn parse(input: ParseStream) -> Result {
fn to_tokens(&self, tokens: &mut TokenStream) {
let mut inner_stream = TokenStream::new();
self.content.to_tokens(&mut inner_stream);
let token_tree: proc_macro2::TokenTree =
proc_macro2::Group::new(proc_macro2::Delimiter::$deli, inner_stream).into();
tokens.extend(once(token_tree));
}
}
impl {
fn clone(&self) -> Self {
Self { token: self.token.clone(), content: self.content.clone() }
}
}
};
}
groups_impl!(Braces, Brace, Brace, braced);
groups_impl!(Brackets, Bracket, Bracket, bracketed);
groups_impl!(Parens, Paren, Parenthesis, parenthesized);
#[derive(Debug)]
pub struct PunctuatedInner {
pub inner: syn::punctuated::Punctuated ,
pub variant: V,
}
#[derive(Debug, Clone)]
pub struct NoTrailing;
#[derive(Debug, Clone)]
pub struct Trailing;
pub type Punctuated = PunctuatedInner ;
pub type PunctuatedTrailing = PunctuatedInner ;
impl {
fn parse(input: ParseStream) -> Result {
fn parse(input: ParseStream) -> Result {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.inner.to_tokens(tokens)
}
}
impl {
fn clone(&self) -> Self {
Self { inner: self.inner.clone(), variant: self.variant.clone() }
}
}
/// Note that syn Meta is almost fine for use case (lacks only `ToToken`)
#[derive(Debug, Clone)]
pub struct Meta {
pub inner: syn::Meta,
}
impl Parse for Meta {
fn parse(input: ParseStream) -> Result