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/proc_macro_impl.rs | |
| 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/proc_macro_impl.rs')
| -rw-r--r-- | src/libsyntax_ext/proc_macro_impl.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs new file mode 100644 index 00000000000..b454628acb1 --- /dev/null +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -0,0 +1,58 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::panic; + +use errors::FatalError; + +use syntax::codemap::Span; +use syntax::ext::base::*; +use syntax::tokenstream::TokenStream; +use syntax::ext::base; + +use proc_macro::TokenStream as TsShim; +use proc_macro::__internal; + +pub struct AttrProcMacro { + pub inner: fn(TsShim, TsShim) -> TsShim, +} + +impl base::AttrProcMacro for AttrProcMacro { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt, + span: Span, + annotation: TokenStream, + annotated: TokenStream) + -> TokenStream { + let annotation = __internal::token_stream_wrap(annotation); + let annotated = __internal::token_stream_wrap(annotated); + + let res = __internal::set_parse_sess(&ecx.parse_sess, || { + panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(annotation, annotated))) + }); + + match res { + Ok(stream) => __internal::token_stream_inner(stream), + Err(e) => { + let msg = "custom attribute panicked"; + let mut err = ecx.struct_span_fatal(span, msg); + if let Some(s) = e.downcast_ref::<String>() { + err.help(&format!("message: {}", s)); + } + if let Some(s) = e.downcast_ref::<&'static str>() { + err.help(&format!("message: {}", s)); + } + + err.emit(); + panic!(FatalError); + } + } + } +} |
