diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 9796aab51fb6b..ff1b50a48b919 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -171,7 +171,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) } if sess.show_span() { - front::show_span::run(sess, &krate); + syntax::show_span::run(sess.diagnostic(), &krate); } krate @@ -214,7 +214,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, // baz! should not use this definition unless foo is enabled. krate = time(time_passes, "configuration 1", krate, |krate| - front::config::strip_unconfigured_items(krate)); + syntax::config::strip_unconfigured_items(krate)); let mut addl_plugins = Some(addl_plugins); let Plugins { macros, registrars } @@ -283,16 +283,19 @@ pub fn phase_2_configure_and_expand(sess: &Session, // strip again, in case expansion added anything with a #[cfg]. krate = time(time_passes, "configuration 2", krate, |krate| - front::config::strip_unconfigured_items(krate)); + syntax::config::strip_unconfigured_items(krate)); krate = time(time_passes, "maybe building test harness", krate, |krate| - front::test::modify_for_testing(sess, krate)); + syntax::test::modify_for_testing(&sess.parse_sess, + &sess.opts.cfg, + krate, + sess.diagnostic())); krate = time(time_passes, "prelude injection", krate, |krate| front::std_inject::maybe_inject_prelude(sess, krate)); let (krate, map) = time(time_passes, "assigning node ids and indexing ast", krate, |krate| - front::assign_node_ids_and_map::assign_node_ids_and_map(sess, krate)); + syntax::assign_node_ids_and_map::assign_node_ids_and_map(&sess.parse_sess, krate)); if sess.opts.debugging_opts & config::AST_JSON != 0 { let mut stdout = io::BufferedWriter::new(io::stdout()); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 135e21e4e0184..fcce3e7000d28 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -47,7 +47,6 @@ pub struct Session { pub working_dir: Path, pub lint_store: RefCell, pub lints: RefCell>>, - pub node_id: Cell, pub crate_types: RefCell>, pub crate_metadata: RefCell>, pub features: front::feature_gate::Features, @@ -129,17 +128,10 @@ impl Session { lints.insert(id, vec!((lint_id, sp, msg))); } pub fn next_node_id(&self) -> ast::NodeId { - self.reserve_node_ids(1) + self.parse_sess.next_node_id() } pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { - let v = self.node_id.get(); - - match v.checked_add(&count) { - Some(next) => { self.node_id.set(next); } - None => self.bug("Input too large, ran out of node ids!") - } - - v + self.parse_sess.reserve_node_ids(count) } pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler { &self.parse_sess.span_diagnostic @@ -251,7 +243,6 @@ pub fn build_session_(sopts: config::Options, working_dir: os::getcwd(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap::new()), - node_id: Cell::new(1), crate_types: RefCell::new(Vec::new()), crate_metadata: RefCell::new(Vec::new()), features: front::feature_gate::Features::new(), diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index f9774e83e8a1c..15dc81ddba65a 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -111,12 +111,8 @@ pub mod middle { } pub mod front { - pub mod config; - pub mod test; pub mod std_inject; - pub mod assign_node_ids_and_map; pub mod feature_gate; - pub mod show_span; } pub mod metadata; diff --git a/src/librustc/front/assign_node_ids_and_map.rs b/src/libsyntax/assign_node_ids_and_map.rs similarity index 79% rename from src/librustc/front/assign_node_ids_and_map.rs rename to src/libsyntax/assign_node_ids_and_map.rs index f7c919131a809..f99de44df66ee 100644 --- a/src/librustc/front/assign_node_ids_and_map.rs +++ b/src/libsyntax/assign_node_ids_and_map.rs @@ -8,13 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use driver::session::Session; - -use syntax::ast; -use syntax::ast_map; +use ast; +use ast_map; +use parse::ParseSess; struct NodeIdAssigner<'a> { - sess: &'a Session + sess: &'a ParseSess } impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> { @@ -24,6 +23,7 @@ impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> { } } -pub fn assign_node_ids_and_map(sess: &Session, krate: ast::Crate) -> (ast::Crate, ast_map::Map) { +pub fn assign_node_ids_and_map(sess: &ParseSess, + krate: ast::Crate) -> (ast::Crate, ast_map::Map) { ast_map::map_crate(krate, NodeIdAssigner { sess: sess }) } diff --git a/src/librustc/front/config.rs b/src/libsyntax/config.rs similarity index 99% rename from src/librustc/front/config.rs rename to src/libsyntax/config.rs index ab363a88db2d9..fd04247aaeda4 100644 --- a/src/librustc/front/config.rs +++ b/src/libsyntax/config.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::fold::Folder; -use syntax::{ast, fold, attr}; -use syntax::codemap; +use fold::Folder; +use {ast, fold, attr}; +use codemap; use std::gc::{Gc, GC}; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 13d2a632f3638..4cc372f3c9e3b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -53,16 +53,20 @@ pub mod syntax { } pub mod abi; +pub mod assign_node_ids_and_map; pub mod ast; pub mod ast_map; pub mod ast_util; pub mod attr; pub mod codemap; +pub mod config; pub mod crateid; pub mod diagnostic; pub mod fold; pub mod owned_slice; pub mod parse; +pub mod show_span; +pub mod test; pub mod visit; pub mod print { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a3e169cd5116d..8ee8c791824e3 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -16,7 +16,7 @@ use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto}; use parse::attr::ParserAttr; use parse::parser::Parser; -use std::cell::RefCell; +use std::cell::{Cell,RefCell}; use std::gc::Gc; use std::io::File; use std::rc::Rc; @@ -36,12 +36,14 @@ pub struct ParseSess { pub span_diagnostic: SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions included_mod_stack: RefCell>, + pub node_id: Cell, } pub fn new_parse_sess() -> ParseSess { ParseSess { span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()), included_mod_stack: RefCell::new(Vec::new()), + node_id: Cell::new(1), } } @@ -49,6 +51,23 @@ pub fn new_parse_sess_special_handler(sh: SpanHandler) -> ParseSess { ParseSess { span_diagnostic: sh, included_mod_stack: RefCell::new(Vec::new()), + node_id: Cell::new(1), + } +} + +impl ParseSess { + pub fn next_node_id(&self) -> ast::NodeId { + self.reserve_node_ids(1) + } + pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { + let v = self.node_id.get(); + + match v.checked_add(&count) { + Some(next) => { self.node_id.set(next); } + None => fail!("Input too large, ran out of node ids!") + } + + v } } diff --git a/src/librustc/front/show_span.rs b/src/libsyntax/show_span.rs similarity index 72% rename from src/librustc/front/show_span.rs rename to src/libsyntax/show_span.rs index 36db4e422c11d..96a3563676bab 100644 --- a/src/librustc/front/show_span.rs +++ b/src/libsyntax/show_span.rs @@ -13,24 +13,23 @@ //! This module shows spans for all expressions in the crate //! to help with compiler debugging. -use syntax::ast; -use syntax::visit; -use syntax::visit::Visitor; - -use driver::session::Session; +use ast; +use diagnostic; +use visit; +use visit::Visitor; struct ShowSpanVisitor<'a> { - sess: &'a Session + span_diagnostic: &'a diagnostic::SpanHandler, } impl<'a> Visitor<()> for ShowSpanVisitor<'a> { fn visit_expr(&mut self, e: &ast::Expr, _: ()) { - self.sess.span_note(e.span, "expression"); + self.span_diagnostic.span_note(e.span, "expression"); visit::walk_expr(self, e, ()); } } -pub fn run(sess: &Session, krate: &ast::Crate) { - let mut v = ShowSpanVisitor { sess: sess }; +pub fn run(span_diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate) { + let mut v = ShowSpanVisitor { span_diagnostic: span_diagnostic }; visit::walk_crate(&mut v, krate, ()); } diff --git a/src/librustc/front/test.rs b/src/libsyntax/test.rs similarity index 83% rename from src/librustc/front/test.rs rename to src/libsyntax/test.rs index 0fce75c8369bc..8c0ac7552ebb7 100644 --- a/src/librustc/front/test.rs +++ b/src/libsyntax/test.rs @@ -13,29 +13,28 @@ #![allow(dead_code)] #![allow(unused_imports)] -use driver::session::Session; -use front::config; - use std::gc::{Gc, GC}; use std::slice; use std::mem; use std::vec; -use syntax::ast_util::*; -use syntax::attr::AttrMetaMethods; -use syntax::attr; -use syntax::codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; -use syntax::codemap; -use syntax::ext::base::ExtCtxt; -use syntax::ext::build::AstBuilder; -use syntax::ext::expand::ExpansionConfig; -use syntax::fold::Folder; -use syntax::fold; -use syntax::owned_slice::OwnedSlice; -use syntax::parse::token::InternedString; -use syntax::parse::token; -use syntax::print::pprust; -use syntax::{ast, ast_util}; -use syntax::util::small_vector::SmallVector; +use ast_util::*; +use attr::AttrMetaMethods; +use attr; +use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; +use codemap; +use diagnostic; +use config; +use ext::base::ExtCtxt; +use ext::build::AstBuilder; +use ext::expand::ExpansionConfig; +use fold::Folder; +use fold; +use owned_slice::OwnedSlice; +use parse::token::InternedString; +use parse::{token, ParseSess}; +use print::pprust; +use {ast, ast_util}; +use util::small_vector::SmallVector; struct Test { span: Span, @@ -46,8 +45,10 @@ struct Test { } struct TestCtxt<'a> { - sess: &'a Session, + sess: &'a ParseSess, + span_diagnostic: &'a diagnostic::SpanHandler, path: Vec, + reexports: Vec>, ext_cx: ExtCtxt<'a>, testfns: Vec, reexport_mod_ident: ast::Ident, @@ -57,15 +58,17 @@ struct TestCtxt<'a> { // Traverse the crate, collecting all the test functions, eliding any // existing main functions, and synthesizing a main test harness -pub fn modify_for_testing(sess: &Session, - krate: ast::Crate) -> ast::Crate { +pub fn modify_for_testing(sess: &ParseSess, + cfg: &ast::CrateConfig, + krate: ast::Crate, + span_diagnostic: &diagnostic::SpanHandler) -> ast::Crate { // We generate the test harness when building in the 'test' // configuration, either with the '--test' or '--cfg test' // command line options. let should_test = attr::contains_name(krate.config.as_slice(), "test"); if should_test { - generate_test_harness(sess, krate) + generate_test_harness(sess, krate, cfg, span_diagnostic) } else { strip_test_functions(krate) } @@ -73,8 +76,6 @@ pub fn modify_for_testing(sess: &Session, struct TestHarnessGenerator<'a> { cx: TestCtxt<'a>, - tests: Vec, - tested_submods: Vec, } impl<'a> fold::Folder for TestHarnessGenerator<'a> { @@ -97,8 +98,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { if is_test_fn(&self.cx, i) || is_bench_fn(&self.cx, i) { match i.node { ast::ItemFn(_, ast::UnsafeFn, _, _, _) => { - let sess = self.cx.sess; - sess.span_fatal(i.span, + let diag = self.cx.span_diagnostic; + diag.span_fatal(i.span, "unsafe functions cannot be used for \ tests"); } @@ -112,7 +113,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { should_fail: should_fail(i) }; self.cx.testfns.push(test); - self.tests.push(i.ident); + self.cx.reexports.push(self.cx.path.clone()); // debug!("have {} test/bench functions", // cx.testfns.len()); } @@ -130,11 +131,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { } fn fold_mod(&mut self, m: &ast::Mod) -> ast::Mod { - let tests = mem::replace(&mut self.tests, Vec::new()); - let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); + let reexports = mem::replace(&mut self.cx.reexports, Vec::new()); let mut mod_folded = fold::noop_fold_mod(m, self); - let tests = mem::replace(&mut self.tests, tests); - let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); + let reexports = mem::replace(&mut self.cx.reexports, reexports); // Remove any #[main] from the AST so it doesn't clash with // the one we're going to add. Only if compiling an executable. @@ -155,32 +154,20 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { for i in mod_folded.items.mut_iter() { *i = nomain(*i); } - if !tests.is_empty() || !tested_submods.is_empty() { - mod_folded.items.push(mk_reexport_mod(&mut self.cx, tests, - tested_submods)); - if !self.cx.path.is_empty() { - self.tested_submods.push(self.cx.path[self.cx.path.len()-1]); - } + if !reexports.is_empty() { + mod_folded.items.push(mk_reexport_mod(&mut self.cx, reexports)); + self.cx.reexports.push(self.cx.path.clone()); } mod_folded } } -fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec, - tested_submods: Vec) -> Gc { - let mut view_items = Vec::new(); - let super_ = token::str_to_ident("super"); - - view_items.extend(tests.move_iter().map(|r| { - cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public, - cx.ext_cx.path(DUMMY_SP, vec![super_, r])) - })); - view_items.extend(tested_submods.move_iter().map(|r| { - let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, cx.reexport_mod_ident]); - cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path) - })); - +fn mk_reexport_mod(cx: &mut TestCtxt, reexports: Vec>) + -> Gc { + let view_items = reexports.move_iter().map(|r| { + cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public, cx.ext_cx.path(DUMMY_SP, r)) + }).collect(); let reexport_mod = ast::Mod { inner: DUMMY_SP, view_items: view_items, @@ -196,15 +183,20 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec, } } -fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate { +fn generate_test_harness(sess: &ParseSess, + krate: ast::Crate, + cfg: &ast::CrateConfig, + sd: &diagnostic::SpanHandler) -> ast::Crate { let mut cx: TestCtxt = TestCtxt { sess: sess, - ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(), + span_diagnostic: sd, + ext_cx: ExtCtxt::new(sess, cfg.clone(), ExpansionConfig { deriving_hash_type_parameter: false, crate_name: "test".to_string(), }), path: Vec::new(), + reexports: Vec::new(), testfns: Vec::new(), reexport_mod_ident: token::str_to_ident("__test_reexports"), is_test_crate: is_test_crate(&krate), @@ -222,8 +214,6 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate { let mut fold = TestHarnessGenerator { cx: cx, - tests: Vec::new(), - tested_submods: Vec::new(), }; let res = fold.fold_crate(krate); fold.cx.ext_cx.bt_pop(); @@ -258,8 +248,8 @@ fn is_test_fn(cx: &TestCtxt, i: Gc) -> bool { } if has_test_attr && !has_test_signature(i) { - let sess = cx.sess; - sess.span_err( + let diag = cx.span_diagnostic; + diag.span_err( i.span, "functions used as tests must have signature fn() -> ()." ); @@ -290,8 +280,8 @@ fn is_bench_fn(cx: &TestCtxt, i: Gc) -> bool { } if has_bench_attr && !has_test_signature(i) { - let sess = cx.sess; - sess.span_err(i.span, "functions used as benches must have signature \ + let diag = cx.span_diagnostic; + diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> ()`"); } @@ -464,8 +454,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc { span: span }; - let mut visible_path = vec![cx.reexport_mod_ident.clone()]; - visible_path.extend(path.move_iter()); + let mut visible_path = Vec::new(); + for ident in path.move_iter() { + visible_path.push(cx.reexport_mod_ident.clone()); + visible_path.push(ident); + } let fn_path = cx.ext_cx.path_global(DUMMY_SP, visible_path); let fn_expr = box(GC) ast::Expr {