about summary refs log tree commit diff
path: root/src/libsyntax_ext/proc_macro_impl.rs
diff options
context:
space:
mode:
authorAustin Bonander <austin.bonander@gmail.com>2017-01-09 01:31:14 -0800
committerAustin Bonander <austin.bonander@gmail.com>2017-01-16 22:41:22 -0800
commit375cbd20cfcc9dbf15682bcfc0081ce5ce95567b (patch)
tree6eee726bbefda54496b97963b696404cc50287aa /src/libsyntax_ext/proc_macro_impl.rs
parentf6c0c4837c303e327a8b37649dd72f115b48f309 (diff)
downloadrust-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.rs58
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);
+            }
+        }
+    }
+}