rustc: Configure out #[test] functions when not testing
This commit is contained in:
parent
a2acb052ca
commit
c2c497ff53
@ -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));
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
7
src/test/compile-fail/elided-test.rs
Normal file
7
src/test/compile-fail/elided-test.rs
Normal 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() {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user