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
#![recursion_limit = "128"]
extern crate proc_macro;
use proc_macro::TokenStream;
use near_bindgen_core::*;
use proc_macro2::Span;
use quote::quote;
use syn::{File, ItemImpl, ItemStruct, ItemTrait};
#[proc_macro_attribute]
pub fn near_bindgen(_attr: TokenStream, item: TokenStream) -> TokenStream {
if let Ok(input) = syn::parse::<ItemStruct>(item.clone()) {
let sys_file = rust_file(include_bytes!("../res/sys.rs"));
let near_environment = rust_file(include_bytes!("../res/near_blockchain.rs"));
return TokenStream::from(quote! {
#input
#sys_file
#near_environment
});
} else if let Ok(mut input) = syn::parse::<ItemImpl>(item) {
let item_impl_info = match ItemImplInfo::new(&mut input) {
Ok(x) => x,
Err(err) => {
return err.to_compile_error().into();
}
};
let generated_code = item_impl_info.wrapper_code();
TokenStream::from(quote! {
#input
#generated_code
})
} else {
TokenStream::from(
syn::Error::new(
Span::call_site(),
"near_bindgen can only be used on type declarations and impl sections.",
)
.to_compile_error(),
)
}
}
fn rust_file(data: &[u8]) -> File {
let data = std::str::from_utf8(data).unwrap();
syn::parse_file(data).unwrap()
}
#[proc_macro_attribute]
pub fn ext_contract(attr: TokenStream, item: TokenStream) -> TokenStream {
if let Ok(mut input) = syn::parse::<ItemTrait>(item.clone()) {
let mut mod_name: Option<proc_macro2::Ident> = None;
if !attr.is_empty() {
mod_name = match syn::parse(attr) {
Ok(x) => x,
Err(err) => {
return TokenStream::from(
syn::Error::new(
Span::call_site(),
format!("Failed to parse mod name for ext_contract: {}", err),
)
.to_compile_error(),
)
}
};
}
let item_trait_info = match ItemTraitInfo::new(&mut input, mod_name) {
Ok(x) => x,
Err(err) => return TokenStream::from(err.to_compile_error()),
};
item_trait_info.wrapped_module().into()
} else {
TokenStream::from(
syn::Error::new(Span::call_site(), "ext_contract can only be used on traits")
.to_compile_error(),
)
}
}
#[proc_macro_attribute]
pub fn callback(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn callback_vec(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn serializer(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn result_serializer(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn init(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}