diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-11-04 14:59:42 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-11-07 12:04:28 -0800 |
| commit | 3dbd32854f6bdee94c98c5e3e5da58fb79d79fd9 (patch) | |
| tree | c38be4cf6f5ffdf89a3983635849a90b502d87fb /src/libsyntax | |
| parent | 45cbdec4174778bf915f17561ef971c068a7fcbc (diff) | |
| download | rust-3dbd32854f6bdee94c98c5e3e5da58fb79d79fd9.tar.gz rust-3dbd32854f6bdee94c98c5e3e5da58fb79d79fd9.zip | |
rustc: Process #[cfg]/#[cfg_attr] on crates
This commit implements processing these two attributes at the crate level as well as at the item level. When #[cfg] is applied at the crate level, then the entire crate will be omitted if the cfg doesn't match. The #[cfg_attr] attribute is processed as usual in that the attribute is included or not depending on whether the cfg matches. This was spurred on by motivations of #18585 where #[cfg_attr] annotations will be applied at the crate-level. cc #18585
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/config.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 9 |
3 files changed, 56 insertions, 13 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 72c62a173fc..257bfd69f43 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -15,6 +15,8 @@ use {ast, fold, attr}; use codemap::Spanned; use ptr::P; +use util::small_vector::SmallVector; + /// A folder that strips out items that do not belong in the current /// configuration. struct Context<'a> { @@ -47,6 +49,9 @@ impl<'a> fold::Folder for Context<'a> { fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { fold::noop_fold_mac(mac, self) } + fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> { + fold_item(self, item) + } } pub fn strip_items(krate: ast::Crate, @@ -72,13 +77,9 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> view_items: view_items.into_iter().filter_map(|a| { filter_view_item(cx, a).map(|x| cx.fold_view_item(x)) }).collect(), - items: items.into_iter().filter_map(|a| { - if item_in_cfg(cx, &*a) { - Some(cx.fold_item(a)) - } else { - None - } - }).flat_map(|x| x.into_iter()).collect() + items: items.into_iter().flat_map(|a| { + cx.fold_item(a).into_iter() + }).collect() } } @@ -104,6 +105,14 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: } } +fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> { + if item_in_cfg(cx, &*item) { + SmallVector::one(item.map(|i| cx.fold_item_simple(i))) + } else { + SmallVector::zero() + } +} + fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ { let item = match item { ast::ItemImpl(a, b, c, impl_items) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cd4a3d10c48..1132ea372b7 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1057,12 +1057,41 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mu pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, exported_macros, span}: Crate, folder: &mut T) -> Crate { + let config = folder.fold_meta_items(config); + + let mut items = folder.fold_item(P(ast::Item { + ident: token::special_idents::invalid, + attrs: attrs, + id: ast::DUMMY_NODE_ID, + vis: ast::Public, + span: span, + node: ast::ItemMod(module), + })).into_iter(); + + let (module, attrs, span) = match items.next() { + Some(item) => { + assert!(items.next().is_none(), + "a crate cannot expand to more than one item"); + item.and_then(|ast::Item { attrs, span, node, .. }| { + match node { + ast::ItemMod(m) => (m, attrs, span), + _ => panic!("fold converted a module to not a module"), + } + }) + } + None => (ast::Mod { + inner: span, + view_items: Vec::new(), + items: Vec::new(), + }, Vec::new(), span) + }; + Crate { - module: folder.fold_mod(module), - attrs: attrs.move_map(|x| folder.fold_attribute(x)), - config: folder.fold_meta_items(config), + module: module, + attrs: attrs, + config: config, exported_macros: exported_macros, - span: folder.new_span(span) + span: span, } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index a7db8e800a9..29637e88dd5 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -108,7 +108,10 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { } fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> { - self.cx.path.push(i.ident); + let ident = i.ident; + if ident.name != token::special_idents::invalid.name { + self.cx.path.push(ident); + } debug!("current path: {}", ast_util::path_name_i(self.cx.path.as_slice())); @@ -143,7 +146,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { ast::ItemMod(..) => fold::noop_fold_item(i, self), _ => SmallVector::one(i), }; - self.cx.path.pop(); + if ident.name != token::special_idents::invalid.name { + self.cx.path.pop(); + } res } |
