rustc: Configure out #[test] functions when not testing

This commit is contained in:
Brian Anderson 2012-01-05 17:30:00 -08:00
parent a2acb052ca
commit c2c497ff53
4 changed files with 62 additions and 25 deletions

View File

@ -146,11 +146,9 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
crate = crate =
time(time_passes, "configuration", time(time_passes, "configuration",
bind front::config::strip_unconfigured_items(crate)); bind front::config::strip_unconfigured_items(crate));
if sess.get_opts().test { crate =
crate = time(time_passes, "maybe building test harness",
time(time_passes, "building test harness", bind front::test::modify_for_testing(sess, crate));
bind front::test::modify_for_testing(sess, crate));
}
crate = crate =
time(time_passes, "expansion", time(time_passes, "expansion",
bind syntax::ext::expand::expand_crate(sess, crate)); bind syntax::ext::expand::expand_crate(sess, crate));

View File

@ -4,16 +4,31 @@
export strip_unconfigured_items; export strip_unconfigured_items;
export metas_in_cfg; export metas_in_cfg;
export strip_items;
type in_cfg_pred = fn@([ast::attribute]) -> bool;
type ctxt = @{
in_cfg: in_cfg_pred
};
// Support conditional compilation by transforming the AST, stripping out // Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration // any items that do not belong in the current configuration
fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate { fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
let cfg = crate.node.config; strip_items(crate) {|attrs|
in_cfg(crate.node.config, attrs)
}
}
fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
-> @ast::crate {
let ctxt = @{in_cfg: in_cfg};
let precursor = let precursor =
{fold_mod: bind fold_mod(cfg, _, _), {fold_mod: bind fold_mod(ctxt, _, _),
fold_block: bind fold_block(cfg, _, _), fold_block: bind fold_block(ctxt, _, _),
fold_native_mod: bind fold_native_mod(cfg, _, _) fold_native_mod: bind fold_native_mod(ctxt, _, _)
with *fold::default_ast_fold()}; with *fold::default_ast_fold()};
let fold = fold::make_fold(precursor); let fold = fold::make_fold(precursor);
@ -21,41 +36,41 @@ fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
ret res; ret res;
} }
fn filter_item(cfg: ast::crate_cfg, &&item: @ast::item) -> fn filter_item(cx: ctxt, &&item: @ast::item) ->
option::t<@ast::item> { option::t<@ast::item> {
if item_in_cfg(cfg, item) { option::some(item) } else { option::none } if item_in_cfg(cx, item) { option::some(item) } else { option::none }
} }
fn fold_mod(cfg: ast::crate_cfg, m: ast::_mod, fld: fold::ast_fold) -> fn fold_mod(cx: ctxt, m: ast::_mod, fld: fold::ast_fold) ->
ast::_mod { ast::_mod {
let filter = bind filter_item(cfg, _); let filter = bind filter_item(cx, _);
let filtered_items = vec::filter_map(m.items, filter); let filtered_items = vec::filter_map(m.items, filter);
ret {view_items: vec::map(m.view_items, fld.fold_view_item), ret {view_items: vec::map(m.view_items, fld.fold_view_item),
items: vec::map(filtered_items, fld.fold_item)}; items: vec::map(filtered_items, fld.fold_item)};
} }
fn filter_native_item(cfg: ast::crate_cfg, &&item: @ast::native_item) -> fn filter_native_item(cx: ctxt, &&item: @ast::native_item) ->
option::t<@ast::native_item> { option::t<@ast::native_item> {
if native_item_in_cfg(cfg, item) { if native_item_in_cfg(cx, item) {
option::some(item) option::some(item)
} else { option::none } } else { option::none }
} }
fn fold_native_mod(cfg: ast::crate_cfg, nm: ast::native_mod, fn fold_native_mod(cx: ctxt, nm: ast::native_mod,
fld: fold::ast_fold) -> ast::native_mod { fld: fold::ast_fold) -> ast::native_mod {
let filter = bind filter_native_item(cfg, _); let filter = bind filter_native_item(cx, _);
let filtered_items = vec::filter_map(nm.items, filter); let filtered_items = vec::filter_map(nm.items, filter);
ret {view_items: vec::map(nm.view_items, fld.fold_view_item), ret {view_items: vec::map(nm.view_items, fld.fold_view_item),
items: filtered_items}; items: filtered_items};
} }
fn filter_stmt(cfg: ast::crate_cfg, &&stmt: @ast::stmt) -> fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) ->
option::t<@ast::stmt> { option::t<@ast::stmt> {
alt stmt.node { alt stmt.node {
ast::stmt_decl(decl, _) { ast::stmt_decl(decl, _) {
alt decl.node { alt decl.node {
ast::decl_item(item) { ast::decl_item(item) {
if item_in_cfg(cfg, item) { if item_in_cfg(cx, item) {
option::some(stmt) option::some(stmt)
} else { option::none } } else { option::none }
} }
@ -66,9 +81,9 @@ fn filter_stmt(cfg: ast::crate_cfg, &&stmt: @ast::stmt) ->
} }
} }
fn fold_block(cfg: ast::crate_cfg, b: ast::blk_, fld: fold::ast_fold) -> fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) ->
ast::blk_ { ast::blk_ {
let filter = bind filter_stmt(cfg, _); let filter = bind filter_stmt(cx, _);
let filtered_stmts = vec::filter_map(b.stmts, filter); let filtered_stmts = vec::filter_map(b.stmts, filter);
ret {view_items: b.view_items, ret {view_items: b.view_items,
stmts: vec::map(filtered_stmts, fld.fold_stmt), stmts: vec::map(filtered_stmts, fld.fold_stmt),
@ -77,12 +92,12 @@ fn fold_block(cfg: ast::crate_cfg, b: ast::blk_, fld: fold::ast_fold) ->
rules: b.rules}; rules: b.rules};
} }
fn item_in_cfg(cfg: ast::crate_cfg, item: @ast::item) -> bool { fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool {
ret in_cfg(cfg, item.attrs); ret cx.in_cfg(item.attrs);
} }
fn native_item_in_cfg(cfg: ast::crate_cfg, item: @ast::native_item) -> bool { fn native_item_in_cfg(cx: ctxt, item: @ast::native_item) -> bool {
ret in_cfg(cfg, item.attrs); ret cx.in_cfg(item.attrs);
} }
// Determine if an item should be translated in the current crate // Determine if an item should be translated in the current crate

View File

@ -27,6 +27,15 @@
fn modify_for_testing(sess: session::session, fn modify_for_testing(sess: session::session,
crate: @ast::crate) -> @ast::crate { crate: @ast::crate) -> @ast::crate {
if sess.get_opts().test {
generate_test_harness(sess, crate)
} else {
strip_test_functions(crate)
}
}
fn generate_test_harness(sess: session::session,
crate: @ast::crate) -> @ast::crate {
let cx: test_ctxt = let cx: test_ctxt =
@{sess: sess, @{sess: sess,
crate: crate, crate: crate,
@ -43,6 +52,14 @@ fn modify_for_testing(sess: session::session,
ret res; ret res;
} }
fn strip_test_functions(crate: @ast::crate) -> @ast::crate {
// When not compiling with --test we should not compile the
// #[test] functions
config::strip_items(crate) {|attrs|
!attr::contains_name(attr::attr_metas(attrs), "test")
}
}
fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {
// Remove any defined main function from the AST so it doesn't clash with // Remove any defined main function from the AST so it doesn't clash with

View File

@ -0,0 +1,7 @@
// error-pattern: main function not found
// Since we're not compiling a test runner this function should be elided
// and the build will fail because main doesn't exist
#[test]
fn main() {
}