mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Implement #[compute(clone)] for #[derive(ToComputedValue)]
This commit is contained in:
parent
efc852f6e3
commit
735e093de7
6 changed files with 37 additions and 95 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<L> {
|
||||
/// 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<L> {
|
|||
/// If there's no `<line-names>`, then it's represented by an empty vector.
|
||||
/// For N `<track-size>` values, there will be N+1 `<line-names>`, and so this vector's
|
||||
/// length is always one value more than that of the `<track-size>`.
|
||||
#[compute(clone)]
|
||||
pub line_names: Box<[Box<[CustomIdent]>]>,
|
||||
/// `<track-size>` values.
|
||||
pub track_sizes: Vec<TrackSize<L>>,
|
||||
|
@ -446,31 +447,6 @@ impl<L: Clone> TrackRepeat<L> {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<L: ToComputedValue> ToComputedValue for TrackRepeat<L> {
|
||||
type ComputedValue = TrackRepeat<L::ComputedValue>;
|
||||
|
||||
#[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 `<track-list>` as determined during parsing.
|
||||
///
|
||||
|
@ -500,8 +476,8 @@ impl ComputedValueAsSpecified for TrackListType {}
|
|||
/// A grid `<track-list>` 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<T> {
|
||||
/// The type of this `<track-list>` (auto, explicit or general).
|
||||
///
|
||||
|
@ -515,6 +491,7 @@ pub struct TrackList<T> {
|
|||
/// If there's no `<line-names>`, then it's represented by an empty vector.
|
||||
/// For N values, there will be N+1 `<line-names>`, and so this vector's
|
||||
/// length is always one value more than that of the `<track-size>`.
|
||||
#[compute(clone)]
|
||||
pub line_names: Box<[Box<[CustomIdent]>]>,
|
||||
/// `<auto-repeat>` value. There can only be one `<auto-repeat>` in a TrackList.
|
||||
pub auto_repeat: Option<TrackRepeat<T>>,
|
||||
|
|
|
@ -35,16 +35,18 @@ pub enum Image<Gradient, MozImageRect, ImageUrl> {
|
|||
|
||||
/// 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<LineDirection, Length, LengthOrPercentage, Position, Color, Angle> {
|
||||
/// Gradients can be linear or radial.
|
||||
pub kind: GradientKind<LineDirection, Length, LengthOrPercentage, Position, Angle>,
|
||||
/// The color stops and interpolation hints.
|
||||
pub items: Vec<GradientItem<Color, LengthOrPercentage>>,
|
||||
/// True if this is a repeating gradient.
|
||||
#[compute(clone)]
|
||||
pub repeating: bool,
|
||||
/// Compatibility mode.
|
||||
#[compute(clone)]
|
||||
pub compat_mode: CompatMode,
|
||||
}
|
||||
|
||||
|
|
|
@ -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<LengthOrPercentage> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl ToComputedValue for TrackList<LengthOrPercentage> {
|
||||
type ComputedValue = TrackList<computed::LengthOrPercentage>;
|
||||
|
||||
#[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<LengthOrPercentage> {
|
||||
// FIXME: Derive Parse (probably with None_)
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -14,15 +14,32 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
|||
cg::fmap_trait_parts(&input, trait_path, "ComputedValue");
|
||||
|
||||
let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| {
|
||||
let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&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| {
|
||||
let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&binding.field);
|
||||
if attrs.clone {
|
||||
quote! { ::std::clone::Clone::clone(#binding) }
|
||||
} else {
|
||||
quote! {
|
||||
::values::computed::ToComputedValue::from_computed_value(#binding)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
|
@ -46,3 +63,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[darling(attributes(compute), default)]
|
||||
#[derive(Default, FromField)]
|
||||
struct ComputedValueAttrs {
|
||||
clone: bool,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue