Parse,
ParseStream, //
},
+ Attribute,
Error,
LitStr,
Result, //
proc_macro::Span::call_site().file()
}
}
+
+/// Obtain all `#[cfg]` attributes.
+pub(crate) fn gather_cfg_attrs(attr: &[Attribute]) -> impl Iterator<Item = &Attribute> + '_ {
+ attr.iter().filter(|a| a.path().is_ident("cfg"))
+}
fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
let mut gen_items = Vec::new();
- let mut gen_consts = HashSet::new();
gen_items.push(parse_quote! {
/// A marker to prevent implementors from forgetting to use [`#[vtable]`](vtable)
&format!("HAS_{}", name.to_string().to_uppercase()),
name.span(),
);
- // Skip if it's declared already -- this can happen if `#[cfg]` is used to selectively
- // define functions.
- // FIXME: `#[cfg]` should be copied and propagated to the generated consts.
- if gen_consts.contains(&gen_const_name) {
- continue;
- }
// We don't know on the implementation-site whether a method is required or provided
// so we have to generate a const for all methods.
+ let cfg_attrs = crate::helpers::gather_cfg_attrs(&fn_item.attrs);
let comment =
format!("Indicates if the `{name}` method is overridden by the implementor.");
gen_items.push(parse_quote! {
+ #(#cfg_attrs)*
#[doc = #comment]
const #gen_const_name: bool = false;
});
- gen_consts.insert(gen_const_name);
}
}
if defined_consts.contains(&gen_const_name) {
continue;
}
+ let cfg_attrs = crate::helpers::gather_cfg_attrs(&fn_item.attrs);
gen_items.push(parse_quote! {
+ #(#cfg_attrs)*
const #gen_const_name: bool = true;
});
- defined_consts.insert(gen_const_name);
}
}