| 1 | use crate::attr::{self, Then}; | 
| 2 | use crate::error::{Error, Result}; | 
|---|
| 3 | use crate::{constfn, expr, iter, token}; | 
|---|
| 4 | use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; | 
|---|
| 5 | use std::iter::FromIterator; | 
|---|
| 6 |  | 
|---|
| 7 | pub fn cfg(introducer: &str, args: TokenStream, input: TokenStream) -> TokenStream { | 
|---|
| 8 | try_cfg(introducer, args, input).unwrap_or_else(op:Error::into_compile_error) | 
|---|
| 9 | } | 
|---|
| 10 |  | 
|---|
| 11 | fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<TokenStream> { | 
|---|
| 12 | let introducer: Ident = Ident::new(string:introducer, Span::call_site()); | 
|---|
| 13 |  | 
|---|
| 14 | let mut full_args: TokenStream = TokenStream::from(TokenTree::Ident(introducer)); | 
|---|
| 15 | if !args.is_empty() { | 
|---|
| 16 | full_args.extend(iter:std::iter::once(TokenTree::Group(Group::new( | 
|---|
| 17 | Delimiter::Parenthesis, | 
|---|
| 18 | stream:args, | 
|---|
| 19 | )))); | 
|---|
| 20 | } | 
|---|
| 21 |  | 
|---|
| 22 | let ref mut full_args: &mut IterImpl = iter::new(tokens:full_args); | 
|---|
| 23 | let expr: Expr = expr::parse(iter:full_args)?; | 
|---|
| 24 | token::parse_end(iter:full_args)?; | 
|---|
| 25 |  | 
|---|
| 26 | if expr.eval(rustc:crate::RUSTVERSION) { | 
|---|
| 27 | Ok(input) | 
|---|
| 28 | } else { | 
|---|
| 29 | Ok(TokenStream::new()) | 
|---|
| 30 | } | 
|---|
| 31 | } | 
|---|
| 32 |  | 
|---|
| 33 | pub fn try_attr(args: attr::Args, input: TokenStream) -> Result<TokenStream> { | 
|---|
| 34 | if !args.condition.eval(crate::RUSTVERSION) { | 
|---|
| 35 | return Ok(input); | 
|---|
| 36 | } | 
|---|
| 37 |  | 
|---|
| 38 | match args.then { | 
|---|
| 39 | Then::Const(const_token) => constfn::insert_const(input, const_token), | 
|---|
| 40 | Then::Attribute(then) => { | 
|---|
| 41 | // #[cfg_attr(all(), #then)] | 
|---|
| 42 | Ok(TokenStream::from_iter( | 
|---|
| 43 | vec![ | 
|---|
| 44 | TokenTree::Punct(Punct::new( '#', Spacing::Alone)), | 
|---|
| 45 | TokenTree::Group(Group::new( | 
|---|
| 46 | Delimiter::Bracket, | 
|---|
| 47 | TokenStream::from_iter(vec![ | 
|---|
| 48 | TokenTree::Ident(Ident::new( "cfg_attr", Span::call_site())), | 
|---|
| 49 | TokenTree::Group(Group::new( | 
|---|
| 50 | Delimiter::Parenthesis, | 
|---|
| 51 | TokenStream::from_iter( | 
|---|
| 52 | vec![ | 
|---|
| 53 | TokenTree::Ident(Ident::new( "all", Span::call_site())), | 
|---|
| 54 | TokenTree::Group(Group::new( | 
|---|
| 55 | Delimiter::Parenthesis, | 
|---|
| 56 | TokenStream::new(), | 
|---|
| 57 | )), | 
|---|
| 58 | TokenTree::Punct(Punct::new( ',', Spacing::Alone)), | 
|---|
| 59 | ] | 
|---|
| 60 | .into_iter() | 
|---|
| 61 | .chain(then), | 
|---|
| 62 | ), | 
|---|
| 63 | )), | 
|---|
| 64 | ]), | 
|---|
| 65 | )), | 
|---|
| 66 | ] | 
|---|
| 67 | .into_iter() | 
|---|
| 68 | .chain(input), | 
|---|
| 69 | )) | 
|---|
| 70 | } | 
|---|
| 71 | } | 
|---|
| 72 | } | 
|---|
| 73 |  | 
|---|