From 4d0bf2ddf9f4c9515e89b6457837097071f676b5 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 9 Mar 2018 17:56:16 +0100 Subject: [PATCH] Opt into field bounds for #[derive(ToComputedValue)] --- components/style/values/generics/grid.rs | 2 +- components/style/values/generics/transform.rs | 4 - components/style_derive/cg.rs | 13 +-- components/style_derive/to_animated_value.rs | 2 +- components/style_derive/to_computed_value.rs | 80 ++++++++++++------- 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index 3d8005fc62d..cafc4672a81 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -666,7 +666,7 @@ pub enum GridTemplateComponent { /// `none` value. None, /// The grid `` - TrackList(TrackList), + TrackList(#[compute(field_bound)] TrackList), /// A `subgrid ?` Subgrid(LineNameList), } diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index be863d1e005..b80bc8b14f4 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -247,7 +247,6 @@ pub enum TransformOperation #[allow(missing_docs)] #[css(comma, function = "interpolatematrix")] InterpolateMatrix { - #[compute(ignore_bound)] from_list: Transform< TransformOperation< Angle, @@ -257,7 +256,6 @@ pub enum TransformOperation LengthOrPercentage, >, >, - #[compute(ignore_bound)] to_list: Transform< TransformOperation< Angle, @@ -273,7 +271,6 @@ pub enum TransformOperation #[allow(missing_docs)] #[css(comma, function = "accumulatematrix")] AccumulateMatrix { - #[compute(ignore_bound)] from_list: Transform< TransformOperation< Angle, @@ -283,7 +280,6 @@ pub enum TransformOperation LengthOrPercentage, >, >, - #[compute(ignore_bound)] to_list: Transform< TransformOperation< Angle, diff --git a/components/style_derive/cg.rs b/components/style_derive/cg.rs index 5289eaf3f6b..ffe30b89d0b 100644 --- a/components/style_derive/cg.rs +++ b/components/style_derive/cg.rs @@ -111,7 +111,7 @@ where }) } -fn fmap_output_type( +pub fn fmap_output_type( ty: Type, trait_path: &Path, trait_output: Ident, @@ -119,17 +119,6 @@ fn fmap_output_type( parse_quote!(<#ty as ::#trait_path>::#trait_output) } -pub fn fmap_trait_parts<'input, 'path>( - input: &'input DeriveInput, - trait_path: &'path Path, - trait_output: Ident, -) -> (ImplGenerics<'input>, TypeGenerics<'input>, WhereClause<'input, 'path>, Path) { - let (impl_generics, ty_generics, mut where_clause) = trait_parts(input, trait_path); - where_clause.trait_output = Some(trait_output); - let output_ty = fmap_trait_output(input, trait_path, trait_output); - (impl_generics, ty_generics, where_clause, output_ty) -} - pub fn fmap_trait_output( input: &DeriveInput, trait_path: &Path, diff --git a/components/style_derive/to_animated_value.rs b/components/style_derive/to_animated_value.rs index c2e8e4ef984..a7378b70145 100644 --- a/components/style_derive/to_animated_value.rs +++ b/components/style_derive/to_animated_value.rs @@ -15,7 +15,6 @@ pub fn derive(mut input: DeriveInput) -> quote::Tokens { parse_quote!(#param: ::values::animated::ToAnimatedValue), ); } - input.generics.where_clause = where_clause; let to_body = cg::fmap_match(&input, BindStyle::Move, |binding| { quote!(::values::animated::ToAnimatedValue::to_animated_value(#binding)) @@ -24,6 +23,7 @@ pub fn derive(mut input: DeriveInput) -> quote::Tokens { quote!(::values::animated::ToAnimatedValue::from_animated_value(#binding)) }); + input.generics.where_clause = where_clause; let name = &input.ident; let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); let animated_value_type = cg::fmap_trait_output( diff --git a/components/style_derive/to_computed_value.rs b/components/style_derive/to_computed_value.rs index 8ef05f8ecff..9b7544ffbb8 100644 --- a/components/style_derive/to_computed_value.rs +++ b/components/style_derive/to_computed_value.rs @@ -4,21 +4,59 @@ use cg; use quote::Tokens; -use syn::{Ident, DeriveInput}; +use syn::DeriveInput; use synstructure::BindStyle; -pub fn derive(input: DeriveInput) -> Tokens { - let name = &input.ident; - let trait_path = parse_quote!(values::computed::ToComputedValue); - let (impl_generics, ty_generics, mut where_clause, computed_value_type) = - cg::fmap_trait_parts(&input, &trait_path, Ident::from("ComputedValue")); +pub fn derive(mut input: DeriveInput) -> Tokens { + let mut where_clause = input.generics.where_clause.take(); + let (to_body, from_body) = { + let params = input.generics.type_params().collect::>(); + for param in ¶ms { + cg::add_predicate( + &mut where_clause, + parse_quote!(#param: ::values::computed::ToComputedValue), + ); + } - if input.generics.params.is_empty() { + let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { + let attrs = cg::parse_field_attrs::(&binding.ast()); + if attrs.field_bound { + let ty = &binding.ast().ty; + + let output_type = cg::map_type_params(ty, ¶ms, &mut |ident| { + parse_quote!(<#ident as ::values::computed::ToComputedValue>::ComputedValue) + }); + + cg::add_predicate( + &mut where_clause, + parse_quote!( + #ty: ::values::computed::ToComputedValue + ), + ); + } + quote! { + ::values::computed::ToComputedValue::to_computed_value(#binding, context) + } + }); + let from_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { + quote! { + ::values::computed::ToComputedValue::from_computed_value(#binding) + } + }); + + (to_body, from_body) + }; + + input.generics.where_clause = where_clause; + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + if input.generics.type_params().next().is_none() { return quote! { impl #impl_generics ::values::computed::ToComputedValue for #name #ty_generics #where_clause { - type ComputedValue = #computed_value_type; + type ComputedValue = Self; #[inline] fn to_computed_value( @@ -36,25 +74,11 @@ pub fn derive(input: DeriveInput) -> Tokens { } } - let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { - let attrs = cg::parse_field_attrs::(&binding.ast()); - if !attrs.ignore_bound { - where_clause.add_trait_bound(&binding.ast().ty); - } - quote! { - ::values::computed::ToComputedValue::to_computed_value(#binding, context) - } - }); - let from_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { - let attrs = cg::parse_field_attrs::(&binding.ast()); - if attrs.clone { - quote! { ::std::clone::Clone::clone(#binding) } - } else { - quote! { - ::values::computed::ToComputedValue::from_computed_value(#binding) - } - } - }); + let computed_value_type = cg::fmap_trait_output( + &input, + &parse_quote!(values::computed::ToComputedValue), + "ComputedValue".into(), + ); quote! { impl #impl_generics ::values::computed::ToComputedValue for #name #ty_generics #where_clause { @@ -81,5 +105,5 @@ pub fn derive(input: DeriveInput) -> Tokens { #[darling(attributes(compute), default)] #[derive(Default, FromField)] struct ComputedValueAttrs { - ignore_bound: bool, + field_bound: bool, }