]> git.lizzy.rs Git - rust.git/blob - src/libsyntax_ext/plugin_macro_defs.rs
syntax::parser::token -> syntax::token
[rust.git] / src / libsyntax_ext / plugin_macro_defs.rs
1 //! Each macro must have a definition, so `#[plugin]` attributes
2 //! inject a dummy `macro_rules` item for each macro they define.
3
4 use syntax::ast::*;
5 use syntax::attr;
6 use syntax::edition::Edition;
7 use syntax::ptr::P;
8 use syntax::source_map::respan;
9 use syntax::symbol::sym;
10 use syntax::token;
11 use syntax::tokenstream::*;
12 use syntax_expand::base::{Resolver, NamedSyntaxExtension};
13 use syntax_pos::{Span, DUMMY_SP};
14 use syntax_pos::hygiene::{ExpnData, ExpnKind, AstPass};
15
16 use std::mem;
17
18 fn plugin_macro_def(name: Name, span: Span) -> P<Item> {
19     let rustc_builtin_macro = attr::mk_attr_outer(
20         attr::mk_word_item(Ident::new(sym::rustc_builtin_macro, span)));
21
22     let parens: TreeAndJoint = TokenTree::Delimited(
23         DelimSpan::from_single(span), token::Paren, TokenStream::default()
24     ).into();
25     let trees = vec![parens.clone(), TokenTree::token(token::FatArrow, span).into(), parens];
26
27     P(Item {
28         ident: Ident::new(name, span),
29         attrs: vec![rustc_builtin_macro],
30         id: DUMMY_NODE_ID,
31         kind: ItemKind::MacroDef(MacroDef { tokens: TokenStream::new(trees), legacy: true }),
32         vis: respan(span, VisibilityKind::Inherited),
33         span: span,
34         tokens: None,
35     })
36 }
37
38 pub fn inject(
39     krate: &mut Crate,
40     resolver: &mut dyn Resolver,
41     named_exts: Vec<NamedSyntaxExtension>,
42     edition: Edition,
43 ) {
44     if !named_exts.is_empty() {
45         let mut extra_items = Vec::new();
46         let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
47             ExpnKind::AstPass(AstPass::PluginMacroDefs), DUMMY_SP, edition,
48             [sym::rustc_attrs][..].into(),
49         ));
50         for (name, ext) in named_exts {
51             resolver.register_builtin_macro(Ident::with_dummy_span(name), ext);
52             extra_items.push(plugin_macro_def(name, span));
53         }
54         // The `macro_rules` items must be inserted before any other items.
55         mem::swap(&mut extra_items, &mut krate.module.items);
56         krate.module.items.append(&mut extra_items);
57     }
58 }