]> git.lizzy.rs Git - rust.git/blob - src/libsyntax_ext/cfg.rs
syntax::parser::token -> syntax::token
[rust.git] / src / libsyntax_ext / cfg.rs
1 /// The compiler code necessary to support the cfg! extension, which expands to
2 /// a literal `true` or `false` based on whether the given cfg matches the
3 /// current compilation environment.
4
5 use errors::DiagnosticBuilder;
6
7 use syntax::ast;
8 use syntax_expand::base::{self, *};
9 use syntax::attr;
10 use syntax::tokenstream::TokenStream;
11 use syntax::token;
12 use syntax_pos::Span;
13
14 pub fn expand_cfg(
15     cx: &mut ExtCtxt<'_>,
16     sp: Span,
17     tts: TokenStream,
18 ) -> Box<dyn base::MacResult + 'static> {
19     let sp = cx.with_def_site_ctxt(sp);
20
21     match parse_cfg(cx, sp, tts) {
22         Ok(cfg) => {
23             let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
24             MacEager::expr(cx.expr_bool(sp, matches_cfg))
25         }
26         Err(mut err) => {
27             err.emit();
28             DummyResult::any(sp)
29         }
30     }
31 }
32
33 fn parse_cfg<'a>(
34     cx: &mut ExtCtxt<'a>,
35     sp: Span,
36     tts: TokenStream,
37 ) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> {
38     let mut p = cx.new_parser_from_tts(tts);
39
40     if p.token == token::Eof {
41         let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument");
42         err.span_label(sp, "cfg-pattern required");
43         return Err(err);
44     }
45
46     let cfg = p.parse_meta_item()?;
47
48     let _ = p.eat(&token::Comma);
49
50     if !p.eat(&token::Eof) {
51         return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern"));
52     }
53
54     Ok(cfg)
55 }