Bug 1454831 - Generate nsCSSPropertyID.h from data file directly. r=emilio
authorXidorn Quan <me@upsuper.org>
Wed, 18 Apr 2018 19:39:51 +1000
changeset 468003 cc39f78a3d4e802f834c4c7743ea95c24a6dd7b4
parent 468002 3efb974893b546f2348a65bcb953429cefe5a8fd
child 468004 319ba32110edb2551581a86f299c1e9cf003947b
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1454831
milestone61.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 1454831 - Generate nsCSSPropertyID.h from data file directly. r=emilio MozReview-Commit-ID: CcX2uzgjWFo
layout/style/GenerateCSSPropertyID.py
layout/style/ServoBindings.toml
layout/style/moz.build
layout/style/nsCSSPropertyID.h
layout/style/nsCSSPropertyID.h.in
servo/components/style/build_gecko.rs
new file mode 100644
--- /dev/null
+++ b/layout/style/GenerateCSSPropertyID.py
@@ -0,0 +1,35 @@
+# 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/.
+
+import string
+
+def generate(output, template, dataFile):
+    with open(template, "r") as f:
+        template = string.Template(f.read())
+    with open(dataFile, "r") as f:
+        data = eval(f.read())
+
+    longhand_count = 0
+    shorthand_count = 0
+    alias_count = 0
+    property_ids = []
+    for name, method, id, flags, pref, prototype in data:
+        if prototype != "alias":
+            if prototype == "longhand":
+                assert shorthand_count == 0
+                longhand_count += 1
+            else:
+                assert alias_count == 0
+                shorthand_count += 1
+            property_ids.append("eCSSProperty_{}".format(id))
+        else:
+            alias_count += 1
+            property_ids.append("eCSSPropertyAlias_{}".format(id[0]))
+
+    output.write("/* THIS IS AN AUTOGENERATED FILE.  DO NOT EDIT */\n\n")
+    output.write(template.substitute({
+        "property_ids": "\n".join("  {},".format(p) for p in property_ids),
+        "longhand_count": property_ids[longhand_count],
+        "shorthand_count": property_ids[longhand_count + shorthand_count],
+    }))
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -185,19 +185,16 @@ rusty-enums = [
     "nsINode_BooleanFlag",
     "mozilla::CSSPseudoElementType",
     "mozilla::LookAndFeel_ColorID",
     "mozilla::LookAndFeel_FontID",
     "nsStyleTransformMatrix::MatrixTransformOperator",
     "mozilla::StyleGeometryBox",
     "mozilla::SystemColor",
 ]
-constified-enum-variants = [
-    { enum = "nsCSSPropertyID", variants = ["eCSSProperty_COUNT.*"] },
-]
 whitelist-vars = [
     "NS_AUTHOR_SPECIFIED_.*",
     "NS_THEME_.*",
     "NODE_.*",
     "ELEMENT_.*",
     "NS_FONT_.*",
     "NS_STYLE_.*",
     "NS_MATHML_.*",
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -18,29 +18,29 @@ with Files('CSSRuleList.*'):
 
 with Files('nsDOM*'):
     BUG_COMPONENT = ('Core', 'DOM: CSS Object Model')
 
 DIRS += ['xbl-marquee']
 TEST_DIRS += ['test']
 
 EXPORTS += [
+    '!nsCSSPropertyID.h',
     'AnimationCommon.h',
     'CounterStyleManager.h',
     'nsAnimationManager.h',
     'nsComputedDOMStylePropertyList.h',
     'nsCSSAnonBoxes.h',
     'nsCSSAnonBoxList.h',
     'nsCSSCounterDescList.h',
     'nsCSSFontDescList.h',
     'nsCSSKeywordList.h',
     'nsCSSKeywords.h',
     'nsCSSParser.h',
     'nsCSSPropAliasList.h',
-    'nsCSSPropertyID.h',
     'nsCSSPropertyIDSet.h',
     'nsCSSPropList.h',
     'nsCSSProps.h',
     'nsCSSPseudoElementList.h',
     'nsCSSPseudoElements.h',
     'nsCSSScanner.h',
     'nsCSSValue.h',
     'nsDOMCSSAttrDeclaration.h',
@@ -271,20 +271,28 @@ CONTENT_ACCESSIBLE_FILES += [
     'ImageDocument.css',
     'res/plaintext.css',
     'res/viewsource.css',
     'TopLevelImageDocument.css',
     'TopLevelVideoDocument.css',
 ]
 
 GENERATED_FILES += [
+    'nsCSSPropertyID.h',
     'ServoCSSPropList.h',
     'ServoCSSPropList.py',
 ]
 
+prop_id = GENERATED_FILES['nsCSSPropertyID.h']
+prop_id.script = 'GenerateCSSPropertyID.py:generate'
+prop_id.inputs = [
+    'nsCSSPropertyID.h.in',
+    '!ServoCssPropList.py',
+]
+
 servo_props = GENERATED_FILES['ServoCSSPropList.h']
 servo_props.script = 'GenerateServoCSSPropList.py:generate_header'
 servo_props.inputs = [
     '!ServoCSSPropList.py',
 ]
 
 servo_props = GENERATED_FILES['ServoCSSPropList.py']
 servo_props.script = 'GenerateServoCSSPropList.py:generate_data'
rename from layout/style/nsCSSPropertyID.h
rename to layout/style/nsCSSPropertyID.h.in
--- a/layout/style/nsCSSPropertyID.h
+++ b/layout/style/nsCSSPropertyID.h.in
@@ -16,59 +16,36 @@
    enum values are "eCSSProperty_foo" (where foo is the property)
 
    To change the list of properties, see ServoCSSPropList.h
 
  */
 enum nsCSSPropertyID {
   eCSSProperty_UNKNOWN = -1,
 
-  #define CSS_PROP_LONGHAND(name_, id_, ...) eCSSProperty_##id_,
-  #include "mozilla/ServoCSSPropList.h"
-  #undef CSS_PROP_LONGHAND
-
-  eCSSProperty_COUNT_no_shorthands,
-  // Make the count continue where it left off:
-  eCSSProperty_COUNT_DUMMY = eCSSProperty_COUNT_no_shorthands - 1,
-
-  #define CSS_PROP_SHORTHAND(name_, id_, ...) eCSSProperty_##id_,
-  #include "mozilla/ServoCSSPropList.h"
-  #undef CSS_PROP_SHORTHAND
-
-  eCSSProperty_COUNT,
-  // Make the count continue where it left off:
-  eCSSProperty_COUNT_DUMMY2 = eCSSProperty_COUNT - 1,
-
-  #define CSS_PROP_ALIAS(aliasname_, aliasid_, id_, method_, pref_) \
-    eCSSPropertyAlias_##aliasid_,
-  #include "mozilla/ServoCSSPropList.h"
-  #undef CSS_PROP_ALIAS
-
-  eCSSProperty_COUNT_with_aliases,
-  // Make the count continue where it left off:
-  eCSSProperty_COUNT_DUMMY3 = eCSSProperty_COUNT_with_aliases - 1,
+$property_ids
 
   // Some of the values below could probably overlap with each other
   // if we had a need for them to do so.
 
   // Extra values for use in the values of the 'transition-property'
   // property.
   eCSSPropertyExtra_no_properties,
   eCSSPropertyExtra_all_properties,
 
-  // Extra dummy values for nsCSSParser internal use.
-  eCSSPropertyExtra_x_none_value,
-  eCSSPropertyExtra_x_auto_value,
-
   // Extra value to represent custom properties (--*).
   eCSSPropertyExtra_variable,
+};
 
-  // Extra value for use in the DOM API's
-  eCSSProperty_DOM
-};
+const nsCSSPropertyID
+  eCSSProperty_COUNT_no_shorthands = $longhand_count;
+const nsCSSPropertyID
+  eCSSProperty_COUNT = $shorthand_count;
+const nsCSSPropertyID
+  eCSSProperty_COUNT_with_aliases = eCSSPropertyExtra_no_properties;
 
 namespace mozilla {
 
 template<>
 inline PLDHashNumber
 Hash<nsCSSPropertyID>(const nsCSSPropertyID& aValue)
 {
   return uint32_t(aValue);
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -28,18 +28,17 @@ mod common {
         }
         Ok(())
     }
 }
 
 #[cfg(feature = "bindgen")]
 mod bindings {
     use bindgen::{Builder, CodegenConfig};
-    use bindgen::callbacks::{EnumVariantCustomBehavior, EnumVariantValue, ParseCallbacks};
-    use regex::{Regex, RegexSet};
+    use regex::Regex;
     use std::cmp;
     use std::collections::{HashMap, HashSet};
     use std::env;
     use std::fs::{self, File};
     use std::io::{Read, Write};
     use std::path::{Path, PathBuf};
     use std::process::{exit, Command};
     use std::slice;
@@ -411,67 +410,31 @@ mod bindings {
                     panic!(format!("Unknown key: {}", key));
                 }
             }
             self.builder
         }
     }
 
     fn generate_structs() {
-        #[derive(Debug)]
-        struct Callbacks(HashMap<String, RegexSet>);
-        impl ParseCallbacks for Callbacks {
-            fn enum_variant_behavior(
-                &self,
-                enum_name: Option<&str>,
-                variant_name: &str,
-                _variant_value: EnumVariantValue,
-            ) -> Option<EnumVariantCustomBehavior> {
-                enum_name
-                    .and_then(|enum_name| self.0.get(enum_name))
-                    .and_then(|regex| {
-                        if regex.is_match(variant_name) {
-                            Some(EnumVariantCustomBehavior::Constify)
-                        } else {
-                            None
-                        }
-                    })
-            }
-        }
-
         let builder = Builder::get_initial_builder()
             .enable_cxx_namespaces()
             .with_codegen_config(CodegenConfig {
                 types: true,
                 vars: true,
                 ..CodegenConfig::nothing()
             });
         let mut fixups = vec![];
         let builder = BuilderWithConfig::new(builder, CONFIG["structs"].as_table().unwrap())
             .handle_common(&mut fixups)
             .handle_str_items("bitfield-enums", |b, item| b.bitfield_enum(item))
             .handle_str_items("rusty-enums", |b, item| b.rustified_enum(item))
             .handle_str_items("whitelist-vars", |b, item| b.whitelist_var(item))
             .handle_str_items("whitelist-types", |b, item| b.whitelist_type(item))
             .handle_str_items("opaque-types", |b, item| b.opaque_type(item))
-            .handle_list("constified-enum-variants", |builder, iter| {
-                let mut map = HashMap::new();
-                for item in iter {
-                    let item = item.as_table().unwrap();
-                    let name = item["enum"].as_str().unwrap();
-                    let variants = item["variants"]
-                        .as_array()
-                        .unwrap()
-                        .as_slice()
-                        .iter()
-                        .map(|item| item.as_str().unwrap());
-                    map.insert(name.into(), RegexSet::new(variants).unwrap());
-                }
-                builder.parse_callbacks(Box::new(Callbacks(map)))
-            })
             .handle_table_items("mapped-generic-types", |builder, item| {
                 let generic = item["generic"].as_bool().unwrap();
                 let gecko = item["gecko"].as_str().unwrap();
                 let servo = item["servo"].as_str().unwrap();
                 let gecko_name = gecko.rsplit("::").next().unwrap();
                 let gecko = gecko
                     .split("::")
                     .map(|s| format!("\\s*{}\\s*", s))