diff options
| author | Austin Bonander <austin.bonander@gmail.com> | 2017-01-09 01:31:14 -0800 |
|---|---|---|
| committer | Austin Bonander <austin.bonander@gmail.com> | 2017-01-16 22:41:22 -0800 |
| commit | 375cbd20cfcc9dbf15682bcfc0081ce5ce95567b (patch) | |
| tree | 6eee726bbefda54496b97963b696404cc50287aa /src/libsyntax/ext | |
| parent | f6c0c4837c303e327a8b37649dd72f115b48f309 (diff) | |
| download | rust-375cbd20cfcc9dbf15682bcfc0081ce5ce95567b.tar.gz rust-375cbd20cfcc9dbf15682bcfc0081ce5ce95567b.zip | |
Implement `#[proc_macro_attribute]`
* Add support for `#[proc_macro]` * Reactivate `proc_macro` feature and gate `#[proc_macro_attribute]` under it * Have `#![feature(proc_macro)]` imply `#![feature(use_extern_macros)]`, error on legacy import of proc macros via `#[macro_use]`
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 201e8d69494..1f7874274f7 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -364,7 +364,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { kind.expect_from_annotatables(items) } SyntaxExtension::AttrProcMacro(ref mac) => { - let attr_toks = TokenStream::from_tts(tts_for_attr(&attr, &self.cx.parse_sess)); + let attr_toks = TokenStream::from_tts(tts_for_attr_args(&attr, + &self.cx.parse_sess)); + let item_toks = TokenStream::from_tts(tts_for_item(&item, &self.cx.parse_sess)); let tok_result = mac.expand(self.cx, attr.span, attr_toks, item_toks); @@ -640,8 +642,30 @@ fn tts_for_item(item: &Annotatable, parse_sess: &ParseSess) -> Vec<TokenTree> { string_to_tts(text, parse_sess) } -fn tts_for_attr(attr: &ast::Attribute, parse_sess: &ParseSess) -> Vec<TokenTree> { - string_to_tts(pprust::attr_to_string(attr), parse_sess) +fn tts_for_attr_args(attr: &ast::Attribute, parse_sess: &ParseSess) -> Vec<TokenTree> { + use ast::MetaItemKind::*; + use print::pp::Breaks; + use print::pprust::PrintState; + + let token_string = match attr.value.node { + // For `#[foo]`, an empty token + Word => return vec![], + // For `#[foo(bar, baz)]`, returns `(bar, baz)` + List(ref items) => pprust::to_string(|s| { + s.popen()?; + s.commasep(Breaks::Consistent, + &items[..], + |s, i| s.print_meta_list_item(&i))?; + s.pclose() + }), + // For `#[foo = "bar"]`, returns `= "bar"` + NameValue(ref lit) => pprust::to_string(|s| { + s.word_space("=")?; + s.print_literal(lit) + }), + }; + + string_to_tts(token_string, parse_sess) } fn string_to_tts(text: String, parse_sess: &ParseSess) -> Vec<TokenTree> { |
