]> git.proxmox.com Git - rustc.git/blob - src/libsyntax_ext/proc_macro_impl.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / libsyntax_ext / proc_macro_impl.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::panic;
12
13 use errors::FatalError;
14
15 use syntax::codemap::Span;
16 use syntax::ext::base::*;
17 use syntax::tokenstream::TokenStream;
18 use syntax::ext::base;
19
20 use proc_macro::TokenStream as TsShim;
21 use proc_macro::__internal;
22
23 pub struct AttrProcMacro {
24 pub inner: fn(TsShim, TsShim) -> TsShim,
25 }
26
27 impl base::AttrProcMacro for AttrProcMacro {
28 fn expand<'cx>(&self,
29 ecx: &'cx mut ExtCtxt,
30 span: Span,
31 annotation: TokenStream,
32 annotated: TokenStream)
33 -> TokenStream {
34 let annotation = __internal::token_stream_wrap(annotation);
35 let annotated = __internal::token_stream_wrap(annotated);
36
37 let res = __internal::set_parse_sess(&ecx.parse_sess, || {
38 panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(annotation, annotated)))
39 });
40
41 match res {
42 Ok(stream) => __internal::token_stream_inner(stream),
43 Err(e) => {
44 let msg = "custom attribute panicked";
45 let mut err = ecx.struct_span_fatal(span, msg);
46 if let Some(s) = e.downcast_ref::<String>() {
47 err.help(&format!("message: {}", s));
48 }
49 if let Some(s) = e.downcast_ref::<&'static str>() {
50 err.help(&format!("message: {}", s));
51 }
52
53 err.emit();
54 panic!(FatalError);
55 }
56 }
57 }
58 }
59
60 pub struct BangProcMacro {
61 pub inner: fn(TsShim) -> TsShim,
62 }
63
64 impl base::ProcMacro for BangProcMacro {
65 fn expand<'cx>(&self,
66 ecx: &'cx mut ExtCtxt,
67 span: Span,
68 input: TokenStream)
69 -> TokenStream {
70 let input = __internal::token_stream_wrap(input);
71
72 let res = __internal::set_parse_sess(&ecx.parse_sess, || {
73 panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input)))
74 });
75
76 match res {
77 Ok(stream) => __internal::token_stream_inner(stream),
78 Err(e) => {
79 let msg = "proc macro panicked";
80 let mut err = ecx.struct_span_fatal(span, msg);
81 if let Some(s) = e.downcast_ref::<String>() {
82 err.help(&format!("message: {}", s));
83 }
84 if let Some(s) = e.downcast_ref::<&'static str>() {
85 err.help(&format!("message: {}", s));
86 }
87
88 err.emit();
89 panic!(FatalError);
90 }
91 }
92 }
93 }