Jeff Vander Stoep | e6217f3 | 2022-12-19 09:05:15 +0100 | [diff] [blame] | 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(Error::into_compile_error) |
| 9 | } |
| 10 | |
| 11 | fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<TokenStream> { |
| 12 | let introducer = Ident::new(introducer, Span::call_site()); |
| 13 | |
| 14 | let mut full_args = TokenStream::from(TokenTree::Ident(introducer)); |
| 15 | if !args.is_empty() { |
| 16 | full_args.extend(std::iter::once(TokenTree::Group(Group::new( |
| 17 | Delimiter::Parenthesis, |
| 18 | args, |
| 19 | )))); |
| 20 | } |
| 21 | |
| 22 | let ref mut full_args = iter::new(full_args); |
| 23 | let expr = expr::parse(full_args)?; |
| 24 | token::parse_end(full_args)?; |
| 25 | |
| 26 | if expr.eval(crate::rust_version()) { |
| 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::rust_version()) { |
| 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 | } |