|
| 1 | +import std::option; |
| 2 | +import std::vec; |
| 3 | +import ast; |
| 4 | +import fold; |
| 5 | +import attr; |
| 6 | + |
| 7 | +export strip_unconfigured_items; |
| 8 | + |
| 9 | +// Support conditional compilation by transforming the AST, stripping out |
| 10 | +// any items that do not belong in the current configuration |
| 11 | +fn strip_unconfigured_items(@ast::crate crate) -> @ast::crate { |
| 12 | + auto cfg = crate.node.config; |
| 13 | + |
| 14 | + auto precursor = rec(fold_mod = bind fold_mod(cfg, _, _) |
| 15 | + with *fold::default_ast_fold()); |
| 16 | + |
| 17 | + auto fold = fold::make_fold(precursor); |
| 18 | + auto res = @fold.fold_crate(*crate); |
| 19 | + // FIXME: This is necessary to break a circular reference |
| 20 | + fold::dummy_out(fold); |
| 21 | + ret res; |
| 22 | +} |
| 23 | + |
| 24 | +fn filter_item(&ast::crate_cfg cfg, |
| 25 | + &@ast::item item) -> option::t[@ast::item] { |
| 26 | + if (in_cfg(cfg, item)) { |
| 27 | + option::some(item) |
| 28 | + } else { |
| 29 | + option::none |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +fn fold_mod(&ast::crate_cfg cfg, &ast::_mod m, |
| 34 | + fold::ast_fold fld) -> ast::_mod { |
| 35 | + auto filter = bind filter_item(cfg, _); |
| 36 | + auto filtered_items = vec::filter_map(filter, m.items); |
| 37 | + ret rec(view_items=vec::map(fld.fold_view_item, m.view_items), |
| 38 | + items=vec::map(fld.fold_item, filtered_items)); |
| 39 | +} |
| 40 | + |
| 41 | +// Determine if an item should be translated in the current crate |
| 42 | +// configuration based on the item's attributes |
| 43 | +fn in_cfg(&ast::crate_cfg cfg, &@ast::item item) -> bool { |
| 44 | + |
| 45 | + auto item_cfg_attrs = attr::find_attrs_by_name(item.attrs, "cfg"); |
| 46 | + |
| 47 | + auto item_has_cfg_attrs = vec::len(item_cfg_attrs) > 0u; |
| 48 | + if (!item_has_cfg_attrs) { ret true; } |
| 49 | + |
| 50 | + auto item_cfg_metas = attr::attr_metas(item_cfg_attrs); |
| 51 | + |
| 52 | + for (@ast::meta_item cfg_mi in item_cfg_metas) { |
| 53 | + if (attr::contains(cfg, cfg_mi)) { |
| 54 | + ret true; |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + ret false; |
| 59 | +} |
| 60 | + |
| 61 | + |
| 62 | +// Local Variables: |
| 63 | +// fill-column: 78; |
| 64 | +// indent-tabs-mode: nil |
| 65 | +// c-basic-offset: 4 |
| 66 | +// buffer-file-coding-system: utf-8-unix |
| 67 | +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; |
| 68 | +// End: |
0 commit comments