]> git.proxmox.com Git - rustc.git/blame - src/libsyntax_ext/plugin_macro_defs.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / src / libsyntax_ext / plugin_macro_defs.rs
CommitLineData
416331ca
XL
1//! Each macro must have a definition, so `#[plugin]` attributes
2//! inject a dummy `macro_rules` item for each macro they define.
3
4use syntax::ast::*;
5use syntax::attr;
6use syntax::edition::Edition;
e74abb32 7use syntax_expand::base::{Resolver, NamedSyntaxExtension};
416331ca
XL
8use syntax::parse::token;
9use syntax::ptr::P;
10use syntax::source_map::respan;
11use syntax::symbol::sym;
12use syntax::tokenstream::*;
13use syntax_pos::{Span, DUMMY_SP};
e1599b0c 14use syntax_pos::hygiene::{ExpnData, ExpnKind, AstPass};
416331ca
XL
15
16use std::mem;
17
18fn 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(
e74abb32 23 DelimSpan::from_single(span), token::Paren, TokenStream::default()
416331ca
XL
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,
e74abb32 31 kind: ItemKind::MacroDef(MacroDef { tokens: TokenStream::new(trees), legacy: true }),
416331ca
XL
32 vis: respan(span, VisibilityKind::Inherited),
33 span: span,
34 tokens: None,
35 })
36}
37
38pub 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();
e1599b0c
XL
46 let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
47 ExpnKind::AstPass(AstPass::PluginMacroDefs), DUMMY_SP, edition,
416331ca
XL
48 [sym::rustc_attrs][..].into(),
49 ));
50 for (name, ext) in named_exts {
e1599b0c 51 resolver.register_builtin_macro(Ident::with_dummy_span(name), ext);
416331ca
XL
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}