Title: [206099] trunk/Source/_javascript_Core
Revision
206099
Author
bb...@apple.com
Date
2016-09-19 10:16:32 -0700 (Mon, 19 Sep 2016)

Log Message

Web Replay: teach the replay inputs generator to encode and decode OptionSet<T>
https://bugs.webkit.org/show_bug.cgi?id=162107

Reviewed by Anders Carlsson.

Add a new type flag OPTION_SET. This means that the type is a typechecked enum class
declaration, but it's stored in an OptionSet object and can contain multiple
distinct enumeration values like an untyped enum declaration.

Do some cleanup since the generator now supports three different enumerable types:
'enum', 'enum class', and 'OptionSet<T>' where T is an enum class.

Also clean up some sloppy variable names. Using an 'enum_' prefix is really confusing now.

* replay/scripts/CodeGeneratorReplayInputs.py:
(Type.is_enum_declaration):
(Type.is_enum_class_declaration):
(Type.is_option_set):
(Type):
(Type.is_enumerable):
When we want all enumerable types, this property includes all three variants.

(Type.declaration_kind): Forward-declare OptionSet's type parameter as an enum class.
(VectorType.is_enum_declaration): Renamed from is_enum().
(VectorType.is_enum_class_declaration): Renamed from is_enum_class().
(VectorType.is_option_set): Added.
(InputsModel.enumerable_types): Added.
(InputsModel.parse_type_with_framework):
(Generator.generate_header):
(Generator.generate_implementation):
(Generator.generate_includes):
(Generator.generate_type_forward_declarations):
(Generator.generate_enumerable_type_trait_declaration):
(Generator.generate_enum_trait_declaration): Renamed.
(Generator.generate_enum_trait_implementation): Renamed.

* replay/scripts/CodeGeneratorReplayInputsTemplates.py:
Add new templates for OptionSet types. Clean up parameter names and simplify the
enumerable type declaration template, which is the same for all enumerable type variants.

* replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error:
* replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
(JSC::EncodingTraits<Test::PlatformEvent::OtherType>::encodeValue):
(JSC::EncodingTraits<Test::PlatformEvent::OtherType>::decodeValue):
* replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
* replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h:
Rebaseline test results.

* replay/scripts/tests/generate-enum-encoding-helpers.json:
Add a new type for OptionSet<PlatformEvent::Modifier> to capture generated encode/decode methods.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (206098 => 206099)


--- trunk/Source/_javascript_Core/ChangeLog	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-09-19 17:16:32 UTC (rev 206099)
@@ -1,3 +1,56 @@
+2016-09-19  Brian Burg  <bb...@apple.com>
+
+        Web Replay: teach the replay inputs generator to encode and decode OptionSet<T>
+        https://bugs.webkit.org/show_bug.cgi?id=162107
+
+        Reviewed by Anders Carlsson.
+
+        Add a new type flag OPTION_SET. This means that the type is a typechecked enum class
+        declaration, but it's stored in an OptionSet object and can contain multiple
+        distinct enumeration values like an untyped enum declaration.
+
+        Do some cleanup since the generator now supports three different enumerable types:
+        'enum', 'enum class', and 'OptionSet<T>' where T is an enum class.
+
+        Also clean up some sloppy variable names. Using an 'enum_' prefix is really confusing now.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.is_enum_declaration):
+        (Type.is_enum_class_declaration):
+        (Type.is_option_set):
+        (Type):
+        (Type.is_enumerable):
+        When we want all enumerable types, this property includes all three variants.
+
+        (Type.declaration_kind): Forward-declare OptionSet's type parameter as an enum class.
+        (VectorType.is_enum_declaration): Renamed from is_enum().
+        (VectorType.is_enum_class_declaration): Renamed from is_enum_class().
+        (VectorType.is_option_set): Added.
+        (InputsModel.enumerable_types): Added.
+        (InputsModel.parse_type_with_framework):
+        (Generator.generate_header):
+        (Generator.generate_implementation):
+        (Generator.generate_includes):
+        (Generator.generate_type_forward_declarations):
+        (Generator.generate_enumerable_type_trait_declaration):
+        (Generator.generate_enum_trait_declaration): Renamed.
+        (Generator.generate_enum_trait_implementation): Renamed.
+
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py:
+        Add new templates for OptionSet types. Clean up parameter names and simplify the
+        enumerable type declaration template, which is the same for all enumerable type variants.
+
+        * replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<Test::PlatformEvent::OtherType>::encodeValue):
+        (JSC::EncodingTraits<Test::PlatformEvent::OtherType>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h:
+        Rebaseline test results.
+
+        * replay/scripts/tests/generate-enum-encoding-helpers.json:
+        Add a new type for OptionSet<PlatformEvent::Modifier> to capture generated encode/decode methods.
+
 2016-09-19  Yusuke Suzuki  <utatane....@gmail.com>
 
         [JSC][LLInt] Introduce is_cell_with_type

Modified: trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputs.py (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputs.py	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputs.py	2016-09-19 17:16:32 UTC (rev 206099)
@@ -302,17 +302,26 @@
     def is_struct(self):
         return self.has_flag("STRUCT")
 
-    def is_enum(self):
+    def is_enum_declaration(self):
         return self.has_flag("ENUM")
 
-    def is_enum_class(self):
+    def is_enum_class_declaration(self):
         return self.has_flag("ENUM_CLASS")
 
+    def is_option_set(self):
+        return self.has_flag("OPTION_SET")
+
+    def is_enumerable(self):
+        return self.is_enum_declaration() or self.is_enum_class_declaration() or self.is_option_set()
+
     def declaration_kind(self):
-        if self.is_enum():
+        if self.is_enum_declaration():
             return "enum"
-        elif self.is_enum_class():
+        elif self.is_enum_class_declaration():
             return "enum class"
+        # If the enumerable is an OptionSet<T>, then T must be forward declared as an enum class.
+        elif self.is_option_set():
+            return "enum class"
         elif self.is_struct():
             return "struct"
         else:
@@ -380,12 +389,15 @@
     def is_struct(self):
         return False
 
-    def is_enum(self):
+    def is_enum_declaration(self):
         return False
 
-    def is_enum_class(self):
+    def is_enum_class_declaration(self):
         return False
 
+    def is_option_set(self):
+        return False
+
     def qualified_prefix(self):
         return ""
 
@@ -409,9 +421,9 @@
         self.types_by_name = {}
         self.inputs_by_name = {}
 
-    def enum_types(self):
-        _enums = filter(lambda x: x.is_enum() or x.is_enum_class(), self.types)
-        return sorted(_enums, key=lambda _enum: _enum.type_name())
+    def enumerable_types(self):
+        _enumerables = filter(lambda x: x.is_enumerable(), self.types)
+        return sorted(_enumerables, key=lambda _enumerable: _enumerable.type_name())
 
     def get_type_for_member(self, member):
         if member.has_flag("VECTOR"):
@@ -453,19 +465,19 @@
         type_mode = TypeMode.fromString(json['mode'])
         header = json.get('header')
         enclosing_class = json.get('enclosing_class')
-        enum_values = json.get('values')
-        guarded_enum_values = json.get('guarded_values', {})
+        enumerable_values = json.get('values')
+        guarded_enumerable_values = json.get('guarded_values', {})
         type_storage = json.get('storage')
         type_flags = json.get('flags', [])
         guard = json.get('guard', None)
-        _type = Type(type_name, type_mode, framework, header, enclosing_class, enum_values, guarded_enum_values, type_storage, type_flags, guard)
-        if _type.is_enum() or _type.is_enum_class():
+        _type = Type(type_name, type_mode, framework, header, enclosing_class, enumerable_values, guarded_enumerable_values, type_storage, type_flags, guard)
+        if _type.is_enumerable():
             check_for_required_properties(['values'], json, 'enum')
             if not isinstance(json['values'], list) or len(_type.values) == 0:
-                raise ParseException("Malformed specification: enum %s does not supply a list of values" % type_name)
+                raise ParseException("Malformed specification: enumerable type %s does not supply a list of values" % type_name)
 
-            if _type.is_enum() and enclosing_class is None and type_storage is None:
-                raise ParseException("Could not parse enum %s: C-style enums not enclosed by a class must specify their storage type so they can be forward declared." % type_name)
+            if _type.is_enum_declaration() and enclosing_class is None and type_storage is None:
+                raise ParseException("Could not parse enumerable type %s: C-style enum declarations not enclosed by a class must specify their storage type so they can be forward declared." % type_name)
 
         self.types.append(_type)
 
@@ -597,7 +609,7 @@
         implementation_file.close()
 
     def generate_header(self):
-        enums_to_generate = filter(self.should_generate_item, self._model.enum_types())
+        enumerable_types_to_generate = filter(self.should_generate_item, self._model.enumerable_types())
         inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
 
         template_arguments = {
@@ -613,7 +625,7 @@
             'inputClassDeclarations': "\n\n".join([self.generate_class_declaration(_input) for _input in inputs_to_generate]),
             'inputTraitDeclarations': "\n\n".join([self.generate_input_trait_declaration(_input) for _input in inputs_to_generate]),
             'inputTypeTraitDeclarations': "\n\n".join([self.generate_input_type_trait_declaration(_input) for _input in inputs_to_generate]),
-            'enumTraitDeclarations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_declaration(_type), _type.guard) for _type in enums_to_generate]),
+            'enumerableTypeTraitDeclarations': "\n\n".join([wrap_with_guard(self.generate_enumerable_type_trait_declaration(_type), _type.guard) for _type in enumerable_types_to_generate]),
             'forEachMacro': self.generate_for_each_macro(),
         }
 
@@ -620,7 +632,7 @@
         return Template(Templates.HeaderSkeleton).substitute(template_arguments)
 
     def generate_implementation(self):
-        enums_to_generate = filter(self.should_generate_item, self._model.enum_types())
+        enumerable_types_to_generate = filter(self.should_generate_item, self._model.enumerable_types())
         inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
 
         template_arguments = {
@@ -632,7 +644,7 @@
             'includes': self.generate_includes(defaults=self.setting('implIncludes'), includes_for_types=True),
             'inputClassImplementations': "\n\n".join([self.generate_class_implementation(_input) for _input in inputs_to_generate]),
             'inputTraitImplementations': "\n\n".join([self.generate_input_trait_implementation(_input) for _input in inputs_to_generate]),
-            'enumTraitImplementations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_implementation(_type), _type.guard) for _type in enums_to_generate]),
+            'enumerableTypeTraitImplementations': "\n\n".join([wrap_with_guard(self.generate_enumerable_type_trait_implementation(_type), _type.guard) for _type in enumerable_types_to_generate]),
         }
 
         return Template(Templates.ImplementationSkeleton).substitute(template_arguments)
@@ -650,7 +662,7 @@
             # For RefCounted types, we reverse when to include the header so that the destructor can be
             # used in the header file.
             include_for_destructor = _type.mode is TypeModes.SHARED
-            # Enums within classes cannot be forward declared, so we include
+            # Enum declarations within classes cannot be forward declared, so we include
             # headers with the relevant class declaration.
             include_for_enclosing_class = _type.enclosing_class is not None
             # Include headers for types like URL and String which are copied, not owned or shared.
@@ -691,9 +703,9 @@
                 continue
             if _type.mode == TypeModes.HEAVY_SCALAR:
                 continue
-            if _type.mode == TypeModes.SCALAR and not (_type.is_enum() or _type.is_enum_class()):
+            if _type.mode == TypeModes.SCALAR and not _type.is_enumerable():
                 continue
-            if _type.is_enum():
+            if _type.is_enum_declaration():
                 declaration = "enum %s : %s;" % (_type.type_name(), _type.underlying_storage)
             else:
                 declaration = "%s %s;" % (_type.declaration_kind(), _type.type_name())
@@ -793,19 +805,22 @@
 
         return wrap_with_guard(Template(Templates.InputTypeTraitsDeclaration).substitute(template_arguments), _input.guard)
 
-    def generate_enum_trait_declaration(self, _type):
+    def generate_enumerable_type_trait_declaration(self, _type):
         decl_type = ['struct']
         if len(self.setting('exportMacro')) > 0:
             decl_type.append(self.setting('exportMacro'))
 
         should_qualify_type = _type.framework != self.traits_framework
-        template = Templates.EnumTraitDeclaration if _type.is_enum() else Templates.EnumClassTraitDeclaration
+        decoded_type = _type.type_name(qualified=should_qualify_type)
+        if _type.is_option_set():
+            decoded_type = "OptionSet<%s>" % decoded_type
+
         template_arguments = {
             'encodingTypeArgument': _type.encoding_type_argument(qualified=should_qualify_type),
-            'enumType': _type.type_name(qualified=should_qualify_type),
+            'enumerableType': decoded_type,
             'structOrClass': " ".join(decl_type)
         }
-        return Template(template).substitute(template_arguments)
+        return Template(Templates.EnumerableTypeTraitDeclaration).substitute(template_arguments)
 
     def generate_for_each_macro(self):
         inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
@@ -828,33 +843,37 @@
 
         return wrap_with_guard(Template(Templates.InputClassImplementation).substitute(template_arguments), _input.guard)
 
-    def generate_enum_trait_implementation(self, _type):
+    def generate_enumerable_type_trait_implementation(self, _type):
         should_qualify_type = _type.framework != self.traits_framework
         prefix_components = []
         if should_qualify_type:
             prefix_components.append(_type.framework.setting('namespace'))
-        if _type.is_enum() and _type.enclosing_class is not None:
+        if _type.is_enum_declaration() and _type.enclosing_class is not None:
             prefix_components.append(_type.enclosing_class)
-        elif _type.is_enum_class():
+        elif _type.is_enum_class_declaration() or _type.is_option_set():
             prefix_components.append(_type.type_name(qualified=False))
         prefix_components.append("")
-        enum_prefix = "::".join(prefix_components)
+        enumerable_type_prefix = "::".join(prefix_components)
         encodeLines = []
 
-        if _type.is_enum():
-            encode_template = Templates.EnumEncodeCase
-            decode_template = Templates.EnumDecodeCase
-            enum_trait_template = Templates.EnumTraitImplementation
-        else:
-            encode_template = Templates.EnumClassEncodeCase
-            decode_template = Templates.EnumClassDecodeCase
-            enum_trait_template = Templates.EnumClassTraitImplementation
+        if _type.is_enum_declaration():
+            encode_template = Templates.EnumTypeEncodeCase
+            decode_template = Templates.EnumTypeDecodeCase
+            enumerable_type_trait_template = Templates.EnumTypeTraitImplementation
+        elif _type.is_enum_class_declaration():
+            encode_template = Templates.EnumClassTypeEncodeCase
+            decode_template = Templates.EnumClassTypeDecodeCase
+            enumerable_type_trait_template = Templates.EnumClassTypeTraitImplementation
+        else:  # Thus, _type.is_option_set().
+            encode_template = Templates.OptionSetTypeEncodeCase
+            decode_template = Templates.OptionSetTypeDecodeCase
+            enumerable_type_trait_template = Templates.OptionSetTypeTraitImplementation
 
         # Generate body for encode.
         for _value in _type.values:
             template_arguments = {
                 'enumStringValue': _value,
-                'qualifiedEnumValue': "%s%s" % (enum_prefix, _value),
+                'qualifiedEnumValue': "%s%s" % (enumerable_type_prefix, _value),
             }
             encodeLines.append(Template(encode_template).substitute(template_arguments))
 
@@ -863,7 +882,7 @@
             for guard_value in guard_values:
                 template_arguments = {
                     'enumStringValue': guard_value,
-                    'qualifiedEnumValue': "%s%s" % (enum_prefix, guard_value),
+                    'qualifiedEnumValue': "%s%s" % (enumerable_type_prefix, guard_value),
                 }
                 guardedLines.append(Template(encode_template).substitute(template_arguments))
             encodeLines.append(wrap_with_guard("\n".join(guardedLines), guard))
@@ -875,7 +894,7 @@
             template_arguments = {
                 'branchKeyword': "else if" if i > 0 else "if",
                 'enumStringValue': _value,
-                'qualifiedEnumValue': "%s%s" % (enum_prefix, _value),
+                'qualifiedEnumValue': "%s%s" % (enumerable_type_prefix, _value),
                 'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
             }
             decodeLines.append(Template(decode_template).substitute(template_arguments))
@@ -886,20 +905,24 @@
                 template_arguments = {
                     'branchKeyword': "else if" if i > 0 else "if",
                     'enumStringValue': guard_value,
-                    'qualifiedEnumValue': "%s%s" % (enum_prefix, guard_value),
+                    'qualifiedEnumValue': "%s%s" % (enumerable_type_prefix, guard_value),
                     'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
                 }
                 guardedLines.append(Template(decode_template).substitute(template_arguments))
             decodeLines.append(wrap_with_guard("\n".join(guardedLines), guard))
 
+        enumerable_type = _type.type_name(qualified=should_qualify_type)
+        if _type.is_option_set():
+            enumerable_type = "OptionSet<%s>" % enumerable_type
+
         template_arguments = {
             'encodingTypeArgument': _type.encoding_type_argument(qualified=should_qualify_type),
-            'enumType': _type.type_name(qualified=should_qualify_type),
+            'enumerableType': enumerable_type,
             'encodeCases': "\n".join(encodeLines),
             'decodeCases': "\n".join(decodeLines)
         }
 
-        return Template(enum_trait_template).substitute(template_arguments)
+        return Template(enumerable_type_trait_template).substitute(template_arguments)
 
     def generate_input_trait_implementation(self, _input):
         template_arguments = {

Modified: trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputsTemplates.py (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputsTemplates.py	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/CodeGeneratorReplayInputsTemplates.py	2016-09-19 17:16:32 UTC (rev 206099)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # Copyright (c) 2011 Google Inc. All rights reserved.
 # Copyright (c) 2012 Intel Corporation. All rights reserved.
-# Copyright (c) 2013, 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2013, 2014, 2016 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -81,7 +81,7 @@
 
 namespace ${traitsNamespace} {
 ${inputTraitDeclarations}
-${enumTraitDeclarations}
+${enumerableTypeTraitDeclarations}
 } // namespace ${traitsNamespace}
 
 namespace ${inputsNamespace} {
@@ -111,22 +111,14 @@
     static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<${qualifiedInputName}>::type(); }
 SPECIALIZE_TYPE_TRAITS_END()""")
 
-    EnumTraitDeclaration = (
+    EnumerableTypeTraitDeclaration = (
     """template<> ${structOrClass} EncodingTraits<${encodingTypeArgument}> {
-    typedef ${enumType} DecodedType;
+    typedef ${enumerableType} DecodedType;
 
-    static EncodedValue encodeValue(const ${enumType}& value);
-    static bool decodeValue(EncodedValue&, ${enumType}& value);
+    static EncodedValue encodeValue(const ${enumerableType}& value);
+    static bool decodeValue(EncodedValue&, ${enumerableType}& value);
 };""")
 
-    EnumClassTraitDeclaration = (
-    """template<> ${structOrClass} EncodingTraits<${encodingTypeArgument}> {
-    typedef ${enumType} DecodedType;
-
-    static EncodedValue encodeValue(const ${enumType}& value);
-    static bool decodeValue(EncodedValue&, ${enumType}& value);
-};""")
-
     InputClassDeclaration = (
     """class ${inputName} : public ${baseClass} {
 public:
@@ -152,7 +144,7 @@
 
 namespace ${traitsNamespace} {
 ${inputTraitImplementations}
-${enumTraitImplementations}
+${enumerableTypeTraitImplementations}
 } // namespace ${traitsNamespace}
 
 #endif // ${guardCondition}
@@ -177,8 +169,8 @@
     return true;
 }""")
 
-    EnumClassTraitImplementation = (
-    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumType}& enumValue)
+    EnumClassTypeTraitImplementation = (
+    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumerableType}& enumValue)
 {
     switch (enumValue) {
 ${encodeCases}
@@ -186,7 +178,7 @@
     }
 }
 
-bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumType}& enumValue)
+bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumerableType}& enumValue)
 {
     String enumString = encodedValue.convertTo<String>();
 ${decodeCases}
@@ -193,17 +185,17 @@
     return false;
 }""")
 
-    EnumClassEncodeCase = (
+    EnumClassTypeEncodeCase = (
     """    case ${qualifiedEnumValue}: return EncodedValue::createString("${enumStringValue}");""")
 
-    EnumClassDecodeCase = (
+    EnumClassTypeDecodeCase = (
     """    if (enumString == "${enumStringValue}") {
         enumValue = ${qualifiedEnumValue};
         return true;
     }""")
 
-    EnumTraitImplementation = (
-    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumType}& enumValue)
+    EnumTypeTraitImplementation = (
+    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumerableType}& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();
 ${encodeCases}
@@ -210,7 +202,7 @@
     return encodedValue;
 }
 
-bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumType}& enumValue)
+bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumerableType}& enumValue)
 {
     Vector<String> enumStrings;
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
@@ -223,7 +215,7 @@
     return true;
 }""")
 
-    EnumEncodeCase = (
+    EnumTypeEncodeCase = (
     """    if (enumValue & ${qualifiedEnumValue}) {
         encodedValue.append<String>(ASCIILiteral("${enumStringValue}"));
         if (enumValue == ${qualifiedEnumValue})
@@ -230,10 +222,41 @@
             return encodedValue;
     }""")
 
-    EnumDecodeCase = (
+    EnumTypeDecodeCase = (
     """        ${branchKeyword} (enumString == "${enumStringValue}")
             enumValue = static_cast<${qualifiedEnumName}>(enumValue | ${qualifiedEnumValue});""")
 
+    OptionSetTypeTraitImplementation = (
+    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumerableType}& enumValue)
+{
+    EncodedValue encodedValue = EncodedValue::createArray();
+${encodeCases}
+
+    return encodedValue;
+}
+
+bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumerableType}& enumValue)
+{
+    Vector<String> enumStrings;
+    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
+        return false;
+
+    for (const String& enumString : enumStrings) {
+${decodeCases}
+    }
+
+    return true;
+}""")
+
+    OptionSetTypeEncodeCase = (
+    """    if (enumValue.contains(${qualifiedEnumValue}))
+        encodedValue.append<String>(ASCIILiteral("${enumStringValue}"));""")
+
+    OptionSetTypeDecodeCase = (
+    """        ${branchKeyword} (enumString == "${enumStringValue}")
+            enumValue |= ${qualifiedEnumValue};""")
+
+
     InputClassImplementation = (
     """${inputName}::${inputName}(${constructorFormalsList})
 ${initializerList}

Modified: trunk/Source/_javascript_Core/replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error	2016-09-19 17:16:32 UTC (rev 206099)
@@ -1 +1 @@
-ERROR: Could not parse enum MouseButton: C-style enums not enclosed by a class must specify their storage type so they can be forward declared.
+ERROR: Could not parse enumerable type MouseButton: C-style enum declarations not enclosed by a class must specify their storage type so they can be forward declared.

Modified: trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp	2016-09-19 17:16:32 UTC (rev 206099)
@@ -143,6 +143,41 @@
     return true;
 }
 
+EncodedValue EncodingTraits<Test::PlatformEvent::OtherType>::encodeValue(const OptionSet<Test::PlatformEvent::OtherType>& enumValue)
+{
+    EncodedValue encodedValue = EncodedValue::createArray();
+    if (enumValue.contains(Test::PlatformEvent::OtherType::Mouse))
+        encodedValue.append<String>(ASCIILiteral("Mouse"));
+    if (enumValue.contains(Test::PlatformEvent::OtherType::Key))
+        encodedValue.append<String>(ASCIILiteral("Key"));
+    if (enumValue.contains(Test::PlatformEvent::OtherType::Touch))
+        encodedValue.append<String>(ASCIILiteral("Touch"));
+    if (enumValue.contains(Test::PlatformEvent::OtherType::Wheel))
+        encodedValue.append<String>(ASCIILiteral("Wheel"));
+
+    return encodedValue;
+}
+
+bool EncodingTraits<Test::PlatformEvent::OtherType>::decodeValue(EncodedValue& encodedValue, OptionSet<Test::PlatformEvent::OtherType>& enumValue)
+{
+    Vector<String> enumStrings;
+    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
+        return false;
+
+    for (const String& enumString : enumStrings) {
+        if (enumString == "Mouse")
+            enumValue |= Test::PlatformEvent::OtherType::Mouse;
+        else if (enumString == "Key")
+            enumValue |= Test::PlatformEvent::OtherType::Key;
+        else if (enumString == "Touch")
+            enumValue |= Test::PlatformEvent::OtherType::Touch;
+        else if (enumString == "Wheel")
+            enumValue |= Test::PlatformEvent::OtherType::Wheel;
+    }
+
+    return true;
+}
+
 EncodedValue EncodingTraits<Test::PlatformEvent::Type>::encodeValue(const Test::PlatformEvent::Type& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();

Modified: trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h	2016-09-19 17:16:32 UTC (rev 206099)
@@ -67,6 +67,13 @@
     static bool decodeValue(EncodedValue&, Test::MouseButton& value);
 };
 
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::PlatformEvent::OtherType> {
+    typedef OptionSet<Test::PlatformEvent::OtherType> DecodedType;
+
+    static EncodedValue encodeValue(const OptionSet<Test::PlatformEvent::OtherType>& value);
+    static bool decodeValue(EncodedValue&, OptionSet<Test::PlatformEvent::OtherType>& value);
+};
+
 template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::PlatformEvent::Type> {
     typedef Test::PlatformEvent::Type DecodedType;
 

Modified: trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h	2016-09-19 17:16:32 UTC (rev 206099)
@@ -72,7 +72,7 @@
     virtual ~HandleWheelEvent();
 
     // EventLoopInput API
-    void dispatch(ReplayController&) final;
+    virtual void dispatch(ReplayController&) final;
     const PlatformWheelEvent& platformEvent() const { return *m_platformEvent; }
     PlatformWheelPhase phase() const { return m_phase; }
 private:

Modified: trunk/Source/_javascript_Core/replay/scripts/tests/generate-enum-encoding-helpers.json (206098 => 206099)


--- trunk/Source/_javascript_Core/replay/scripts/tests/generate-enum-encoding-helpers.json	2016-09-19 17:00:25 UTC (rev 206098)
+++ trunk/Source/_javascript_Core/replay/scripts/tests/generate-enum-encoding-helpers.json	2016-09-19 17:16:32 UTC (rev 206099)
@@ -19,6 +19,13 @@
                 "enclosing_class": "PlatformEvent",
                 "values": ["Mouse", "Key", "Touch", "Wheel"],
                 "header": "platform/PlatformEvent.h"
+            },
+            {
+                "name": "OtherType", "mode": "SCALAR",
+                "flags": ["OPTION_SET"],
+                "enclosing_class": "PlatformEvent",
+                "values": ["Mouse", "Key", "Touch", "Wheel"],
+                "header": "platform/PlatformEvent.h"
             }
         ]
     },
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to