diff options
| author | bors <bors@rust-lang.org> | 2015-02-10 19:52:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-02-10 19:52:04 +0000 |
| commit | bc87efef2cceaec99d30e809cac2b8d22b9e25fc (patch) | |
| tree | 1f59e50bc58a426615cc15594cade8b69f24bdbf /src/libsyntax/config.rs | |
| parent | 88d8ba5ab3b1d22288b021708c3d87464e43b880 (diff) | |
| parent | 3e10785e21b731d536cf9ad9b911e8261862bde7 (diff) | |
| download | rust-bc87efef2cceaec99d30e809cac2b8d22b9e25fc.tar.gz rust-bc87efef2cceaec99d30e809cac2b8d22b9e25fc.zip | |
Auto merge of #22153 - alexcrichton:rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/config.rs')
| -rw-r--r-- | src/libsyntax/config.rs | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index eb845e463a0..7ca0591be50 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -12,7 +12,7 @@ use attr::AttrMetaMethods; use diagnostic::SpanHandler; use fold::Folder; use {ast, fold, attr}; -use codemap::Spanned; +use codemap::{Spanned, respan}; use ptr::P; use util::small_vector::SmallVector; @@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool { // Support conditional compilation by transforming the AST, stripping out // any items that do not belong in the current configuration pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate { + let krate = process_cfg_attr(diagnostic, krate); let config = krate.config.clone(); strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs)) } @@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr attr::cfg_matches(diagnostic, cfg, &*mis[0]) }) } + +struct CfgAttrFolder<'a> { + diag: &'a SpanHandler, + config: ast::CrateConfig, +} + +// Process `#[cfg_attr]`. +fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate { + let mut fld = CfgAttrFolder { + diag: diagnostic, + config: krate.config.clone(), + }; + fld.fold_crate(krate) +} + +impl<'a> fold::Folder for CfgAttrFolder<'a> { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> { + if !attr.check_name("cfg_attr") { + return fold::noop_fold_attribute(attr, self); + } + + let (cfg, mi) = match attr.meta_item_list() { + Some([ref cfg, ref mi]) => (cfg, mi), + _ => { + self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`"); + return None; + } + }; + + if attr::cfg_matches(self.diag, &self.config[], &cfg) { + Some(respan(mi.span, ast::Attribute_ { + id: attr::mk_attr_id(), + style: attr.node.style, + value: mi.clone(), + is_sugared_doc: false, + })) + } else { + None + } + } + + // Need the ability to run pre-expansion. + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } +} |
