mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Add a pass to fold out items that do not belong in the current configuration
The parser needs to parse unconfigured items into the AST so that they can make the round trip back through the pretty printer, but subsequent passes shouldn't care about items not being translated. Running a fold pass after parsing is the lowest-impact way to make this work. The performance seems fine. Issue #489
This commit is contained in:
parent
3483c65b1f
commit
4165d3640a
@ -80,6 +80,8 @@ fn compile_input(session::session sess, eval::env env, str input,
|
||||
auto crate =
|
||||
time(time_passes, "parsing", bind parse_input(sess, p, input));
|
||||
if (sess.get_opts().output_type == link::output_type_none) { ret; }
|
||||
crate = time(time_passes, "configuration",
|
||||
bind front::config::strip_unconfigured_items(crate));
|
||||
auto ast_map = time(time_passes, "ast indexing",
|
||||
bind middle::ast_map::map_crate(*crate));
|
||||
auto d =
|
||||
|
68
src/comp/front/config.rs
Normal file
68
src/comp/front/config.rs
Normal file
@ -0,0 +1,68 @@
|
||||
import std::option;
|
||||
import std::vec;
|
||||
import ast;
|
||||
import fold;
|
||||
import attr;
|
||||
|
||||
export strip_unconfigured_items;
|
||||
|
||||
// Support conditional compilation by transforming the AST, stripping out
|
||||
// any items that do not belong in the current configuration
|
||||
fn strip_unconfigured_items(@ast::crate crate) -> @ast::crate {
|
||||
auto cfg = crate.node.config;
|
||||
|
||||
auto precursor = rec(fold_mod = bind fold_mod(cfg, _, _)
|
||||
with *fold::default_ast_fold());
|
||||
|
||||
auto fold = fold::make_fold(precursor);
|
||||
auto res = @fold.fold_crate(*crate);
|
||||
// FIXME: This is necessary to break a circular reference
|
||||
fold::dummy_out(fold);
|
||||
ret res;
|
||||
}
|
||||
|
||||
fn filter_item(&ast::crate_cfg cfg,
|
||||
&@ast::item item) -> option::t[@ast::item] {
|
||||
if (in_cfg(cfg, item)) {
|
||||
option::some(item)
|
||||
} else {
|
||||
option::none
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mod(&ast::crate_cfg cfg, &ast::_mod m,
|
||||
fold::ast_fold fld) -> ast::_mod {
|
||||
auto filter = bind filter_item(cfg, _);
|
||||
auto filtered_items = vec::filter_map(filter, m.items);
|
||||
ret rec(view_items=vec::map(fld.fold_view_item, m.view_items),
|
||||
items=vec::map(fld.fold_item, filtered_items));
|
||||
}
|
||||
|
||||
// Determine if an item should be translated in the current crate
|
||||
// configuration based on the item's attributes
|
||||
fn in_cfg(&ast::crate_cfg cfg, &@ast::item item) -> bool {
|
||||
|
||||
auto item_cfg_attrs = attr::find_attrs_by_name(item.attrs, "cfg");
|
||||
|
||||
auto item_has_cfg_attrs = vec::len(item_cfg_attrs) > 0u;
|
||||
if (!item_has_cfg_attrs) { ret true; }
|
||||
|
||||
auto item_cfg_metas = attr::attr_metas(item_cfg_attrs);
|
||||
|
||||
for (@ast::meta_item cfg_mi in item_cfg_metas) {
|
||||
if (attr::contains(cfg, cfg_mi)) {
|
||||
ret true;
|
||||
}
|
||||
}
|
||||
|
||||
ret false;
|
||||
}
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
||||
// End:
|
@ -57,6 +57,7 @@ mod front {
|
||||
mod parser;
|
||||
mod token;
|
||||
mod eval;
|
||||
mod config;
|
||||
}
|
||||
|
||||
mod back {
|
||||
|
Loading…
Reference in New Issue
Block a user