Bump syn/quote in domobject_derive

This commit is contained in:
Bastien Orivel 2018-02-12 15:05:35 +01:00
parent 0a0d37bea3
commit c18137b4ea
3 changed files with 22 additions and 33 deletions

View file

@ -2,20 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![recursion_limit = "128"]
extern crate proc_macro;
#[macro_use] extern crate quote;
extern crate syn;
#[macro_use] extern crate syn;
#[proc_macro_derive(DomObject)]
pub fn expand_token_stream(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
expand_string(&input.to_string()).parse().unwrap()
let input = syn::parse(input).unwrap();
expand_dom_object(input).into()
}
fn expand_string(input: &str) -> String {
let type_ = syn::parse_macro_input(input).unwrap();
let fields = if let syn::Body::Struct(syn::VariantData::Struct(ref fields)) = type_.body {
fields
fn expand_dom_object(input: syn::DeriveInput) -> quote::Tokens {
let fields = if let syn::Data::Struct(syn::DataStruct { ref fields, .. }) = input.data {
fields.iter().collect::<Vec<&syn::Field>>()
} else {
panic!("#[derive(DomObject)] should only be applied on proper structs")
};
@ -23,6 +24,7 @@ fn expand_string(input: &str) -> String {
let (first_field, fields) = fields
.split_first()
.expect("#[derive(DomObject)] should not be applied on empty structs");
let first_field_name = first_field.ident.as_ref().unwrap();
let mut field_types = vec![];
for field in fields {
@ -31,9 +33,8 @@ fn expand_string(input: &str) -> String {
}
}
let name = &type_.ident;
let (impl_generics, ty_generics, where_clause) = type_.generics.split_for_impl();
let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let mut items = quote! {
impl #impl_generics ::js::conversions::ToJSValConvertible for #name #ty_generics #where_clause {
#[allow(unsafe_code)]
@ -60,7 +61,7 @@ fn expand_string(input: &str) -> String {
};
let mut params = quote::Tokens::new();
params.append_separated(type_.generics.ty_params.iter().map(|param| &param.ident), ", ");
params.append_separated(input.generics.type_params().map(|param| param.ident), ", ");
// For each field in the struct, we implement ShouldNotImplDomObject for a
// pair of all the type parameters of the DomObject and and the field type.
@ -72,33 +73,21 @@ fn expand_string(input: &str) -> String {
}
}));
let bound = syn::TyParamBound::Trait(
syn::PolyTraitRef {
bound_lifetimes: vec![],
trait_ref: syn::parse_path("::dom::bindings::reflector::DomObject").unwrap(),
},
syn::TraitBoundModifier::None
);
let mut generics = input.generics.clone();
generics.params.push(parse_quote!(__T: ::dom::bindings::reflector::DomObject));
let mut generics = type_.generics.clone();
generics.ty_params.push(syn::TyParam {
attrs: vec![],
ident: "__T".into(),
bounds: vec![bound],
default: None,
});
let (impl_generics, _, where_clause) = generics.split_for_impl();
items.append(quote! {
items.append_all(quote! {
trait ShouldNotImplDomObject {}
impl #impl_generics ShouldNotImplDomObject for ((#params), __T) #where_clause {}
}.as_str());
});
let dummy_const = syn::Ident::new(format!("_IMPL_DOMOBJECT_FOR_{}", name));
let dummy_const = syn::Ident::from(format!("_IMPL_DOMOBJECT_FOR_{}", name));
let tokens = quote! {
#[allow(non_upper_case_globals)]
const #dummy_const: () = { #items };
};
tokens.to_string()
tokens
}