]> git.lizzy.rs Git - rust.git/blob - src/libsyntax_ext/test_case.rs
Auto merge of #60763 - matklad:tt-parser, r=petrochenkov
[rust.git] / src / libsyntax_ext / test_case.rs
1 // http://rust-lang.org/COPYRIGHT.
2 //
3
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.
8 //
9 // We mark item with an inert attribute "rustc_test_marker" which the test generation
10 // logic will pick up on.
11
12 use syntax::ext::base::*;
13 use syntax::ext::build::AstBuilder;
14 use syntax::ext::hygiene::{self, Mark, SyntaxContext};
15 use syntax::ast;
16 use syntax::source_map::respan;
17 use syntax::symbol::{Symbol, sym};
18 use syntax_pos::{DUMMY_SP, Span};
19 use syntax::source_map::{ExpnInfo, MacroAttribute};
20 use syntax::feature_gate;
21
22 pub fn expand(
23     ecx: &mut ExtCtxt<'_>,
24     attr_sp: Span,
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,
31                                        attr_sp,
32                                        feature_gate::GateIssue::Language,
33                                        feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
34     }
35
36     if !ecx.ecfg.should_test { return vec![]; }
37
38     let sp = {
39         let mark = Mark::fresh(Mark::root());
40         mark.set_expn_info(ExpnInfo {
41             call_site: DUMMY_SP,
42             def_site: None,
43             format: MacroAttribute(Symbol::intern("test_case")),
44             allow_internal_unstable: Some(vec![
45                 Symbol::intern("test"),
46                 Symbol::intern("rustc_attrs"),
47             ].into()),
48             allow_internal_unsafe: false,
49             local_inner_macros: false,
50             edition: hygiene::default_edition(),
51         });
52         attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
53     };
54
55     let mut item = anno_item.expect_item();
56
57     item = item.map(|mut item| {
58         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
59         item.ident = item.ident.gensym();
60         item.attrs.push(
61             ecx.attribute(sp,
62                 ecx.meta_word(sp, Symbol::intern("rustc_test_marker")))
63         );
64         item
65     });
66
67     return vec![Annotatable::Item(item)]
68 }