Bug 1454831 - Generate nsCSSPropertyID.h from data file directly. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Wed, 18 Apr 2018 19:39:51 +1000
changeset 784918 b4abe072eaee773b9b457431725ea01fe404e6e7
parent 784863 4a2029bedb9990393927a86fdbb610f5f8eafa23
push id107079
push userxquan@mozilla.com
push dateThu, 19 Apr 2018 11:05:18 +0000
reviewersemilio
bugs1454831
milestone61.0a1
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))