about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-01-05 17:30:00 -0800
committerBrian Anderson <banderson@mozilla.com>2012-01-05 17:31:57 -0800
commitc2c497ff53596ffcdf713d6aabfbaaf2e50371bf (patch)
tree546c56a7c0d763b8c901681d786585f765736fe2 /src
parenta2acb052cae2252e45f09a79ba48a15bb4d2bbd9 (diff)
downloadrust-c2c497ff53596ffcdf713d6aabfbaaf2e50371bf.tar.gz
rust-c2c497ff53596ffcdf713d6aabfbaaf2e50371bf.zip
rustc: Configure out #[test] functions when not testing
Diffstat (limited to 'src')
-rw-r--r--src/comp/driver/driver.rs8
-rw-r--r--src/comp/front/config.rs55
-rw-r--r--src/comp/front/test.rs17
-rw-r--r--src/test/compile-fail/elided-test.rs7
4 files changed, 62 insertions, 25 deletions
diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs
index 74aafca0a15..efad512221e 100644
--- a/src/comp/driver/driver.rs
+++ b/src/comp/driver/driver.rs
@@ -146,11 +146,9 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
     crate =
         time(time_passes, "configuration",
              bind front::config::strip_unconfigured_items(crate));
-    if sess.get_opts().test {
-        crate =
-            time(time_passes, "building test harness",
-                 bind front::test::modify_for_testing(sess, crate));
-    }
+    crate =
+        time(time_passes, "maybe building test harness",
+             bind front::test::modify_for_testing(sess, crate));
     crate =
         time(time_passes, "expansion",
              bind syntax::ext::expand::expand_crate(sess, crate));
diff --git a/src/comp/front/config.rs b/src/comp/front/config.rs
index 13f6f07849e..c7de20bb1b3 100644
--- a/src/comp/front/config.rs
+++ b/src/comp/front/config.rs
@@ -4,16 +4,31 @@ import attr;
 
 export strip_unconfigured_items;
 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
 // any items that do not belong in the current configuration
 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 =
-        {fold_mod: bind fold_mod(cfg, _, _),
-         fold_block: bind fold_block(cfg, _, _),
-         fold_native_mod: bind fold_native_mod(cfg, _, _)
+        {fold_mod: bind fold_mod(ctxt, _, _),
+         fold_block: bind fold_block(ctxt, _, _),
+         fold_native_mod: bind fold_native_mod(ctxt, _, _)
             with *fold::default_ast_fold()};
 
     let fold = fold::make_fold(precursor);
@@ -21,41 +36,41 @@ fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
     ret res;
 }
 
-fn filter_item(cfg: ast::crate_cfg, &&item: @ast::item) ->
+fn filter_item(cx: ctxt, &&item: @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 {
-    let filter = bind filter_item(cfg, _);
+    let filter = bind filter_item(cx, _);
     let filtered_items = vec::filter_map(m.items, filter);
     ret {view_items: vec::map(m.view_items, fld.fold_view_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> {
-    if native_item_in_cfg(cfg, item) {
+    if native_item_in_cfg(cx, item) {
         option::some(item)
     } 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 {
-    let filter = bind filter_native_item(cfg, _);
+    let filter = bind filter_native_item(cx, _);
     let filtered_items = vec::filter_map(nm.items, filter);
     ret {view_items: vec::map(nm.view_items, fld.fold_view_item),
          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> {
     alt stmt.node {
       ast::stmt_decl(decl, _) {
         alt decl.node {
           ast::decl_item(item) {
-            if item_in_cfg(cfg, item) {
+            if item_in_cfg(cx, item) {
                 option::some(stmt)
             } 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_ {
-    let filter = bind filter_stmt(cfg, _);
+    let filter = bind filter_stmt(cx, _);
     let filtered_stmts = vec::filter_map(b.stmts, filter);
     ret {view_items: b.view_items,
          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};
 }
 
-fn item_in_cfg(cfg: ast::crate_cfg, item: @ast::item) -> bool {
-    ret in_cfg(cfg, item.attrs);
+fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool {
+    ret cx.in_cfg(item.attrs);
 }
 
-fn native_item_in_cfg(cfg: ast::crate_cfg, item: @ast::native_item) -> bool {
-    ret in_cfg(cfg, item.attrs);
+fn native_item_in_cfg(cx: ctxt, item: @ast::native_item) -> bool {
+    ret cx.in_cfg(item.attrs);
 }
 
 // Determine if an item should be translated in the current crate
diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs
index 570c18b857c..46293c80310 100644
--- a/src/comp/front/test.rs
+++ b/src/comp/front/test.rs
@@ -27,6 +27,15 @@ type test_ctxt =
 fn modify_for_testing(sess: session::session,
                       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 =
         @{sess: sess,
           crate: crate,
@@ -43,6 +52,14 @@ fn modify_for_testing(sess: session::session,
     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 {
 
     // Remove any defined main function from the AST so it doesn't clash with
diff --git a/src/test/compile-fail/elided-test.rs b/src/test/compile-fail/elided-test.rs
new file mode 100644
index 00000000000..551eaf06c39
--- /dev/null
+++ b/src/test/compile-fail/elided-test.rs
@@ -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() {
+}
\ No newline at end of file