diff options
| author | bors <bors@rust-lang.org> | 2014-09-27 01:37:53 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-27 01:37:53 +0000 |
| commit | 43d7d7c15e964c1cb506cbce90bb4b32b57281b8 (patch) | |
| tree | ce3d1c405d06461fb8de8ba58b7f62440be5d199 /src/libsyntax | |
| parent | d64b4103d688f38c2e9e2daf966d50beeb383f1e (diff) | |
| parent | dcdbdc10036b444ef39c329e9440d4acc6975fda (diff) | |
| download | rust-43d7d7c15e964c1cb506cbce90bb4b32b57281b8.tar.gz rust-43d7d7c15e964c1cb506cbce90bb4b32b57281b8.zip | |
auto merge of #17506 : sfackler/rust/cfg-attr, r=alexcrichton
cc #17490 Reopening of #16230
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/cfg_attr.rs | 57 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 6 |
4 files changed, 66 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b35a9456757..8bf13e20fed 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -439,6 +439,8 @@ fn initial_syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(intern("cfg"), builtin_normal_expander( ext::cfg::expand_cfg)); + syntax_expanders.insert(intern("cfg_attr"), + Modifier(box ext::cfg_attr::expand)); syntax_expanders.insert(intern("trace_macros"), builtin_normal_expander( ext::trace_macros::expand_trace_macros)); diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs new file mode 100644 index 00000000000..ad02b50f248 --- /dev/null +++ b/src/libsyntax/ext/cfg_attr.rs @@ -0,0 +1,57 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ast; +use attr; +use codemap::Span; +use ext::base::ExtCtxt; +use ext::build::AstBuilder; +use ptr::P; + +pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> { + let (cfg, attr) = match mi.node { + ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]), + _ => { + cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`"); + return it; + } + }; + + let mut out = (*it).clone(); + if cfg_matches(cx, &**cfg) { + out.attrs.push(cx.attribute(attr.span, attr.clone())); + } + + P(out) +} + +fn cfg_matches(cx: &mut ExtCtxt, cfg: &ast::MetaItem) -> bool { + match cfg.node { + ast::MetaList(ref pred, ref mis) if pred.get() == "any" => + mis.iter().any(|mi| cfg_matches(cx, &**mi)), + ast::MetaList(ref pred, ref mis) if pred.get() == "all" => + mis.iter().all(|mi| cfg_matches(cx, &**mi)), + ast::MetaList(ref pred, ref mis) if pred.get() == "not" => { + if mis.len() != 1 { + cx.span_err(cfg.span, format!("expected 1 value, got {}", + mis.len()).as_slice()); + return false; + } + !cfg_matches(cx, &*mis[0]) + } + ast::MetaList(ref pred, _) => { + cx.span_err(cfg.span, + format!("invalid predicate `{}`", pred).as_slice()); + false + }, + ast::MetaWord(_) | ast::MetaNameValue(..) => + attr::contains(cx.cfg.as_slice(), cfg), + } +} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 153b3cc90d6..7a504d22c1e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -83,6 +83,7 @@ pub mod ext { pub mod build; pub mod bytes; pub mod cfg; + pub mod cfg_attr; pub mod concat; pub mod concat_idents; pub mod deriving; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f0e69712714..091b0ce8ed9 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -339,6 +339,12 @@ fn is_ignored(cx: &TestCtxt, i: &ast::Item) -> bool { // check ignore(cfg(foo, bar)) attr.check_name("ignore") && match attr.meta_item_list() { Some(ref cfgs) => { + if cfgs.iter().any(|cfg| cfg.check_name("cfg")) { + cx.span_diagnostic.span_warn(attr.span, + "The use of cfg filters in #[ignore] is \ + deprecated. Use #[cfg_attr(<cfg pattern>, \ + ignore)] instead."); + } attr::test_cfg(cx.config.as_slice(), cfgs.iter()) } None => true |
