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
use std::collections::HashSet;
use std::str::FromStr;
use proc_macro2::TokenStream;
use proc_macro_error::emit_warning;
use quote::ToTokens;
use syn::ImplItemMethod;
use syn::visit::Visit;
use crate::transformation::{AttributeFilter, CallTypeAttribute};
pub(crate) fn get_call_type(node: &ImplItemMethod) -> Option<CallTypeAttribute> {
let whitelist = {
let mut f = HashSet::new();
f.insert(syn::parse2(TokenStream::from_str("call_type").unwrap()).unwrap());
f
};
let mut attributes_collector = AttributeFilter::with_whitelist(whitelist);
attributes_collector.visit_impl_item_method(&node);
let call_type_attribute = attributes_collector.filtered_attributes.first().and_then(|call_type_attr| {
syn::parse2(call_type_attr.to_token_stream()).map_err(|e| {
emit_warning!(e.span(), format!("invalid parsing of `call_type` attribute, defaulting to #[call_type(safe)]. {}", e));
e
}).ok()
});
call_type_attribute
}
macro_rules! parse_quote_spanned {
($span:expr => $($tt:tt)*) => {
syn::parse2(quote::quote_spanned!($span => $($tt)*)).unwrap_or_else(|e| panic!("{}", e))
};
}