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
This commit is contained in:
Alex Crichton
2014-11-04 14:59:42 -08:00
parent 45cbdec417
commit 3dbd32854f
11 changed files with 127 additions and 23 deletions

View File

@@ -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) => {