Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  parse_quote.rs   Sprache: unbekannt

 
/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/1.0/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: crate::parse::Parse
///
/// ```
/// use quote::quote;
/// use syn::{parse_quote, Stmt};
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available only if Syn is built with both the `"parsing"` and
/// `"printing"` features.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// use syn::{parse_quote, Generics, GenericParam};
///
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(type_param) = param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
/// - [`Vec<Stmt>`] — parses the same as `Block::parse_within`
///
/// [`Vec<Stmt>`]: Block::parse_within
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::__private::parse_quote($crate::__private::quote::quote!($($tt)*))
    };
}

/// This macro is [`parse_quote!`] + [`quote_spanned!`][quote::quote_spanned].
///
/// Please refer to each of their documentation.
///
/// # Example
///
/// ```
/// use quote::{quote, quote_spanned};
/// use syn::spanned::Spanned;
/// use syn::{parse_quote_spanned, ReturnType, Signature};
///
/// // Changes `fn()` to `fn() -> Pin<Box<dyn Future<Output = ()>>>`,
/// // and `fn() -> T` to `fn() -> Pin<Box<dyn Future<Output = T>>>`,
/// // without introducing any call_site() spans.
/// fn make_ret_pinned_future(sig: &mut Signature) {
///     let ret = match &sig.output {
///         ReturnType::Default => quote_spanned!(sig.paren_token.span=> ()),
///         ReturnType::Type(_, ret) => quote!(#ret),
///     };
///     sig.output = parse_quote_spanned! {ret.span()=>
///         -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = #ret>>>
///     };
/// }
/// ```
#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote_spanned {
    ($span:expr=> $($tt:tt)*) => {
        $crate::__private::parse_quote($crate::__private::quote::quote_spanned!($span=> $($tt)*))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Parse.

use crate::error::Result;
use crate::parse::{Parse, ParseStream, Parser};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
#[track_caller]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

use crate::punctuated::Punctuated;
#[cfg(any(feature = "full", feature = "derive"))]
use crate::{attr, Attribute, Field, FieldMutability, Ident, Type, Visibility};
#[cfg(feature = "full")]
use crate::{Block, Pat, Stmt};

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Vec<Attribute> {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut attrs = Vec::new();
        while !input.is_empty() {
            attrs.push(ParseQuote::parse(input)?);
        }
        Ok(attrs)
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Field {
    fn parse(input: ParseStream) -> Result<Self> {
        let attrs = input.call(Attribute::parse_outer)?;
        let vis: Visibility = input.parse()?;

        let ident: Option<Ident>;
        let colon_token: Option<Token![:]>;
        let is_named = input.peek(Ident) && input.peek2(Token![:]) && !input.peek2(Token![::]);
        if is_named {
            ident = Some(input.parse()?);
            colon_token = Some(input.parse()?);
        } else {
            ident = None;
            colon_token = None;
        }

        let ty: Type = input.parse()?;

        Ok(Field {
            attrs,
            vis,
            mutability: FieldMutability::None,
            ident,
            colon_token,
            ty,
        })
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Pat {
    fn parse(input: ParseStream) -> Result<Self> {
        Pat::parse_multi_with_leading_vert(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Box<Pat> {
    fn parse(input: ParseStream) -> Result<Self> {
        <Pat as ParseQuote>::parse(input).map(Box::new)
    }
}

impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
    fn parse(input: ParseStream) -> Result<Self> {
        Self::parse_terminated(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Vec<Stmt> {
    fn parse(input: ParseStream) -> Result<Self> {
        Block::parse_within(input)
    }
}

[ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge