diff options
| author | bors <bors@rust-lang.org> | 2018-09-05 07:30:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-09-05 07:30:19 +0000 |
| commit | 3f13b27c2b6a1f83ee08a87c6134c86526edffc0 (patch) | |
| tree | 851bd551452a99115a72773b871f0d0f1433fcc4 /src/libsyntax/ext | |
| parent | 0be2c303692cab31390e52701007cfa87867bf74 (diff) | |
| parent | 0593dc7e3c9783f1c0bbbc8f017f9e914114e057 (diff) | |
| download | rust-3f13b27c2b6a1f83ee08a87c6134c86526edffc0.tar.gz rust-3f13b27c2b6a1f83ee08a87c6134c86526edffc0.zip | |
Auto merge of #53410 - djrenren:custom-test-frameworks, r=alexcrichton
Introduce Custom Test Frameworks Introduces `#[test_case]` and `#[test_runner]` and re-implements `#[test]` and `#[bench]` in terms of them. Details found here: https://blog.jrenner.net/rust/testing/2018/08/06/custom-test-framework-prop.html
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 80 |
2 files changed, 9 insertions, 74 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index e8a68b6d767..0e059bc4a6c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -721,6 +721,7 @@ pub trait Resolver { fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>); + fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>); fn resolve_imports(&mut self); // Resolves attribute and derive legacy macros from `#![plugin(..)]`. @@ -729,6 +730,7 @@ pub trait Resolver { fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool) -> Result<Option<Lrc<SyntaxExtension>>, Determinacy>; + fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark, derives_in_scope: &[ast::Path], force: bool) -> Result<Lrc<SyntaxExtension>, Determinacy>; @@ -759,6 +761,7 @@ impl Resolver for DummyResolver { fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment, _derives: &[Mark]) {} fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {} + fn add_unshadowable_attr(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {} fn resolve_imports(&mut self) {} fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6e38f820586..3bb19121ee3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -12,10 +12,9 @@ use ast::{self, Block, Ident, NodeId, PatKind, Path}; use ast::{MacStmtStyle, StmtKind, ItemKind}; use attr::{self, HasAttrs}; use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan}; -use config::{is_test_or_bench, StripUnconfigured}; +use config::StripUnconfigured; use errors::{Applicability, FatalError}; use ext::base::*; -use ext::build::AstBuilder; use ext::derive::{add_derived_markers, collect_derives}; use ext::hygiene::{self, Mark, SyntaxContext}; use ext::placeholders::{placeholder, PlaceholderExpander}; @@ -37,7 +36,6 @@ use visit::{self, Visitor}; use rustc_data_structures::fx::FxHashMap; use std::fs::File; use std::io::Read; -use std::iter::FromIterator; use std::{iter, mem}; use std::rc::Rc; use std::path::PathBuf; @@ -452,14 +450,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let (fragment_with_placeholders, invocations) = { let mut collector = InvocationCollector { cfg: StripUnconfigured { - should_test: self.cx.ecfg.should_test, sess: self.cx.parse_sess, features: self.cx.ecfg.features, }, cx: self.cx, invocations: Vec::new(), monotonic: self.monotonic, - tests_nameable: true, }; (fragment.fold_with(&mut collector), collector.invocations) }; @@ -477,7 +473,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn fully_configure(&mut self, item: Annotatable) -> Annotatable { let mut cfg = StripUnconfigured { - should_test: self.cx.ecfg.should_test, sess: self.cx.parse_sess, features: self.cx.ecfg.features, }; @@ -1049,11 +1044,6 @@ struct InvocationCollector<'a, 'b: 'a> { cfg: StripUnconfigured<'a>, invocations: Vec<Invocation>, monotonic: bool, - - /// Test functions need to be nameable. Tests inside functions or in other - /// unnameable locations need to be ignored. `tests_nameable` tracks whether - /// any test functions found in the current context would be nameable. - tests_nameable: bool, } impl<'a, 'b> InvocationCollector<'a, 'b> { @@ -1071,20 +1061,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { placeholder(fragment_kind, NodeId::placeholder_from_mark(mark)) } - /// Folds the item allowing tests to be expanded because they are still nameable. - /// This should probably only be called with module items - fn fold_nameable(&mut self, item: P<ast::Item>) -> OneVector<P<ast::Item>> { - fold::noop_fold_item(item, self) - } - - /// Folds the item but doesn't allow tests to occur within it - fn fold_unnameable(&mut self, item: P<ast::Item>) -> OneVector<P<ast::Item>> { - let was_nameable = mem::replace(&mut self.tests_nameable, false); - let items = fold::noop_fold_item(item, self); - self.tests_nameable = was_nameable; - items - } - fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment { self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span }) } @@ -1299,7 +1275,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { fn fold_item(&mut self, item: P<ast::Item>) -> OneVector<P<ast::Item>> { let item = configure!(self, item); - let (attr, traits, mut item) = self.classify_item(item); + let (attr, traits, item) = self.classify_item(item); if attr.is_some() || !traits.is_empty() { let item = Annotatable::Item(item); return self.collect_attr(attr, traits, item, AstFragmentKind::Items).make_items(); @@ -1321,7 +1297,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } ast::ItemKind::Mod(ast::Mod { inner, .. }) => { if item.ident == keywords::Invalid.ident() { - return self.fold_nameable(item); + return noop_fold_item(item, self); } let orig_directory_ownership = self.cx.current_expansion.directory_ownership; @@ -1361,58 +1337,13 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let orig_module = mem::replace(&mut self.cx.current_expansion.module, Rc::new(module)); - let result = self.fold_nameable(item); + let result = noop_fold_item(item, self); self.cx.current_expansion.module = orig_module; self.cx.current_expansion.directory_ownership = orig_directory_ownership; result } - // Ensure that test functions are accessible from the test harness. - // #[test] fn foo() {} - // becomes: - // #[test] pub fn foo_gensym(){} - // #[allow(unused)] - // use foo_gensym as foo; - ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => { - if self.tests_nameable && item.attrs.iter().any(|attr| is_test_or_bench(attr)) { - let orig_ident = item.ident; - let orig_vis = item.vis.clone(); - - // Publicize the item under gensymed name to avoid pollution - item = item.map(|mut item| { - item.vis = respan(item.vis.span, ast::VisibilityKind::Public); - item.ident = item.ident.gensym(); - item - }); - - // Use the gensymed name under the item's original visibility - let mut use_item = self.cx.item_use_simple_( - item.ident.span, - orig_vis, - Some(orig_ident), - self.cx.path(item.ident.span, - vec![keywords::SelfValue.ident(), item.ident])); - - // #[allow(unused)] because the test function probably isn't being referenced - use_item = use_item.map(|mut ui| { - ui.attrs.push( - self.cx.attribute(DUMMY_SP, attr::mk_list_item(DUMMY_SP, - Ident::from_str("allow"), vec![ - attr::mk_nested_word_item(Ident::from_str("unused")) - ] - )) - ); - - ui - }); - OneVector::from_iter( - self.fold_unnameable(item).into_iter() - .chain(self.fold_unnameable(use_item))) - } else { - self.fold_unnameable(item) - } - } - _ => self.fold_unnameable(item), + _ => noop_fold_item(item, self), } } @@ -1637,6 +1568,7 @@ impl<'feat> ExpansionConfig<'feat> { feature_tests! { fn enable_quotes = quote, fn enable_asm = asm, + fn enable_custom_test_frameworks = custom_test_frameworks, fn enable_global_asm = global_asm, fn enable_log_syntax = log_syntax, fn enable_concat_idents = concat_idents, |
