diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-10-26 15:01:54 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-11-04 09:26:35 +0200 |
commit | 43378e3827fd0d17325646c40c76bab9db1da19a (patch) | |
tree | 0d68ca5cfb9e58f6afa406a62965a21e82e56a30 /build2/test/script/parser.cxx | |
parent | 616690fd06d1c5d05de97b88119dd8d328522df0 (diff) |
Handle explicit test scopes
Diffstat (limited to 'build2/test/script/parser.cxx')
-rw-r--r-- | build2/test/script/parser.cxx | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx index 25d3636..3043f05 100644 --- a/build2/test/script/parser.cxx +++ b/build2/test/script/parser.cxx @@ -114,10 +114,10 @@ namespace build2 // Push group. Use line number as the scope id. // + unique_ptr<group> g (new group (to_string (ll.line), *group_)); + group* og (group_); - unique_ptr<group> p ( - group_ = new group (to_string (ll.line), *og)); - og->scopes.push_back (move (p)); + group_ = g.get (); group_->start_loc_ = ll; token e (pre_parse_scope_body ()); @@ -127,6 +127,66 @@ namespace build2 // group_ = og; + // Drop empty scopes. + // + if (!g->empty ()) + { + // See if this turned out to be an explicit test scope. An + // explicit test scope contains a single test, only variable + // assignments in setup and nothing in teardown. Plus only the + // test or the scope (but not both) can have an explicit id. + // + // @@ TODO: explicit id. + // + auto& sc (g->scopes); + auto& su (g->setup_); + auto& td (g->tdown_); + + test* t; + if (sc.size () == 1 && + (t = dynamic_cast<test*> (sc.back ().get ())) != nullptr && + td.empty () && + find_if ( + su.begin (), su.end (), + [] (const line& l) + { + return l.type != line_type::variable; + }) == su.end ()) + { + // It would have been nice to reuse the test object and only + // throw aways the group. However, the merged scope should + // have id_path/wd_path of the group. So to keep things + // simple we are going to throw away both and create a new + // test object. + // + // @@ TODO: decide whose id to use. + // + unique_ptr<test> m (new test (g->id_path.leaf ().string (), + *group_)); + + // Merge the lines of the group and the test. + // + if (su.empty ()) + m->tests_ = move (t->tests_); + else + { + m->tests_ = move (su); // Should come first. + m->tests_.insert (m->tests_.end (), + make_move_iterator (t->tests_.begin ()), + make_move_iterator (t->tests_.end ())); + } + + // Use start/end locations of the outer scope. + // + m->start_loc_ = g->start_loc_; + m->end_loc_ = g->end_loc_; + + group_->scopes.push_back (move (m)); + } + else + group_->scopes.push_back (move (g)); + } + if (e.type != type::rcbrace) fail (e) << "expected '}' at the end of the scope"; |