1use crate::attr::{self, Then};
2use crate::error::{Error, Result};
3use crate::{constfn, expr, iter, token};
4use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
5use std::iter::FromIterator;
6
7pub 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
11fn 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
33pub 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