Bug 1466609: Move some parsing-only attributes to use #[parse(..)] instead of #[css(..)]. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 04 Jun 2018 19:24:43 +0200
changeset 421570 9889304ebdea753a8408d1e1ab192ee764520da0
parent 421569 01997380f76db787f84b14bc34031b8fef3c6c4b
child 421571 4607eea0048d5bdba9de9a1b781d47eb5ff7b6c2
push id34098
push usernbeleuzu@mozilla.com
push dateWed, 06 Jun 2018 17:00:32 +0000
treeherdermozilla-central@04cc917f68c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1466609
milestone62.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
Bug 1466609: Move some parsing-only attributes to use #[parse(..)] instead of #[css(..)]. r=xidorn I need to admit I'm ambivalent about this one :). MozReview-Commit-ID: F1jlfnQKXwo
servo/components/style/parser.rs
servo/components/style/properties/helpers.mako.rs
servo/components/style/values/specified/box.rs
servo/components/style_derive/lib.rs
servo/components/style_derive/parse.rs
servo/components/style_derive/specified_value_info.rs
servo/components/style_derive/to_css.rs
servo/components/style_traits/specified_value_info.rs
--- a/servo/components/style/parser.rs
+++ b/servo/components/style/parser.rs
@@ -152,22 +152,22 @@ impl<'a> ParserContext<'a> {
 
 /// A trait to abstract parsing of a specified value given a `ParserContext` and
 /// CSS input.
 ///
 /// This can be derived on keywords with `#[derive(Parse)]`.
 ///
 /// The derive code understands the following attributes on each of the variants:
 ///
-///  * `#[css(aliases = "foo,bar")]` can be used to alias a value with another
+///  * `#[parse(aliases = "foo,bar")]` can be used to alias a value with another
 ///    at parse-time.
 ///
-///  * `#[css(parse_condition = "function")]` can be used to make the parsing of
-///    the value conditional on `function`, which will be invoked with a
-///    `&ParserContext` reference.
+///  * `#[parse(condition = "function")]` can be used to make the parsing of the
+///    value conditional on `function`, which needs to fulfill
+///    `fn(&ParserContext) -> bool`.
 pub trait Parse: Sized {
     /// Parse a value of this type.
     ///
     /// Returns an error on failure.
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>>;
--- a/servo/components/style/properties/helpers.mako.rs
+++ b/servo/components/style/properties/helpers.mako.rs
@@ -589,17 +589,17 @@
             % if include_aliases:
             <%
                 aliases = []
                 for alias, v in keyword.aliases_for(product).iteritems():
                     if variant == v:
                         aliases.append(alias)
             %>
             % if aliases:
-            #[css(aliases = "${','.join(aliases)}")]
+            #[parse(aliases = "${','.join(aliases)}")]
             % endif
             % endif
             ${to_camel_case(variant)},
             % endfor
         </%def>
         % if extra_specified:
             #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
             #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq,
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -48,19 +48,19 @@ pub enum Display {
     TableFooterGroup,
     TableRow,
     TableColumnGroup,
     TableColumn,
     TableCell,
     TableCaption,
     ListItem,
     None,
-    #[css(aliases = "-webkit-flex")]
+    #[parse(aliases = "-webkit-flex")]
     Flex,
-    #[css(aliases = "-webkit-inline-flex")]
+    #[parse(aliases = "-webkit-inline-flex")]
     InlineFlex,
     #[cfg(feature = "gecko")]
     Grid,
     #[cfg(feature = "gecko")]
     InlineGrid,
     #[cfg(feature = "gecko")]
     Ruby,
     #[cfg(feature = "gecko")]
@@ -79,41 +79,41 @@ pub enum Display {
     WebkitBox,
     #[cfg(feature = "gecko")]
     WebkitInlineBox,
     #[cfg(feature = "gecko")]
     MozBox,
     #[cfg(feature = "gecko")]
     MozInlineBox,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozGrid,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozInlineGrid,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozGridGroup,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozGridLine,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozStack,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozInlineStack,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozDeck,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozPopup,
     #[cfg(feature = "gecko")]
-    #[css(parse_condition = "moz_display_values_enabled")]
+    #[parse(condition = "moz_display_values_enabled")]
     MozGroupbox,
 }
 
 impl Display {
     /// The initial display value.
     #[inline]
     pub fn inline() -> Self {
         Display::Inline
--- a/servo/components/style_derive/lib.rs
+++ b/servo/components/style_derive/lib.rs
@@ -35,17 +35,17 @@ pub fn derive_compute_squared_distance(s
 }
 
 #[proc_macro_derive(ToAnimatedValue)]
 pub fn derive_to_animated_value(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     to_animated_value::derive(input).into()
 }
 
-#[proc_macro_derive(Parse, attributes(css))]
+#[proc_macro_derive(Parse, attributes(css, parse))]
 pub fn derive_parse(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     parse::derive(input).into()
 }
 
 #[proc_macro_derive(ToAnimatedZero, attributes(animation, zero))]
 pub fn derive_to_animated_zero(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
@@ -59,13 +59,13 @@ pub fn derive_to_computed_value(stream: 
 }
 
 #[proc_macro_derive(ToCss, attributes(css))]
 pub fn derive_to_css(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     to_css::derive(input).into()
 }
 
-#[proc_macro_derive(SpecifiedValueInfo, attributes(css, value_info))]
+#[proc_macro_derive(SpecifiedValueInfo, attributes(css, parse, value_info))]
 pub fn derive_specified_value_info(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     specified_value_info::derive(input).into()
 }
--- a/servo/components/style_derive/parse.rs
+++ b/servo/components/style_derive/parse.rs
@@ -1,52 +1,62 @@
 /* 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/. */
 
 use cg;
 use quote::Tokens;
-use syn::DeriveInput;
+use syn::{DeriveInput, Path};
 use synstructure;
 use to_css::CssVariantAttrs;
 
+#[darling(attributes(parse), default)]
+#[derive(Default, FromVariant)]
+pub struct ParseVariantAttrs {
+    pub aliases: Option<String>,
+    pub condition: Option<Path>,
+}
+
 pub fn derive(input: DeriveInput) -> Tokens {
     let name = &input.ident;
     let s = synstructure::Structure::new(&input);
 
     let mut saw_condition = false;
     let match_body = s.variants().iter().fold(quote!(), |match_body, variant| {
         let bindings = variant.bindings();
         assert!(
             bindings.is_empty(),
             "Parse is only supported for single-variant enums for now"
         );
 
-        let variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
-        if variant_attrs.skip {
+        let css_variant_attrs =
+            cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
+        let parse_attrs =
+            cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
+        if css_variant_attrs.skip {
             return match_body;
         }
 
         let identifier = cg::to_css_identifier(
-            &variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()),
+            &css_variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()),
         );
         let ident = &variant.ast().ident;
 
-        saw_condition |= variant_attrs.parse_condition.is_some();
-        let condition = match variant_attrs.parse_condition {
+        saw_condition |= parse_attrs.condition.is_some();
+        let condition = match parse_attrs.condition {
             Some(ref p) => quote! { if #p(context) },
             None => quote! { },
         };
 
         let mut body = quote! {
             #match_body
             #identifier #condition => Ok(#name::#ident),
         };
 
-        let aliases = match variant_attrs.aliases {
+        let aliases = match parse_attrs.aliases {
             Some(aliases) => aliases,
             None => return body,
         };
 
         for alias in aliases.split(",") {
             body = quote! {
                 #body
                 #alias #condition => Ok(#name::#ident),
--- a/servo/components/style_derive/specified_value_info.rs
+++ b/servo/components/style_derive/specified_value_info.rs
@@ -1,16 +1,17 @@
 /* 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/. */
 
 use cg;
 use quote::Tokens;
 use syn::{Data, DeriveInput, Fields, Ident, Type};
 use to_css::{CssFieldAttrs, CssInputAttrs, CssVariantAttrs};
+use parse::ParseVariantAttrs;
 
 pub fn derive(mut input: DeriveInput) -> Tokens {
     let css_attrs = cg::parse_input_attrs::<CssInputAttrs>(&input);
     let mut types = vec![];
     let mut values = vec![];
 
     let input_ident = input.ident;
     let input_name = || cg::to_css_identifier(input_ident.as_ref());
@@ -28,20 +29,21 @@ pub fn derive(mut input: DeriveInput) ->
         }
         input.generics.where_clause = where_clause;
 
         match input.data {
             Data::Enum(ref e) => {
                 for v in e.variants.iter() {
                     let css_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(&v);
                     let info_attrs = cg::parse_variant_attrs::<ValueInfoVariantAttrs>(&v);
+                    let parse_attrs = cg::parse_variant_attrs::<ParseVariantAttrs>(&v);
                     if css_attrs.skip {
                         continue;
                     }
-                    if let Some(aliases) = css_attrs.aliases {
+                    if let Some(aliases) = parse_attrs.aliases {
                         for alias in aliases.split(",") {
                             values.push(alias.to_string());
                         }
                     }
                     if let Some(other_values) = info_attrs.other_values {
                         for value in other_values.split(",") {
                             values.push(value.to_string());
                         }
--- a/servo/components/style_derive/to_css.rs
+++ b/servo/components/style_derive/to_css.rs
@@ -229,18 +229,16 @@ pub struct CssInputAttrs {
 
 #[darling(attributes(css), default)]
 #[derive(Default, FromVariant)]
 pub struct CssVariantAttrs {
     pub function: Option<Override<String>>,
     pub comma: bool,
     pub dimension: bool,
     pub keyword: Option<String>,
-    pub aliases: Option<String>,
-    pub parse_condition: Option<Path>,
     pub skip: bool,
 }
 
 #[darling(attributes(css), default)]
 #[derive(Default, FromField)]
 pub struct CssFieldAttrs {
     pub if_empty: Option<String>,
     pub field_bound: bool,
--- a/servo/components/style_traits/specified_value_info.rs
+++ b/servo/components/style_traits/specified_value_info.rs
@@ -38,17 +38,17 @@ pub type KeywordsCollectFn<'a> = &'a mut
 /// names following the same rule as `ToCss` in that method.
 ///
 /// Some attributes of `ToCss` can affect the behavior, specifically:
 /// * If `#[css(function)]` is found, the content inside the annotated
 ///   variant (or the whole type) isn't traversed, only the function
 ///   name is listed in `collect_completion_keywords`.
 /// * If `#[css(skip)]` is found, the content inside the variant or
 ///   field is ignored.
-/// * Values listed in `#[css(if_empty)]`, `#[css(aliases)]`, and
+/// * Values listed in `#[css(if_empty)]`, `#[parse(aliases)]`, and
 ///   `#[css(keyword)]` are added into `collect_completion_keywords`.
 ///
 /// In addition to `css` attributes, it also has `value_info` helper
 /// attributes, including:
 /// * `#[value_info(ty = "TYPE")]` can be used to specify a constant
 ///   from `CssType` to `SUPPORTED_TYPES`.
 /// * `#[value_info(other_values = "value1,value2")]` can be used to
 ///   add other values related to a field, variant, or the type itself