servo: Merge #20200 - Derive some more ToCss stuff again (from servo:derive-all-the-things); r=emilio
authorAnthony Ramine <n.oxyde@gmail.com>
Tue, 06 Mar 2018 03:33:18 -0500
changeset 461734 6bf29a26a10daad2756b8eb795b4b1a1c95a2da3
parent 461733 8381ed38af109e758322070dd997e52cfab714fe
child 461735 7a38746fc555b6a9ec1c0ea09864dd14b5b8823f
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #20200 - Derive some more ToCss stuff again (from servo:derive-all-the-things); r=emilio Source-Repo: https://github.com/servo/servo Source-Revision: 17b5a8332b4309188ea7ce9c1aa5919aeb7834e6
servo/components/style/font_face.rs
servo/components/style/gecko/url.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/values/computed/font.rs
servo/components/style/values/generics/font.rs
servo/components/style/values/specified/font.rs
servo/components/style/values/specified/table.rs
servo/components/style_derive/to_css.rs
servo/components/style_traits/values.rs
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -43,34 +43,26 @@ pub enum Source {
 impl OneOrMoreSeparated for Source {
     type S = Comma;
 }
 
 /// A `UrlSource` represents a font-face source that has been specified with a
 /// `url()` function.
 ///
 /// <https://drafts.csswg.org/css-fonts/#src-desc>
-#[derive(Clone, Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
+#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
 pub struct UrlSource {
     /// The specified url.
     pub url: SpecifiedUrl,
     /// The format hints specified with the `format()` function.
+    #[css(skip)]
     pub format_hints: Vec<String>,
 }
 
-impl ToCss for UrlSource {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        self.url.to_css(dest)
-    }
-}
-
 /// A font-display value for a @font-face rule.
 /// The font-display descriptor determines how a font face is displayed based
 /// on whether and when it is downloaded and ready to use.
 #[allow(missing_docs)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
 #[derive(ToComputedValue, ToCss)]
 pub enum FontDisplay {
--- a/servo/components/style/gecko/url.rs
+++ b/servo/components/style/gecko/url.rs
@@ -7,34 +7,36 @@
 use gecko_bindings::structs::{ServoBundledURI, URLExtraData};
 use gecko_bindings::structs::mozilla::css::URLValueData;
 use gecko_bindings::structs::root::{nsStyleImageRequest, RustString};
 use gecko_bindings::structs::root::mozilla::css::ImageValue;
 use gecko_bindings::sugar::refptr::RefPtr;
 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
 use parser::ParserContext;
 use servo_arc::{Arc, RawOffsetArc};
-use std::fmt::{self, Write};
 use std::mem;
-use style_traits::{CssWriter, ToCss, ParseError};
+use style_traits::ParseError;
 
 /// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls.
-#[derive(Clone, Debug, PartialEq)]
+#[css(function = "url")]
+#[derive(Clone, Debug, PartialEq, ToCss)]
 pub struct SpecifiedUrl {
     /// The URL in unresolved string form.
     ///
     /// Refcounted since cloning this should be cheap and data: uris can be
     /// really large.
     serialization: Arc<String>,
 
     /// The URL extra data.
+    #[css(skip)]
     pub extra_data: RefPtr<URLExtraData>,
 
     /// Cache ImageValue, if any, so that we can reuse it while rematching a
     /// a property with this specified url value.
+    #[css(skip)]
     pub image_value: Option<RefPtr<ImageValue>>,
 }
 trivial_to_computed_value!(SpecifiedUrl);
 
 impl SpecifiedUrl {
     /// Try to parse a URL from a string value that is a valid CSS token for a
     /// URL.
     ///
@@ -128,27 +130,16 @@ impl SpecifiedUrl {
                 // We do not expect Gecko_ImageValue_Create returns null.
                 debug_assert!(!ptr.is_null());
                 Some(RefPtr::from_addrefed(ptr))
             }
         }
     }
 }
 
-impl ToCss for SpecifiedUrl {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        dest.write_str("url(")?;
-        self.serialization.to_css(dest)?;
-        dest.write_str(")")
-    }
-}
-
 impl MallocSizeOf for SpecifiedUrl {
     fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
         use gecko_bindings::bindings::Gecko_ImageValue_SizeOfIncludingThis;
 
         let mut n = 0;
 
         // XXX: measure `serialization` once bug 1397971 lands
 
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1702,69 +1702,45 @@ impl PropertyId {
             Some(id) => id,
         };
         id.allowed_in(context)
     }
 }
 
 /// A declaration using a CSS-wide keyword.
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, ToCss)]
 pub struct WideKeywordDeclaration {
+    #[css(skip)]
     id: LonghandId,
     keyword: CSSWideKeyword,
 }
 
-impl ToCss for WideKeywordDeclaration {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        self.keyword.to_css(dest)
-    }
-}
-
 /// An unparsed declaration that contains `var()` functions.
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, ToCss)]
 pub struct VariableDeclaration {
+    #[css(skip)]
     id: LonghandId,
     #[cfg_attr(feature = "gecko", ignore_malloc_size_of = "XXX: how to handle this?")]
     value: Arc<UnparsedValue>,
 }
 
-impl ToCss for VariableDeclaration {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        self.value.to_css(dest)
-    }
-}
-
 /// A custom property declaration with the property name and the declared value.
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, ToCss)]
 pub struct CustomDeclaration {
     /// The name of the custom property.
+    #[css(skip)]
     pub name: ::custom_properties::Name,
     /// The value of the custom property.
     #[cfg_attr(feature = "gecko", ignore_malloc_size_of = "XXX: how to handle this?")]
     pub value: DeclaredValueOwned<Arc<::custom_properties::SpecifiedValue>>,
 }
 
-impl ToCss for CustomDeclaration {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        self.value.to_css(dest)
-    }
-}
-
 impl fmt::Debug for PropertyDeclaration {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.id().to_css(&mut CssWriter::new(f))?;
         f.write_str(": ")?;
 
         // Because PropertyDeclaration::to_css requires CssStringWriter, we can't write
         // it directly to f, and need to allocate an intermediate string. This is
         // fine for debug-only code.
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -35,23 +35,24 @@ pub use values::specified::font::{XTextZ
 /// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
 ///
 /// However, system fonts may provide other values. Pango
 /// may provide 350, 380, and 1000 (on top of the existing values), for example.
 #[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct FontWeight(pub u16);
 
-#[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedZero)]
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf)]
+#[derive(PartialEq, ToAnimatedZero, ToCss)]
 /// The computed value of font-size
 pub struct FontSize {
     /// The size.
     pub size: NonNegativeLength,
     /// If derived from a keyword, the keyword and additional transformations applied to it
+    #[css(skip)]
     pub keyword_info: Option<KeywordInfo>,
 }
 
 /// Additional information for computed keyword-derived font sizes.
 pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>;
 
 impl FontWeight {
     /// Value for normal
@@ -154,22 +155,16 @@ impl FontSize {
         context.builder.mutate_font().set_font_size(computed);
         #[cfg(feature = "gecko")] {
             let device = context.builder.device;
             context.builder.mutate_font().fixup_font_min_size(device);
         }
     }
 }
 
-impl ToCss for FontSize {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
-        self.size.to_css(dest)
-    }
-}
-
 /// XXXManishearth it might be better to
 /// animate this as computed, however this complicates
 /// clamping and might not be the right thing to do.
 /// We should figure it out.
 impl ToAnimatedValue for FontSize {
     type AnimatedValue = NonNegativeLength;
 
     #[inline]
--- a/servo/components/style/values/generics/font.rs
+++ b/servo/components/style/values/generics/font.rs
@@ -157,24 +157,26 @@ impl Parse for FontTag {
         }
 
         let mut raw = Cursor::new(tag.as_bytes());
         Ok(FontTag(raw.read_u32::<BigEndian>().unwrap()))
     }
 }
 
 #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf)]
-#[derive(PartialEq, ToAnimatedValue, ToAnimatedZero)]
+#[derive(PartialEq, ToAnimatedValue, ToAnimatedZero, ToCss)]
 /// Additional information for keyword-derived font sizes.
 pub struct KeywordInfo<Length> {
     /// The keyword used
     pub kw: KeywordSize,
     /// A factor to be multiplied by the computed size of the keyword
+    #[css(skip)]
     pub factor: f32,
     /// An additional Au offset to add to the kw*factor in the case of calcs
+    #[css(skip)]
     pub offset: Length,
 }
 
 impl<L> KeywordInfo<L>
 where
     Au: Into<L>,
 {
     /// KeywordInfo value for font-size: medium
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -113,17 +113,17 @@ impl ToComputedValue for FontWeight {
     }
 
     #[inline]
     fn from_computed_value(computed: &computed::FontWeight) -> Self {
         FontWeight::Weight(*computed)
     }
 }
 
-#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
 /// A specified font-size value
 pub enum FontSize {
     /// A length; e.g. 10px.
     Length(LengthOrPercentage),
     /// A keyword value, along with a ratio and absolute offset.
     /// The ratio in any specified keyword value
     /// will be 1 (with offset 0), but we cascade keywordness even
     /// after font-relative (percent and em) values
@@ -137,31 +137,16 @@ pub enum FontSize {
     /// font-size: smaller
     Smaller,
     /// font-size: larger
     Larger,
     /// Derived from a specified system font.
     System(SystemFont)
 }
 
-impl ToCss for FontSize {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        match *self {
-            FontSize::Length(ref lop) => lop.to_css(dest),
-            FontSize::Keyword(info) => info.kw.to_css(dest),
-            FontSize::Smaller => dest.write_str("smaller"),
-            FontSize::Larger => dest.write_str("larger"),
-            FontSize::System(sys) => sys.to_css(dest),
-        }
-    }
-}
-
 impl From<LengthOrPercentage> for FontSize {
     fn from(other: LengthOrPercentage) -> Self {
         FontSize::Length(other)
     }
 }
 
 /// Specifies a prioritized list of font family names or generic family names.
 #[derive(Clone, Debug, Eq, Hash, PartialEq, ToCss)]
@@ -2010,39 +1995,30 @@ impl Parse for VariationValue<Number> {
     ) -> Result<Self, ParseError<'i>> {
         let tag = FontTag::parse(context, input)?;
         let value = Number::parse(context, input)?;
         Ok(Self { tag, value })
     }
 }
 
 
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
 /// text-zoom. Enable if true, disable if false
-pub struct XTextZoom(pub bool);
+pub struct XTextZoom(#[css(skip)] pub bool);
 
 impl Parse for XTextZoom {
     fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<XTextZoom, ParseError<'i>> {
         debug_assert!(false, "Should be set directly by presentation attributes only.");
         Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }
 
-impl ToCss for XTextZoom {
-    fn to_css<W>(&self, _: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        Ok(())
-    }
-}
-
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
 /// Internal property that reflects the lang attribute
-pub struct XLang(pub Atom);
+pub struct XLang(#[css(skip)] pub Atom);
 
 impl XLang {
     #[inline]
     /// Get default value for `-x-lang`
     pub fn get_initial_value() -> XLang {
         XLang(atom!(""))
     }
 }
@@ -2052,25 +2028,16 @@ impl Parse for XLang {
         _: &ParserContext,
         input: &mut Parser<'i, 't>
     ) -> Result<XLang, ParseError<'i>> {
         debug_assert!(false, "Should be set directly by presentation attributes only.");
         Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }
 
-impl ToCss for XLang {
-    fn to_css<W>(&self, _: &mut CssWriter<W>) -> fmt::Result
-    where
-        W: Write,
-    {
-        Ok(())
-    }
-}
-
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
 #[derive(Clone, Copy, Debug, PartialEq, ToCss)]
 /// Specifies the minimum font size allowed due to changes in scriptlevel.
 /// Ref: https://wiki.mozilla.org/MathML:mstyle
 pub struct MozScriptMinSize(pub NoCalcLength);
 
 impl MozScriptMinSize {
     #[inline]
--- a/servo/components/style/values/specified/table.rs
+++ b/servo/components/style/values/specified/table.rs
@@ -1,27 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 //! Specified types for table properties.
 
 use cssparser::Parser;
 use parser::{Parse, ParserContext};
-use std::fmt;
-use style_traits::{CssWriter, ToCss, StyleParseErrorKind, ParseError};
+use style_traits::{StyleParseErrorKind, ParseError};
 
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
 /// span. for `<col span>` pres attr
-pub struct XSpan(pub i32);
+pub struct XSpan(#[css(skip)] pub i32);
 
 impl Parse for XSpan {
     // never parse it, only set via presentation attribute
     fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<XSpan, ParseError<'i>> {
         Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }
-
-impl ToCss for XSpan {
-    fn to_css<W>(&self, _: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
-        Ok(())
-    }
-}
--- a/servo/components/style_derive/to_css.rs
+++ b/servo/components/style_derive/to_css.rs
@@ -48,16 +48,19 @@ pub fn derive(input: syn::DeriveInput) -
 
                     for item in #binding.iter() {
                         writer.item(&item)?;
                     }
                 };
             } else {
                 for binding in bindings {
                     let attrs = cg::parse_field_attrs::<CssFieldAttrs>(&binding.ast());
+                    if attrs.skip {
+                        continue;
+                    }
                     if !attrs.ignore_bound {
                         where_clause.add_trait_bound(&binding.ast().ty);
                     }
                     expr = quote! {
                         #expr
                         writer.item(#binding)?;
                     };
                 }
@@ -147,9 +150,10 @@ pub struct CssVariantAttrs {
     pub keyword: Option<String>,
     pub aliases: Option<String>,
 }
 
 #[darling(attributes(css), default)]
 #[derive(Default, FromField)]
 struct CssFieldAttrs {
     ignore_bound: bool,
+    skip: bool,
 }
--- a/servo/components/style_traits/values.rs
+++ b/servo/components/style_traits/values.rs
@@ -21,20 +21,22 @@ use std::fmt::{self, Write};
 /// * unit variants whose name starts with "Moz" or "Webkit" are prepended
 ///   with a "-";
 /// * if `#[css(comma)]` is found on a variant, its fields are separated by
 ///   commas, otherwise, by spaces;
 /// * if `#[css(function)]` is found on a variant, the variant name gets
 ///   serialised like unit variants and its fields are surrounded by parentheses;
 /// * if `#[css(iterable)]` is found on a function variant, that variant needs
 ///   to have a single member, and that member needs to be iterable. The
-///   iterable will be serialized as the arguments for the function.
+///   iterable will be serialized as the arguments for the function;
 /// * if `#[css(dimension)]` is found on a variant, that variant needs
 ///   to have a single member. The variant would be serialized as a CSS
-///   dimension token, like: <member><identifier>.
+///   dimension token, like: <member><identifier>;
+/// * if `#[css(skip)]` is found on a field, the `ToCss` call for that field
+///   is skipped;
 /// * finally, one can put `#[css(derive_debug)]` on the whole type, to
 ///   implement `Debug` by a single call to `ToCss::to_css`.
 pub trait ToCss {
     /// Serialize `self` in CSS syntax, writing to `dest`.
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write;
 
     /// Serialize `self` in CSS syntax and return a string.
     ///