use failure::Error;
use syn;
use wasm_wrapper_gen_shared::transform_mac_to_items;
pub fn walk_crate_for_js_fns(source: &str) -> Result<Vec<syn::Item>, Error> {
use syn::visit::Visitor;
let ast = syn::parse_crate(source)
.map_err(|e| format_err!("failed to parse macro input as an item: {}", e))?;
let mut v = FindMacrosVisitor::find_js_fn();
v.visit_crate(&ast);
let mut func_definition_items = Vec::new();
for found_macro in v.found {
func_definition_items.extend(transform_mac_to_items(found_macro)?);
}
Ok(func_definition_items)
}
struct FindMacrosVisitor {
ident_to_find: syn::Path,
found: Vec<syn::Mac>,
}
impl FindMacrosVisitor {
fn new(ident_to_find: syn::Path) -> Self {
FindMacrosVisitor {
ident_to_find: ident_to_find,
found: Vec::new(),
}
}
fn find_js_fn() -> Self {
FindMacrosVisitor::new(syn::Path {
global: false,
segments: vec![
syn::PathSegment {
ident: syn::Ident::new("js_fn"),
parameters: syn::PathParameters::none(),
},
],
})
}
}
impl syn::visit::Visitor for FindMacrosVisitor {
fn visit_mac(&mut self, mac: &syn::Mac) {
if mac.path == self.ident_to_find {
self.found.push(mac.clone());
}
}
}