(index<- )        ./librustc/front/config.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  use syntax::fold::Folder;
  12  use syntax::{ast, fold, attr};
  13  use syntax::codemap;
  14  
  15  struct Context<'a> {
  16      in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
  17  }
  18  
  19  // Support conditional compilation by transforming the AST, stripping out
  20  // any items that do not belong in the current configuration
  21  pub fn strip_unconfigured_items(krateast::Crate) -> ast::Crate {
  22      let config = krate.config.clone();
  23      strip_items(krate, |attrs| in_cfg(config.as_slice(), attrs))
  24  }
  25  
  26  impl<'a> fold::Folder for Context<'a> {
  27      fn fold_mod(&mut self, module&ast::Mod) -> ast::Mod {
  28          fold_mod(self, module)
  29      }
  30      fn fold_block(&mut self, blockast::P<ast::Block>) -> ast::P<ast::Block> {
  31          fold_block(self, block)
  32      }
  33      fn fold_foreign_mod(&mut self, foreign_mod&ast::ForeignMod) -> ast::ForeignMod {
  34          fold_foreign_mod(self, foreign_mod)
  35      }
  36      fn fold_item_underscore(&mut self, item&ast::Item_) -> ast::Item_ {
  37          fold_item_underscore(self, item)
  38      }
  39      fn fold_expr(&mut self, expr@ast::Expr) -> @ast::Expr {
  40          fold_expr(self, expr)
  41      }
  42  }
  43  
  44  pub fn strip_items(krateast::Crate,
  45                     in_cfg: |attrs: &[ast::Attribute]-> bool)
  46                     -> ast::Crate {
  47      let mut ctxt = Context {
  48          in_cfg: in_cfg,
  49      };
  50      ctxt.fold_crate(krate)
  51  }
  52  
  53  fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
  54                          -> Option<&'r ast::ViewItem> {
  55      if view_item_in_cfg(cx, view_item) {
  56          Some(view_item)
  57      } else {
  58          None
  59      }
  60  }
  61  
  62  fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
  63      let filtered_itemsVec<&@ast::Item> = m.items.iter()
  64              .filter(|&a| item_in_cfg(cx, *a))
  65              .collect();
  66      let flattened_items = filtered_items.move_iter()
  67              .flat_map(|&x| cx.fold_item(x).move_iter())
  68              .collect();
  69      let filtered_view_items = m.view_items.iter().filter_map(|a| {
  70          filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
  71      }).collect();
  72      ast::Mod {
  73          inner: m.inner,
  74          view_items: filtered_view_items,
  75          items: flattened_items
  76      }
  77  }
  78  
  79  fn filter_foreign_item(cx: &mut Context, item: @ast::ForeignItem)
  80                         -> Option<@ast::ForeignItem> {
  81      if foreign_item_in_cfg(cx, item) {
  82          Some(item)
  83      } else {
  84          None
  85      }
  86  }
  87  
  88  fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
  89      let filtered_items = nm.items
  90                             .iter()
  91                             .filter_map(|a| filter_foreign_item(cx, *a))
  92                             .collect();
  93      let filtered_view_items = nm.view_items.iter().filter_map(|a| {
  94          filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
  95      }).collect();
  96      ast::ForeignMod {
  97          abi: nm.abi,
  98          view_items: filtered_view_items,
  99          items: filtered_items
 100      }
 101  }
 102  
 103  fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
 104      let item = match *item {
 105          ast::ItemImpl(ref a, ref b, c, ref methods) => {
 106              let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
 107                  .map(|x| *x).collect();
 108              ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
 109          }
 110          ast::ItemTrait(ref a, b, ref c, ref methods) => {
 111              let methods = methods.iter()
 112                                   .filter(|m| trait_method_in_cfg(cx, *m) )
 113                                   .map(|x| (*x).clone())
 114                                   .collect();
 115              ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
 116          }
 117          ast::ItemStruct(def, ref generics) => {
 118              ast::ItemStruct(fold_struct(cx, def), generics.clone())
 119          }
 120          ast::ItemEnum(ref def, ref generics) => {
 121              let mut variants = def.variants.iter().map(|c| c.clone()).
 122              filter_map(|v| {
 123                  if !(cx.in_cfg)(v.node.attrs.as_slice()) {
 124                      None
 125                  } else {
 126                      Some(match v.node.kind {
 127                                  ast::TupleVariantKind(..) => v,
 128                                  ast::StructVariantKind(def) => {
 129                                      let def = fold_struct(cx, def);
 130                                      @codemap::Spanned {
 131                                          node: ast::Variant_ {
 132                                              kind: ast::StructVariantKind(def),
 133                                              ..v.node.clone()
 134                                          },
 135                                          ..*v
 136                                      }
 137                                  }
 138                              })
 139                      }
 140                  });
 141              ast::ItemEnum(ast::EnumDef {
 142                  variants: variants.collect(),
 143              }, generics.clone())
 144          }
 145          ref item => item.clone(),
 146      };
 147  
 148      fold::noop_fold_item_underscore(&item, cx)
 149  }
 150  
 151  fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef {
 152      let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
 153          (cx.in_cfg)(m.node.attrs.as_slice())
 154      });
 155      @ast::StructDef {
 156          fields: fields.collect(),
 157          ctor_id: def.ctor_id,
 158          super_struct: def.super_struct.clone(),
 159          is_virtual: def.is_virtual,
 160      }
 161  }
 162  
 163  fn retain_stmt(cx: &mut Context, stmt: @ast::Stmt) -> bool {
 164      match stmt.node {
 165        ast::StmtDecl(decl, _) => {
 166          match decl.node {
 167            ast::DeclItem(item) => {
 168              item_in_cfg(cx, item)
 169            }
 170            _ => true
 171          }
 172        }
 173        _ => true
 174      }
 175  }
 176  
 177  fn fold_block(cx: &mut Context, bast::P<ast::Block>) -> ast::P<ast::Block> {
 178      let resulting_stmtsVec<&@ast::Stmt> =
 179          b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
 180      let resulting_stmts = resulting_stmts.move_iter()
 181          .flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
 182          .collect();
 183      let filtered_view_items = b.view_items.iter().filter_map(|a| {
 184          filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
 185      }).collect();
 186      ast::P(ast::Block {
 187          view_items: filtered_view_items,
 188          stmts: resulting_stmts,
 189          expr: b.expr.map(|x| cx.fold_expr(x)),
 190          id: b.id,
 191          rules: b.rules,
 192          span: b.span,
 193      })
 194  }
 195  
 196  fn fold_expr(cx: &mut Context, expr: @ast::Expr) -> @ast::Expr {
 197      let expr = match expr.node {
 198          ast::ExprMatch(ref m, ref arms) => {
 199              let arms = arms.iter()
 200                  .filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
 201                  .map(|a| a.clone())
 202                  .collect();
 203              @ast::Expr {
 204                  id: expr.id,
 205                  span: expr.span.clone(),
 206                  node: ast::ExprMatch(m.clone(), arms),
 207              }
 208          }
 209          _ => expr.clone()
 210      };
 211      fold::noop_fold_expr(expr, cx)
 212  }
 213  
 214  fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
 215      return (cx.in_cfg)(item.attrs.as_slice());
 216  }
 217  
 218  fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool {
 219      return (cx.in_cfg)(item.attrs.as_slice());
 220  }
 221  
 222  fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
 223      return (cx.in_cfg)(item.attrs.as_slice());
 224  }
 225  
 226  fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
 227      return (cx.in_cfg)(meth.attrs.as_slice());
 228  }
 229  
 230  fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
 231      match *meth {
 232          ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
 233          ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())
 234      }
 235  }
 236  
 237  // Determine if an item should be translated in the current crate
 238  // configuration based on the item's attributes
 239  fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool {
 240      attr::test_cfg(cfg, attrs.iter().map(|x| *x))
 241  }
 242  


librustc/front/config.rs:43:1-43:1 -fn- definition:
pub fn strip_items(krate: ast::Crate,
                   in_cfg: |attrs: &[ast::Attribute]| -> bool)
                   -> ast::Crate {
references:- 2
22:     let config = krate.config.clone();
23:     strip_items(krate, |attrs| in_cfg(config.as_slice(), attrs))
24: }
librustc/front/test.rs:
187:     // #[test] functions
188:     config::strip_items(krate, |attrs| {
189:         !attr::contains_name(attrs.as_slice(), "test") &&


librustc/front/config.rs:14:1-14:1 -struct- definition:
struct Context<'a> {
    in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
}
references:- 16
46:                    -> ast::Crate {
47:     let mut ctxt = Context {
48:         in_cfg: in_cfg,
--
62: fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
63:     let filtered_items: Vec<&@ast::Item> = m.items.iter()
--
196: fn fold_expr(cx: &mut Context, expr: @ast::Expr) -> @ast::Expr {
197:     let expr = match expr.node {
--
230: fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
231:     match *meth {


librustc/front/config.rs:213:1-213:1 -fn- definition:
fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
    return (cx.in_cfg)(item.attrs.as_slice());
}
references:- 2
63:     let filtered_items: Vec<&@ast::Item> = m.items.iter()
64:             .filter(|&a| item_in_cfg(cx, *a))
65:             .collect();
--
167:           ast::DeclItem(item) => {
168:             item_in_cfg(cx, item)
169:           }


librustc/front/config.rs:52:1-52:1 -fn- definition:
fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
                        -> Option<&'r ast::ViewItem> {
    if view_item_in_cfg(cx, view_item) {
references:- 3
69:     let filtered_view_items = m.view_items.iter().filter_map(|a| {
70:         filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
71:     }).collect();
--
93:     let filtered_view_items = nm.view_items.iter().filter_map(|a| {
94:         filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
95:     }).collect();
--
183:     let filtered_view_items = b.view_items.iter().filter_map(|a| {
184:         filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
185:     }).collect();


librustc/front/config.rs:20:61-20:61 -fn- definition:
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(krate: ast::Crate) -> ast::Crate {
    let config = krate.config.clone();
references:- 2
librustc/driver/driver.rs:
253:     krate = time(time_passes, "configuration 2", krate, |krate|
254:                  front::config::strip_unconfigured_items(krate));


librustc/front/config.rs:150:1-150:1 -fn- definition:
fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef {
    let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
        (cx.in_cfg)(m.node.attrs.as_slice())
references:- 2
128:                                 ast::StructVariantKind(def) => {
129:                                     let def = fold_struct(cx, def);
130:                                     @codemap::Spanned {