(index<- )        ./librustc/front/std_inject.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 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 driver::session;
  12  use driver::session::Session;
  13  
  14  use syntax::ast;
  15  use syntax::attr;
  16  use syntax::codemap::DUMMY_SP;
  17  use syntax::codemap;
  18  use syntax::fold::Folder;
  19  use syntax::fold;
  20  use syntax::owned_slice::OwnedSlice;
  21  use syntax::parse::token::InternedString;
  22  use syntax::parse::token;
  23  use syntax::util::small_vector::SmallVector;
  24  
  25  pub static VERSION: &'static str = "0.11-pre";
  26  
  27  pub fn maybe_inject_crates_ref(sess: &Session, krateast::Crate)
  28                                 -> ast::Crate {
  29      if use_std(&krate) {
  30          inject_crates_ref(sess, krate)
  31      } else {
  32          krate
  33      }
  34  }
  35  
  36  pub fn maybe_inject_prelude(sess: &Session, krateast::Crate) -> ast::Crate {
  37      if use_std(&krate) {
  38          inject_prelude(sess, krate)
  39      } else {
  40          krate
  41      }
  42  }
  43  
  44  fn use_std(krate: &ast::Crate) -> bool {
  45      !attr::contains_name(krate.attrs.as_slice(), "no_std")
  46  }
  47  
  48  fn use_start(krate: &ast::Crate) -> bool {
  49      !attr::contains_name(krate.attrs.as_slice(), "no_start")
  50  }
  51  
  52  fn no_prelude(attrs: &[ast::Attribute]) -> bool {
  53      attr::contains_name(attrs, "no_implicit_prelude")
  54  }
  55  
  56  struct StandardLibraryInjector<'a> {
  57      sess: &'a Session,
  58  }
  59  
  60  pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
  61      match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
  62          Some("1") => None,
  63          _ => {
  64              Some((token::intern_and_get_ident(format!("{}\\#{}",
  65                                                        krate,
  66                                                        VERSION)),
  67                    ast::CookedStr))
  68          }
  69      }
  70  }
  71  
  72  impl<'a> fold::Folder for StandardLibraryInjector<'a> {
  73      fn fold_crate(&mut self, krateast::Crate) -> ast::Crate {
  74          let mut vis = vec!(ast::ViewItem {
  75              node: ast::ViewItemExternCrate(token::str_to_ident("std"),
  76                                           with_version("std"),
  77                                           ast::DUMMY_NODE_ID),
  78              attrs: vec!(
  79                  attr::mk_attr(attr::mk_list_item(
  80                          InternedString::new("phase"),
  81                          vec!(
  82                              attr::mk_word_item(InternedString::new("syntax")),
  83                              attr::mk_word_item(InternedString::new("link")
  84                          ))))),
  85              vis: ast::Inherited,
  86              span: DUMMY_SP
  87          });
  88  
  89          let any_exe = self.sess.crate_types.borrow().iter().any(|ty| {
  90              *ty == session::CrateTypeExecutable
  91          });
  92          if use_start(&krate) && any_exe {
  93              vis.push(ast::ViewItem {
  94                  node: ast::ViewItemExternCrate(token::str_to_ident("native"),
  95                                               with_version("native"),
  96                                               ast::DUMMY_NODE_ID),
  97                  attrs: Vec::new(),
  98                  vis: ast::Inherited,
  99                  span: DUMMY_SP
 100              });
 101          }
 102  
 103          vis.push_all_move(krate.module.view_items.clone());
 104          let new_module = ast::Mod {
 105              view_items: vis,
 106              ..krate.module.clone()
 107          };
 108  
 109          ast::Crate {
 110              module: new_module,
 111              ..krate
 112          }
 113      }
 114  }
 115  
 116  fn inject_crates_ref(sess: &Session, krateast::Crate) -> ast::Crate {
 117      let mut fold = StandardLibraryInjector {
 118          sess: sess,
 119      };
 120      fold.fold_crate(krate)
 121  }
 122  
 123  struct PreludeInjector<'a> {
 124      sess: &'a Session,
 125  }
 126  
 127  
 128  impl<'a> fold::Folder for PreludeInjector<'a> {
 129      fn fold_crate(&mut self, krateast::Crate) -> ast::Crate {
 130          if !no_prelude(krate.attrs.as_slice()) {
 131              // only add `use std::prelude::*;` if there wasn't a
 132              // `#![no_implicit_prelude]` at the crate level.
 133              ast::Crate {
 134                  module: self.fold_mod(&krate.module),
 135                  ..krate
 136              }
 137          } else {
 138              krate
 139          }
 140      }
 141  
 142      fn fold_item(&mut self, item@ast::Item) -> SmallVector<@ast::Item> {
 143          if !no_prelude(item.attrs.as_slice()) {
 144              // only recur if there wasn't `#![no_implicit_prelude]`
 145              // on this item, i.e. this means that the prelude is not
 146              // implicitly imported though the whole subtree
 147              fold::noop_fold_item(item, self)
 148          } else {
 149              SmallVector::one(item)
 150          }
 151      }
 152  
 153      fn fold_mod(&mut self, module&ast::Mod) -> ast::Mod {
 154          let prelude_path = ast::Path {
 155              span: DUMMY_SP,
 156              global: false,
 157              segments: vec!(
 158                  ast::PathSegment {
 159                      identifier: token::str_to_ident("std"),
 160                      lifetimes: Vec::new(),
 161                      types: OwnedSlice::empty(),
 162                  },
 163                  ast::PathSegment {
 164                      identifier: token::str_to_ident("prelude"),
 165                      lifetimes: Vec::new(),
 166                      types: OwnedSlice::empty(),
 167                  }),
 168          };
 169  
 170          let vp = @codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID));
 171          let vi2 = ast::ViewItem {
 172              node: ast::ViewItemUse(vp),
 173              attrs: Vec::new(),
 174              vis: ast::Inherited,
 175              span: DUMMY_SP,
 176          };
 177  
 178          let vis = (vec!(vi2)).append(module.view_items.as_slice());
 179  
 180          // FIXME #2543: Bad copy.
 181          let new_module = ast::Mod {
 182              view_items: vis,
 183              ..(*module).clone()
 184          };
 185          fold::noop_fold_mod(&new_module, self)
 186      }
 187  }
 188  
 189  fn inject_prelude(sess: &Session, krateast::Crate) -> ast::Crate {
 190      let mut fold = PreludeInjector {
 191          sess: sess,
 192      };
 193      fold.fold_crate(krate)
 194  }


librustc/front/std_inject.rs:55:1-55:1 -struct- definition:
struct StandardLibraryInjector<'a> {
    sess: &'a Session,
}
references:- 2
116: fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
117:     let mut fold = StandardLibraryInjector {
118:         sess: sess,


librustc/front/std_inject.rs:122:1-122:1 -struct- definition:
struct PreludeInjector<'a> {
    sess: &'a Session,
}
references:- 2
189: fn inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
190:     let mut fold = PreludeInjector {
191:         sess: sess,


librustc/front/std_inject.rs:51:1-51:1 -fn- definition:
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
    attr::contains_name(attrs, "no_implicit_prelude")
}
references:- 2
142:     fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
143:         if !no_prelude(item.attrs.as_slice()) {
144:             // only recur if there wasn't `#![no_implicit_prelude]`


librustc/front/std_inject.rs:59:1-59:1 -fn- definition:
pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
    match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
        Some("1") => None,
references:- 3
75:             node: ast::ViewItemExternCrate(token::str_to_ident("std"),
76:                                          with_version("std"),
77:                                          ast::DUMMY_NODE_ID),
librustc/front/test.rs:
304:         (ast::ViewItemExternCrate(id_test,
305:                                with_version("test"),
306:                                ast::DUMMY_NODE_ID),
librustc/front/std_inject.rs:
94:                 node: ast::ViewItemExternCrate(token::str_to_ident("native"),
95:                                              with_version("native"),
96:                                              ast::DUMMY_NODE_ID),


librustc/front/std_inject.rs:43:1-43:1 -fn- definition:
fn use_std(krate: &ast::Crate) -> bool {
    !attr::contains_name(krate.attrs.as_slice(), "no_std")
}
references:- 2
36: pub fn maybe_inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
37:     if use_std(&krate) {
38:         inject_prelude(sess, krate)