2019-01-19 20:29:29 +00:00
|
|
|
use crate::model::{self, ExtDefinition, ExternalFunc, Param};
|
|
|
|
use syn::{ItemImpl, ImplItem, ImplItemMethod, FnArg, ReturnType, Ident};
|
2019-01-19 00:31:47 +00:00
|
|
|
use syn::spanned::Spanned;
|
|
|
|
|
2019-01-19 20:59:32 +00:00
|
|
|
/// Parse an incoming stream of tokens into externalities definition.
|
2019-01-19 00:31:47 +00:00
|
|
|
pub fn parse(input: proc_macro2::TokenStream) -> Result<ExtDefinition, ()> {
|
|
|
|
let item_impl = syn::parse2::<syn::ItemImpl>(input).map_err(|_| ())?;
|
|
|
|
|
|
|
|
let mut funcs = vec![];
|
|
|
|
|
|
|
|
for item in item_impl.items {
|
|
|
|
match item {
|
|
|
|
ImplItem::Method(ImplItemMethod {
|
|
|
|
sig,
|
|
|
|
..
|
|
|
|
}) => {
|
|
|
|
let index = funcs.len() as u32;
|
|
|
|
|
|
|
|
// self TODO: handle this properly
|
2019-01-19 20:29:29 +00:00
|
|
|
let args = sig.decl.inputs.iter().skip(1).enumerate().map(|(idx, input)| {
|
|
|
|
let param_name = format!("arg{}", idx);
|
|
|
|
let ident = Ident::new(¶m_name, input.span());
|
|
|
|
Param {
|
|
|
|
ident,
|
|
|
|
}
|
2019-01-19 00:31:47 +00:00
|
|
|
}).collect::<Vec<_>>();
|
|
|
|
|
|
|
|
let return_ty = match sig.decl.output {
|
|
|
|
ReturnType::Default => None,
|
|
|
|
ReturnType::Type(_, ty) => Some(ty.span()),
|
|
|
|
};
|
|
|
|
|
|
|
|
funcs.push(ExternalFunc {
|
|
|
|
index,
|
|
|
|
name: sig.ident.to_string(),
|
|
|
|
args,
|
|
|
|
return_ty,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
_ => {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(ExtDefinition {
|
|
|
|
funcs,
|
|
|
|
generics: item_impl.generics.clone(),
|
|
|
|
ty: item_impl.self_ty.clone(),
|
|
|
|
})
|
|
|
|
}
|