|
1 |
| -import driver::session; |
| 1 | +// Code that generates a test runner to run all the tests in a crate |
| 2 | + |
| 3 | +import std::option; |
2 | 4 | import syntax::ast;
|
3 | 5 | import syntax::fold;
|
4 | 6 |
|
5 | 7 | export modify_for_testing;
|
6 | 8 |
|
7 |
| -type test_ctxt = rec(@session::session sess); |
| 9 | +type node_id_gen = @fn() -> ast::node_id; |
| 10 | + |
| 11 | +type test_ctxt = rec(node_id_gen next_node_id); |
8 | 12 |
|
9 | 13 | // Traverse the crate, collecting all the test functions, eliding any
|
10 | 14 | // existing main functions, and synthesizing a main test harness
|
11 |
| -fn modify_for_testing(&session::session sess, |
12 |
| - @ast::crate crate) -> @ast::crate { |
| 15 | +fn modify_for_testing(@ast::crate crate) -> @ast::crate { |
| 16 | + |
| 17 | + // FIXME: This hackasaurus assumes that 200000 is a safe number to start |
| 18 | + // generating node_ids at (which is totally not the case). pauls is going |
| 19 | + // to land a patch that puts parse_sess into session, which will give us |
| 20 | + // access to the real next node_id. |
| 21 | + auto next_node_id = @mutable 200000; |
| 22 | + auto next_node_id_fn = @bind fn(@mutable ast::node_id next_node_id) |
| 23 | + -> ast::node_id { |
| 24 | + auto this_node_id = *next_node_id; |
| 25 | + *next_node_id = next_node_id + 1; |
| 26 | + ret this_node_id; |
| 27 | + } (next_node_id); |
13 | 28 |
|
14 |
| - auto cx = rec(sess = @sess); |
| 29 | + auto cx = rec(next_node_id = next_node_id_fn); |
15 | 30 |
|
16 |
| - auto precursor = rec(fold_crate = bind fold_crate(cx, _, _) |
17 |
| - with *fold::default_ast_fold()); |
| 31 | + auto precursor = rec(fold_crate = bind fold_crate(cx, _, _) |
| 32 | + with *fold::default_ast_fold()); |
18 | 33 |
|
19 |
| - auto fold = fold::make_fold(precursor); |
20 |
| - auto res = @fold.fold_crate(*crate); |
21 |
| - // FIXME: This is necessary to break a circular reference |
22 |
| - fold::dummy_out(fold); |
23 |
| - ret res; |
| 34 | + auto fold = fold::make_fold(precursor); |
| 35 | + auto res = @fold.fold_crate(*crate); |
| 36 | + // FIXME: This is necessary to break a circular reference |
| 37 | + fold::dummy_out(fold); |
| 38 | + ret res; |
24 | 39 | }
|
25 | 40 |
|
26 | 41 | fn fold_crate(&test_ctxt cx, &ast::crate_ c,
|
27 | 42 | fold::ast_fold fld) -> ast::crate_ {
|
28 |
| - auto folded = fold::noop_fold_crate(c, fld); |
29 |
| - ret rec(module = add_test_module(folded.module) |
30 |
| - with folded); |
| 43 | + auto folded = fold::noop_fold_crate(c, fld); |
| 44 | + |
| 45 | + // Add a special __test module to the crate that will contain code |
| 46 | + // generated for the test harness |
| 47 | + ret rec(module = add_test_module(cx, folded.module) |
| 48 | + with folded); |
| 49 | +} |
| 50 | + |
| 51 | +fn add_test_module(&test_ctxt cx, &ast::_mod m) -> ast::_mod { |
| 52 | + auto testmod = mk_test_module(cx); |
| 53 | + ret rec(items = m.items + [testmod] |
| 54 | + with m); |
31 | 55 | }
|
32 | 56 |
|
33 |
| -fn add_test_module(&ast::_mod m) -> ast::_mod { |
34 |
| - ret m; |
| 57 | +fn mk_test_module(&test_ctxt cx) -> @ast::item { |
| 58 | + auto mainfn = mk_main(cx); |
| 59 | + let ast::_mod testmod = rec(view_items = [], |
| 60 | + items = [mainfn]); |
| 61 | + auto item_ = ast::item_mod(testmod); |
| 62 | + let ast::item item = rec(ident = "__test", |
| 63 | + attrs = ~[], |
| 64 | + id = cx.next_node_id(), |
| 65 | + node = item_, |
| 66 | + span = rec(lo=0u, hi=0u)); |
| 67 | + ret @item; |
| 68 | +} |
| 69 | + |
| 70 | +fn mk_main(&test_ctxt cx) -> @ast::item { |
| 71 | + auto ret_ty = @rec(node=ast::ty_nil, |
| 72 | + span=rec(lo=0u, hi=0u)); |
| 73 | + |
| 74 | + let ast::fn_decl decl = rec(inputs = [], |
| 75 | + output = ret_ty, |
| 76 | + purity = ast::impure_fn, |
| 77 | + cf = ast::return, |
| 78 | + constraints = ~[]); |
| 79 | + auto proto = ast::proto_fn; |
| 80 | + |
| 81 | + let ast::block_ body_ = rec(stmts = [], |
| 82 | + expr = option::none, |
| 83 | + id = cx.next_node_id()); |
| 84 | + auto body = rec(node = body_, span = rec(lo=0u, hi=0u)); |
| 85 | + |
| 86 | + auto fn_ = rec(decl = decl, |
| 87 | + proto = proto, |
| 88 | + body = body); |
| 89 | + |
| 90 | + auto item_ = ast::item_fn(fn_, []); |
| 91 | + let ast::item item = rec(ident = "main", |
| 92 | + attrs = ~[], |
| 93 | + id = cx.next_node_id(), |
| 94 | + node = item_, |
| 95 | + span = rec(lo=0u, hi=0u)); |
| 96 | + ret @item; |
35 | 97 | }
|
36 | 98 |
|
37 | 99 | // Local Variables:
|
|
0 commit comments