Expand generated test harnesses and macro registries.
This commit is contained in:
parent
f3c2dca353
commit
78c0039878
3 changed files with 27 additions and 28 deletions
|
@ -690,6 +690,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
|
||||||
|
|
||||||
krate = time(time_passes, "maybe building test harness", || {
|
krate = time(time_passes, "maybe building test harness", || {
|
||||||
syntax::test::modify_for_testing(&sess.parse_sess,
|
syntax::test::modify_for_testing(&sess.parse_sess,
|
||||||
|
&mut resolver,
|
||||||
sess.opts.test,
|
sess.opts.test,
|
||||||
krate,
|
krate,
|
||||||
sess.diagnostic())
|
sess.diagnostic())
|
||||||
|
@ -700,6 +701,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
|
||||||
let is_rustc_macro_crate = crate_types.contains(&config::CrateTypeRustcMacro);
|
let is_rustc_macro_crate = crate_types.contains(&config::CrateTypeRustcMacro);
|
||||||
let num_crate_types = crate_types.len();
|
let num_crate_types = crate_types.len();
|
||||||
syntax_ext::rustc_macro_registrar::modify(&sess.parse_sess,
|
syntax_ext::rustc_macro_registrar::modify(&sess.parse_sess,
|
||||||
|
&mut resolver,
|
||||||
krate,
|
krate,
|
||||||
is_rustc_macro_crate,
|
is_rustc_macro_crate,
|
||||||
num_crate_types,
|
num_crate_types,
|
||||||
|
|
|
@ -28,7 +28,7 @@ use errors;
|
||||||
use errors::snippet::{SnippetData};
|
use errors::snippet::{SnippetData};
|
||||||
use config;
|
use config;
|
||||||
use entry::{self, EntryPointType};
|
use entry::{self, EntryPointType};
|
||||||
use ext::base::{ExtCtxt, DummyResolver};
|
use ext::base::{ExtCtxt, Resolver};
|
||||||
use ext::build::AstBuilder;
|
use ext::build::AstBuilder;
|
||||||
use ext::expand::ExpansionConfig;
|
use ext::expand::ExpansionConfig;
|
||||||
use fold::Folder;
|
use fold::Folder;
|
||||||
|
@ -70,6 +70,7 @@ struct TestCtxt<'a> {
|
||||||
// Traverse the crate, collecting all the test functions, eliding any
|
// Traverse the crate, collecting all the test functions, eliding any
|
||||||
// existing main functions, and synthesizing a main test harness
|
// existing main functions, and synthesizing a main test harness
|
||||||
pub fn modify_for_testing(sess: &ParseSess,
|
pub fn modify_for_testing(sess: &ParseSess,
|
||||||
|
resolver: &mut Resolver,
|
||||||
should_test: bool,
|
should_test: bool,
|
||||||
krate: ast::Crate,
|
krate: ast::Crate,
|
||||||
span_diagnostic: &errors::Handler) -> ast::Crate {
|
span_diagnostic: &errors::Handler) -> ast::Crate {
|
||||||
|
@ -82,7 +83,7 @@ pub fn modify_for_testing(sess: &ParseSess,
|
||||||
"reexport_test_harness_main");
|
"reexport_test_harness_main");
|
||||||
|
|
||||||
if should_test {
|
if should_test {
|
||||||
generate_test_harness(sess, reexport_test_harness_main, krate, span_diagnostic)
|
generate_test_harness(sess, resolver, reexport_test_harness_main, krate, span_diagnostic)
|
||||||
} else {
|
} else {
|
||||||
krate
|
krate
|
||||||
}
|
}
|
||||||
|
@ -248,27 +249,28 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
||||||
}).chain(tested_submods.into_iter().map(|(r, sym)| {
|
}).chain(tested_submods.into_iter().map(|(r, sym)| {
|
||||||
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
|
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
|
||||||
cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Visibility::Public, r, path)
|
cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Visibility::Public, r, path)
|
||||||
}));
|
})).collect();
|
||||||
|
|
||||||
let reexport_mod = ast::Mod {
|
let reexport_mod = ast::Mod {
|
||||||
inner: DUMMY_SP,
|
inner: DUMMY_SP,
|
||||||
items: items.collect(),
|
items: items,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sym = token::gensym_ident("__test_reexports");
|
let sym = token::gensym_ident("__test_reexports");
|
||||||
let it = P(ast::Item {
|
let it = cx.ext_cx.expander().fold_item(P(ast::Item {
|
||||||
ident: sym.clone(),
|
ident: sym.clone(),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ItemKind::Mod(reexport_mod),
|
node: ast::ItemKind::Mod(reexport_mod),
|
||||||
vis: ast::Visibility::Public,
|
vis: ast::Visibility::Public,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
});
|
})).pop().unwrap();
|
||||||
|
|
||||||
(it, sym)
|
(it, sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_test_harness(sess: &ParseSess,
|
fn generate_test_harness(sess: &ParseSess,
|
||||||
|
resolver: &mut Resolver,
|
||||||
reexport_test_harness_main: Option<InternedString>,
|
reexport_test_harness_main: Option<InternedString>,
|
||||||
krate: ast::Crate,
|
krate: ast::Crate,
|
||||||
sd: &errors::Handler) -> ast::Crate {
|
sd: &errors::Handler) -> ast::Crate {
|
||||||
|
@ -276,13 +278,10 @@ fn generate_test_harness(sess: &ParseSess,
|
||||||
let mut cleaner = EntryPointCleaner { depth: 0 };
|
let mut cleaner = EntryPointCleaner { depth: 0 };
|
||||||
let krate = cleaner.fold_crate(krate);
|
let krate = cleaner.fold_crate(krate);
|
||||||
|
|
||||||
let mut resolver = DummyResolver;
|
|
||||||
let mut cx: TestCtxt = TestCtxt {
|
let mut cx: TestCtxt = TestCtxt {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
span_diagnostic: sd,
|
span_diagnostic: sd,
|
||||||
ext_cx: ExtCtxt::new(sess, vec![],
|
ext_cx: ExtCtxt::new(sess, vec![], ExpansionConfig::default("test".to_string()), resolver),
|
||||||
ExpansionConfig::default("test".to_string()),
|
|
||||||
&mut resolver),
|
|
||||||
path: Vec::new(),
|
path: Vec::new(),
|
||||||
testfns: Vec::new(),
|
testfns: Vec::new(),
|
||||||
reexport_test_harness_main: reexport_test_harness_main,
|
reexport_test_harness_main: reexport_test_harness_main,
|
||||||
|
@ -511,16 +510,17 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
|
||||||
items: vec![import, mainfn, tests],
|
items: vec![import, mainfn, tests],
|
||||||
};
|
};
|
||||||
let item_ = ast::ItemKind::Mod(testmod);
|
let item_ = ast::ItemKind::Mod(testmod);
|
||||||
|
|
||||||
let mod_ident = token::gensym_ident("__test");
|
let mod_ident = token::gensym_ident("__test");
|
||||||
let item = P(ast::Item {
|
|
||||||
|
let mut expander = cx.ext_cx.expander();
|
||||||
|
let item = expander.fold_item(P(ast::Item {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
ident: mod_ident,
|
ident: mod_ident,
|
||||||
attrs: vec![],
|
attrs: vec![],
|
||||||
node: item_,
|
node: item_,
|
||||||
vis: ast::Visibility::Public,
|
vis: ast::Visibility::Public,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
});
|
})).pop().unwrap();
|
||||||
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
|
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
|
||||||
// building `use <ident> = __test::main`
|
// building `use <ident> = __test::main`
|
||||||
let reexport_ident = token::str_to_ident(&s);
|
let reexport_ident = token::str_to_ident(&s);
|
||||||
|
@ -529,14 +529,14 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
|
||||||
nospan(ast::ViewPathSimple(reexport_ident,
|
nospan(ast::ViewPathSimple(reexport_ident,
|
||||||
path_node(vec![mod_ident, token::str_to_ident("main")])));
|
path_node(vec![mod_ident, token::str_to_ident("main")])));
|
||||||
|
|
||||||
P(ast::Item {
|
expander.fold_item(P(ast::Item {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
ident: keywords::Invalid.ident(),
|
ident: keywords::Invalid.ident(),
|
||||||
attrs: vec![],
|
attrs: vec![],
|
||||||
node: ast::ItemKind::Use(P(use_path)),
|
node: ast::ItemKind::Use(P(use_path)),
|
||||||
vis: ast::Visibility::Inherited,
|
vis: ast::Visibility::Inherited,
|
||||||
span: DUMMY_SP
|
span: DUMMY_SP
|
||||||
})
|
})).pop().unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
|
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
|
||||||
|
|
|
@ -13,12 +13,13 @@ use std::mem;
|
||||||
use errors;
|
use errors;
|
||||||
use syntax::ast::{self, Ident, NodeId};
|
use syntax::ast::{self, Ident, NodeId};
|
||||||
use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute};
|
use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute};
|
||||||
use syntax::ext::base::{ExtCtxt, DummyResolver};
|
use syntax::ext::base::ExtCtxt;
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::ext::expand::ExpansionConfig;
|
use syntax::ext::expand::ExpansionConfig;
|
||||||
use syntax::parse::ParseSess;
|
use syntax::parse::ParseSess;
|
||||||
use syntax::parse::token::{self, InternedString};
|
use syntax::parse::token::{self, InternedString};
|
||||||
use syntax::feature_gate::Features;
|
use syntax::feature_gate::Features;
|
||||||
|
use syntax::fold::Folder;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use syntax::visit::{self, Visitor};
|
use syntax::visit::{self, Visitor};
|
||||||
|
@ -39,16 +40,14 @@ struct CollectCustomDerives<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modify(sess: &ParseSess,
|
pub fn modify(sess: &ParseSess,
|
||||||
|
resolver: &mut ::syntax::ext::base::Resolver,
|
||||||
mut krate: ast::Crate,
|
mut krate: ast::Crate,
|
||||||
is_rustc_macro_crate: bool,
|
is_rustc_macro_crate: bool,
|
||||||
num_crate_types: usize,
|
num_crate_types: usize,
|
||||||
handler: &errors::Handler,
|
handler: &errors::Handler,
|
||||||
features: &Features) -> ast::Crate {
|
features: &Features) -> ast::Crate {
|
||||||
let mut loader = DummyResolver;
|
let ecfg = ExpansionConfig::default("rustc_macro".to_string());
|
||||||
let mut cx = ExtCtxt::new(sess,
|
let mut cx = ExtCtxt::new(sess, Vec::new(), ecfg, resolver);
|
||||||
Vec::new(),
|
|
||||||
ExpansionConfig::default("rustc_macro".to_string()),
|
|
||||||
&mut loader);
|
|
||||||
|
|
||||||
let mut collect = CollectCustomDerives {
|
let mut collect = CollectCustomDerives {
|
||||||
derives: Vec::new(),
|
derives: Vec::new(),
|
||||||
|
@ -268,13 +267,11 @@ fn mk_registrar(cx: &mut ExtCtxt,
|
||||||
i.vis = ast::Visibility::Public;
|
i.vis = ast::Visibility::Public;
|
||||||
i
|
i
|
||||||
});
|
});
|
||||||
let module = cx.item_mod(span,
|
let ident = ast::Ident::with_empty_ctxt(token::gensym("registrar"));
|
||||||
span,
|
let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| {
|
||||||
ast::Ident::with_empty_ctxt(token::gensym("registrar")),
|
|
||||||
Vec::new(),
|
|
||||||
vec![krate, func]);
|
|
||||||
module.map(|mut i| {
|
|
||||||
i.vis = ast::Visibility::Public;
|
i.vis = ast::Visibility::Public;
|
||||||
i
|
i
|
||||||
})
|
});
|
||||||
|
|
||||||
|
cx.expander().fold_item(module).pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue