1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#![crate_type="dylib"]
#![cfg_attr(not(feature = "with-syntex"), feature(plugin, plugin_registrar, quote, rustc_private))]
extern crate syn;
#[macro_use]
extern crate quote;
#[cfg(not(feature = "with-syntex"))]
extern crate syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate rustc_plugin;
#[cfg(feature = "with-syntex")]
extern crate syntex;
#[cfg(feature = "with-syntex")]
extern crate syntex_syntax as syntax;
#[cfg(feature = "with-syntex")]
use std::path::Path;
mod util;
mod tuple;
mod map;
#[cfg(feature = "with-syntex")]
pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
where S: AsRef<Path>, D: AsRef<Path>
{
let mut reg = syntex::Registry::new();
reg.add_decorator("derive_NifMap", map_transcoder_decorator_shim);
reg.add_decorator("derive_NifTuple", tuple_transcoder_decorator_shim);
reg.expand("", src.as_ref(), dst.as_ref())
}
macro_rules! shim_syn_decorator {
($decorator_name:ident, $shim_name:ident, $wrapped:path) => {
fn $shim_name(
cx: &mut syntax::ext::base::ExtCtxt,
span: syntax::codemap::Span,
meta_item: &syntax::ast::MetaItem,
annotatable: &syntax::ext::base::Annotatable,
push: &mut FnMut(syntax::ext::base::Annotatable),
) {
let item = match *annotatable {
syntax::ext::base::Annotatable::Item(ref item) => item,
_ => {
cx.span_err(
meta_item.span,
"decorated item must be either struct or enum"
);
return;
},
};
let s = syntax::print::pprust::item_to_string(item);
let syn_item = syn::parse_macro_input(&s).unwrap();
let expanded = match $wrapped(&syn_item) {
Ok(expanded) => expanded.to_string(),
Err(msg) => {
cx.span_err(span, &msg);
return;
}
};
use syntax::parse;
let name = stringify!($decorator_name).to_string();
let sess = parse::ParseSess::new();
let impl_item = parse::parse_item_from_source_str(name, expanded, &sess);
push(syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
}
};
}
shim_syn_decorator!(NifTuple, tuple_transcoder_decorator_shim, tuple::transcoder_decorator);
shim_syn_decorator!(NifMap, map_transcoder_decorator_shim, map::transcoder_decorator);
#[cfg(not(feature = "with-syntex"))]
#[plugin_registrar]
pub fn register(reg: &mut rustc_plugin::Registry) {
reg.register_syntax_extension(
syntax::parse::token::intern("derive_NifMap"),
syntax::ext::base::MultiDecorator(Box::new(map_transcoder_decorator_shim)));
reg.register_syntax_extension(
syntax::parse::token::intern("derive_NifTuple"),
syntax::ext::base::MultiDecorator(Box::new(tuple_transcoder_decorator_shim)));
}