From 735e093de7d52179e85b3093b8634c18d06dc17b Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 26 Aug 2017 12:56:50 +0200 Subject: [PATCH] Implement #[compute(clone)] for #[derive(ToComputedValue)] --- components/style/values/computed/image.rs | 25 +------------ components/style/values/generics/grid.rs | 31 +++------------- components/style/values/generics/image.rs | 4 ++- components/style/values/specified/grid.rs | 37 -------------------- components/style_derive/lib.rs | 2 +- components/style_derive/to_computed_value.rs | 33 ++++++++++++++--- 6 files changed, 37 insertions(+), 95 deletions(-) diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index f188adf3f7d..952e213ccb9 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -18,8 +18,7 @@ use values::generics::image::{CompatMode, ColorStop as GenericColorStop, EndingS use values::generics::image::{Gradient as GenericGradient, GradientItem as GenericGradientItem}; use values::generics::image::{Image as GenericImage, GradientKind as GenericGradientKind}; use values::generics::image::{LineDirection as GenericLineDirection, MozImageRect as GenericMozImageRect}; -use values::specified::image::{Gradient as SpecifiedGradient, LineDirection as SpecifiedLineDirection}; -use values::specified::image::{GradientKind as SpecifiedGradientKind}; +use values::specified::image::LineDirection as SpecifiedLineDirection; use values::specified::position::{X, Y}; /// A computed image layer. @@ -181,25 +180,3 @@ impl ToComputedValue for SpecifiedLineDirection { } } } - -impl ToComputedValue for SpecifiedGradient { - type ComputedValue = Gradient; - - fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { - Self::ComputedValue { - kind: self.kind.to_computed_value(context), - items: self.items.to_computed_value(context), - repeating: self.repeating, - compat_mode: self.compat_mode - } - } - - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - Self { - kind: SpecifiedGradientKind::from_computed_value(&computed.kind), - items: ToComputedValue::from_computed_value(&computed.items), - repeating: computed.repeating, - compat_mode: computed.compat_mode - } - } -} diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index fba3d747fa8..93d00b8325f 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -349,8 +349,8 @@ no_viewport_percentage!(RepeatCount); /// /// It can also hold `repeat()` function parameters, which expands into the respective /// values in its computed form. -#[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, PartialEq, ToComputedValue)] pub struct TrackRepeat { /// The number of times for the value to be repeated (could also be `auto-fit` or `auto-fill`) pub count: RepeatCount, @@ -359,6 +359,7 @@ pub struct TrackRepeat { /// If there's no ``, then it's represented by an empty vector. /// For N `` values, there will be N+1 ``, and so this vector's /// length is always one value more than that of the ``. + #[compute(clone)] pub line_names: Box<[Box<[CustomIdent]>]>, /// `` values. pub track_sizes: Vec>, @@ -446,31 +447,6 @@ impl TrackRepeat { } } } -impl ToComputedValue for TrackRepeat { - type ComputedValue = TrackRepeat; - - #[inline] - fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { - TrackRepeat { - count: self.count, - track_sizes: self.track_sizes.iter() - .map(|val| val.to_computed_value(context)) - .collect(), - line_names: self.line_names.clone(), - } - } - - #[inline] - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - TrackRepeat { - count: computed.count, - track_sizes: computed.track_sizes.iter() - .map(ToComputedValue::from_computed_value) - .collect(), - line_names: computed.line_names.clone(), - } - } -} /// The type of a `` as determined during parsing. /// @@ -500,8 +476,8 @@ impl ComputedValueAsSpecified for TrackListType {} /// A grid `` type. /// /// https://drafts.csswg.org/css-grid/#typedef-track-list -#[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, PartialEq, ToComputedValue)] pub struct TrackList { /// The type of this `` (auto, explicit or general). /// @@ -515,6 +491,7 @@ pub struct TrackList { /// If there's no ``, then it's represented by an empty vector. /// For N values, there will be N+1 ``, and so this vector's /// length is always one value more than that of the ``. + #[compute(clone)] pub line_names: Box<[Box<[CustomIdent]>]>, /// `` value. There can only be one `` in a TrackList. pub auto_repeat: Option>, diff --git a/components/style/values/generics/image.rs b/components/style/values/generics/image.rs index bc8f038ffb2..3e977759d70 100644 --- a/components/style/values/generics/image.rs +++ b/components/style/values/generics/image.rs @@ -35,16 +35,18 @@ pub enum Image { /// A CSS gradient. /// https://drafts.csswg.org/css-images/#gradients -#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] pub struct Gradient { /// Gradients can be linear or radial. pub kind: GradientKind, /// The color stops and interpolation hints. pub items: Vec>, /// True if this is a repeating gradient. + #[compute(clone)] pub repeating: bool, /// Compatibility mode. + #[compute(clone)] pub compat_mode: CompatMode, } diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs index 6499bbcb49b..72ce404d25c 100644 --- a/components/style/values/specified/grid.rs +++ b/components/style/values/specified/grid.rs @@ -11,7 +11,6 @@ use std::ascii::AsciiExt; use std::mem; use style_traits::{HasViewportPercentage, ParseError, StyleParseError}; use values::{CSSFloat, CustomIdent}; -use values::computed::{self, Context, ToComputedValue}; use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth, TrackKeyword, TrackRepeat}; use values::generics::grid::{LineNameList, TrackSize, TrackList, TrackListType}; use values::specified::LengthOrPercentage; @@ -286,42 +285,6 @@ impl HasViewportPercentage for TrackList { } } - -impl ToComputedValue for TrackList { - type ComputedValue = TrackList; - - #[inline] - fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { - let mut values = Vec::with_capacity(self.values.len() + 1); - for value in self.values.iter().map(|val| val.to_computed_value(context)) { - values.push(value); - } - - TrackList { - list_type: self.list_type.to_computed_value(context), - values: values, - line_names: self.line_names.clone(), - auto_repeat: self.auto_repeat.clone().map(|repeat| repeat.to_computed_value(context)), - } - } - - #[inline] - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - let mut values = Vec::with_capacity(computed.values.len() + 1); - for value in computed.values.iter().map(ToComputedValue::from_computed_value) { - values.push(value); - } - - TrackList { - list_type: computed.list_type, - values: values, - line_names: computed.line_names.clone(), - auto_repeat: computed.auto_repeat.clone().map(|ref repeat| TrackRepeat::from_computed_value(repeat)), - } - } -} - - impl Parse for GridTemplateComponent { // FIXME: Derive Parse (probably with None_) fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index 342d9cc4b9b..4e2ff9e3fca 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -49,7 +49,7 @@ pub fn derive_to_animated_zero(stream: TokenStream) -> TokenStream { to_animated_zero::derive(input).to_string().parse().unwrap() } -#[proc_macro_derive(ToComputedValue)] +#[proc_macro_derive(ToComputedValue, attributes(compute))] pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream { let input = syn::parse_derive_input(&stream.to_string()).unwrap(); to_computed_value::derive(input).to_string().parse().unwrap() diff --git a/components/style_derive/to_computed_value.rs b/components/style_derive/to_computed_value.rs index 74655743eea..7e4db276edd 100644 --- a/components/style_derive/to_computed_value.rs +++ b/components/style_derive/to_computed_value.rs @@ -14,14 +14,31 @@ pub fn derive(input: DeriveInput) -> Tokens { cg::fmap_trait_parts(&input, trait_path, "ComputedValue"); let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { - where_clause.add_trait_bound(&binding.field.ty); - quote! { - ::values::computed::ToComputedValue::to_computed_value(#binding, context) + let attrs = cg::parse_field_attrs::(&binding.field); + if attrs.clone { + if cg::is_parameterized(&binding.field.ty, where_clause.params, None) { + where_clause.inner.predicates.push(cg::where_predicate( + binding.field.ty.clone(), + &["std", "clone", "Clone"], + None, + )); + } + quote! { ::std::clone::Clone::clone(#binding) } + } else { + where_clause.add_trait_bound(&binding.field.ty); + 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) + let attrs = cg::parse_field_attrs::(&binding.field); + if attrs.clone { + quote! { ::std::clone::Clone::clone(#binding) } + } else { + quote! { + ::values::computed::ToComputedValue::from_computed_value(#binding) + } } }); @@ -46,3 +63,9 @@ pub fn derive(input: DeriveInput) -> Tokens { } } } + +#[darling(attributes(compute), default)] +#[derive(Default, FromField)] +struct ComputedValueAttrs { + clone: bool, +}