1 // http://rust-lang.org/COPYRIGHT.
4 // #[test_case] is used by custom test authors to mark tests
5 // When building for test, it needs to make the item public and gensym the name
6 // Otherwise, we'll omit the item. This behavior means that any item annotated
7 // with #[test_case] is never addressable.
9 // We mark item with an inert attribute "rustc_test_marker" which the test generation
10 // logic will pick up on.
12 use syntax::ext::base::*;
13 use syntax::ext::build::AstBuilder;
14 use syntax::ext::hygiene::{Mark, SyntaxContext};
16 use syntax::source_map::respan;
17 use syntax::symbol::sym;
18 use syntax_pos::{DUMMY_SP, Span};
19 use syntax::source_map::{ExpnInfo, MacroAttribute};
20 use syntax::feature_gate;
23 ecx: &mut ExtCtxt<'_>,
25 _meta_item: &ast::MetaItem,
26 anno_item: Annotatable
27 ) -> Vec<Annotatable> {
28 if !ecx.ecfg.enable_custom_test_frameworks() {
29 feature_gate::emit_feature_err(&ecx.parse_sess,
30 sym::custom_test_frameworks,
32 feature_gate::GateIssue::Language,
33 feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
36 if !ecx.ecfg.should_test { return vec![]; }
39 let mark = Mark::fresh(Mark::root());
40 mark.set_expn_info(ExpnInfo {
43 format: MacroAttribute(sym::test_case),
44 allow_internal_unstable: Some(vec![sym::test, sym::rustc_attrs].into()),
45 allow_internal_unsafe: false,
46 local_inner_macros: false,
47 edition: ecx.parse_sess.edition,
49 attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
52 let mut item = anno_item.expect_item();
54 item = item.map(|mut item| {
55 item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
56 item.ident = item.ident.gensym();
59 ecx.meta_word(sp, sym::rustc_test_marker))
64 return vec![Annotatable::Item(item)]