Web Replay: code generator shouldn't complain about enums without a storage type...
authorburg@cs.washington.edu <burg@cs.washington.edu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Oct 2014 18:13:05 +0000 (18:13 +0000)
committerburg@cs.washington.edu <burg@cs.washington.edu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Oct 2014 18:13:05 +0000 (18:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137084

Reviewed by Joseph Pecoraro.

In order to generate encode/decode method declarations without pulling in lots of headers,
the generator must forward declare enums (for enum classes or enums with explicit sizes).

Change the generator to not require an explicit size if an enum is declared inside a struct
or class definition. In that case, it must pull in headers since scoped enums can't be
forward declared.

This patch also fixes some chained if-statements that should be if-else statements.

Test: updated replay/scripts/tests/generate-enum-encoding-helpers.json to cover the new case.

* replay/scripts/CodeGeneratorReplayInputs.py:
(InputsModel.parse_type_with_framework_name.is):
(InputsModel.parse_type_with_framework_name.is.must):
(Generator.generate_enum_trait_implementation):
(InputsModel.parse_type_with_framework_name): Deleted.
* replay/scripts/CodeGeneratorReplayInputsTemplates.py:
* replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error:
* replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp:
(JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
* replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
(JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
(JSC::EncodingTraits<WebCore::PlatformEvent::Type>::encodeValue):
(JSC::EncodingTraits<WebCore::PlatformEvent::Type>::decodeValue):
* replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
* replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp:
(JSC::EncodingTraits<WebCore::FormData1::Type>::decodeValue):
(JSC::EncodingTraits<PlatformEvent1::Type>::decodeValue):
* replay/scripts/tests/generate-enum-encoding-helpers.json: Added a new input to cover this case.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174863 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputs.py
Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputsTemplates.py
Source/JavaScriptCore/replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error
Source/JavaScriptCore/replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp
Source/JavaScriptCore/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp
Source/JavaScriptCore/replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h
Source/JavaScriptCore/replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp
Source/JavaScriptCore/replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp
Source/JavaScriptCore/replay/scripts/tests/generate-enum-encoding-helpers.json

index 67e063f..aa018a4 100644 (file)
@@ -1,3 +1,40 @@
+2014-10-18  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: code generator shouldn't complain about enums without a storage type if they are in an enclosing scope
+        https://bugs.webkit.org/show_bug.cgi?id=137084
+
+        Reviewed by Joseph Pecoraro.
+
+        In order to generate encode/decode method declarations without pulling in lots of headers,
+        the generator must forward declare enums (for enum classes or enums with explicit sizes).
+
+        Change the generator to not require an explicit size if an enum is declared inside a struct
+        or class definition. In that case, it must pull in headers since scoped enums can't be
+        forward declared.
+
+        This patch also fixes some chained if-statements that should be if-else statements.
+
+        Test: updated replay/scripts/tests/generate-enum-encoding-helpers.json to cover the new case.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (InputsModel.parse_type_with_framework_name.is):
+        (InputsModel.parse_type_with_framework_name.is.must):
+        (Generator.generate_enum_trait_implementation):
+        (InputsModel.parse_type_with_framework_name): Deleted.
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py:
+        * replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
+        (JSC::EncodingTraits<WebCore::PlatformEvent::Type>::encodeValue):
+        (JSC::EncodingTraits<WebCore::PlatformEvent::Type>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::FormData1::Type>::decodeValue):
+        (JSC::EncodingTraits<PlatformEvent1::Type>::decodeValue):
+        * replay/scripts/tests/generate-enum-encoding-helpers.json: Added a new input to cover this case.
+
 2014-10-17  Mark Lam  <mark.lam@apple.com>
 
         Web Process crash when starting the web inspector after r174025.
index d9935c2..df9b967 100644 (file)
@@ -454,8 +454,8 @@ class InputsModel:
             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)
 
-            if _type.is_enum() and "storage" not in json:
-                raise ParseException("Could not parse enum %s: C-style enums must also specify their storage type so they can be forward declared." % 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)
 
         self.types.append(_type)
 
@@ -835,8 +835,10 @@ class Generator:
 
         # Generate body for decode.
         decodeLines = []
-        for _value in _type.values:
+        for i, _value in enumerate(_type.values):
+
             template_arguments = {
+                'branchKeyword': "else if" if i > 0 else "if",
                 'enumStringValue': _value,
                 'qualifiedEnumValue': "%s%s" % (enum_prefix, _value),
                 'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
@@ -845,8 +847,9 @@ class Generator:
 
         for guard, guard_values in _type.guard_values_map.iteritems():
             guardedLines = []
-            for guard_value in guard_values:
+            for i, guard_value in enumerate(guard_values):
                 template_arguments = {
+                    'branchKeyword': "else if" if i > 0 else "if",
                     'enumStringValue': guard_value,
                     'qualifiedEnumValue': "%s%s" % (enum_prefix, guard_value),
                     'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
index 3b912cb..8de7bf6 100644 (file)
@@ -209,7 +209,7 @@ bool EncodingTraits<${enumName}>::decodeValue(EncodedValue& encodedValue, ${enum
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
 ${decodeCases}
     }
 
@@ -224,7 +224,7 @@ ${decodeCases}
     }""")
 
     EnumDecodeCase = (
-    """        if (enumString == "${enumStringValue}")
+    """        ${branchKeyword} (enumString == "${enumStringValue}")
             enumValue = static_cast<${qualifiedEnumName}>(enumValue | ${qualifiedEnumValue});""")
 
     InputClassImplementation = (
index 2e8bee6..382fb04 100644 (file)
@@ -1 +1 @@
-ERROR: Could not parse enum MouseButton: C-style enums must also specify their storage type so they can be forward declared.
+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.
index f60559a..30837ed 100644 (file)
@@ -119,19 +119,19 @@ bool EncodingTraits<WebCore::MouseButton>::decodeValue(EncodedValue& encodedValu
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "NoButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::NoButton);
-        if (enumString == "LeftButton")
+        else if (enumString == "LeftButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftButton);
-        if (enumString == "MiddleButton")
+        else if (enumString == "MiddleButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::MiddleButton);
-        if (enumString == "RightButton")
+        else if (enumString == "RightButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightButton);
 #if ENABLE(SIDE_BUTTONS)
         if (enumString == "LeftSideButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftSideButton);
-        if (enumString == "RightSideButton")
+        else if (enumString == "RightSideButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightSideButton);
 #endif // ENABLE(SIDE_BUTTONS)
 #if PLATFORM(WINDOWS)
index b92ae9e..d9f2c1d 100644 (file)
@@ -129,19 +129,65 @@ bool EncodingTraits<WebCore::MouseButton>::decodeValue(EncodedValue& encodedValu
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "NoButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::NoButton);
-        if (enumString == "LeftButton")
+        else if (enumString == "LeftButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftButton);
-        if (enumString == "MiddleButton")
+        else if (enumString == "MiddleButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::MiddleButton);
-        if (enumString == "RightButton")
+        else if (enumString == "RightButton")
             enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightButton);
     }
 
     return true;
 }
+
+EncodedValue EncodingTraits<WebCore::PlatformEvent::Type>::encodeValue(const WebCore::PlatformEvent::Type& enumValue)
+{
+    EncodedValue encodedValue = EncodedValue::createArray();
+    if (enumValue & WebCore::PlatformEvent::Mouse) {
+        encodedValue.append<String>(ASCIILiteral("Mouse"));
+        if (enumValue == WebCore::PlatformEvent::Mouse)
+            return encodedValue;
+    }
+    if (enumValue & WebCore::PlatformEvent::Key) {
+        encodedValue.append<String>(ASCIILiteral("Key"));
+        if (enumValue == WebCore::PlatformEvent::Key)
+            return encodedValue;
+    }
+    if (enumValue & WebCore::PlatformEvent::Touch) {
+        encodedValue.append<String>(ASCIILiteral("Touch"));
+        if (enumValue == WebCore::PlatformEvent::Touch)
+            return encodedValue;
+    }
+    if (enumValue & WebCore::PlatformEvent::Wheel) {
+        encodedValue.append<String>(ASCIILiteral("Wheel"));
+        if (enumValue == WebCore::PlatformEvent::Wheel)
+            return encodedValue;
+    }
+    return encodedValue;
+}
+
+bool EncodingTraits<WebCore::PlatformEvent::Type>::decodeValue(EncodedValue& encodedValue, WebCore::PlatformEvent::Type& enumValue)
+{
+    Vector<String> enumStrings;
+    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
+        return false;
+
+    for (const String& enumString : enumStrings) {
+        if (enumString == "Mouse")
+            enumValue = static_cast<WebCore::PlatformEvent::Type>(enumValue | WebCore::PlatformEvent::Mouse);
+        else if (enumString == "Key")
+            enumValue = static_cast<WebCore::PlatformEvent::Type>(enumValue | WebCore::PlatformEvent::Key);
+        else if (enumString == "Touch")
+            enumValue = static_cast<WebCore::PlatformEvent::Type>(enumValue | WebCore::PlatformEvent::Touch);
+        else if (enumString == "Wheel")
+            enumValue = static_cast<WebCore::PlatformEvent::Type>(enumValue | WebCore::PlatformEvent::Wheel);
+    }
+
+    return true;
+}
 } // namespace JSC
 
 #endif // ENABLE(WEB_REPLAY)
index 2f95a3b..394efb3 100644 (file)
@@ -33,6 +33,7 @@
 #if ENABLE(WEB_REPLAY)
 #include "InternalNamespaceHeaderIncludeDummy.h"
 #include <platform/ExternalNamespaceHeaderIncludeDummy.h>
+#include <platform/PlatformEvent.h>
 
 namespace WebCore {
 enum MouseButton : unsigned;
@@ -68,6 +69,13 @@ template<> struct EncodingTraits<WebCore::MouseButton> {
     static EncodedValue encodeValue(const WebCore::MouseButton& value);
     static bool decodeValue(EncodedValue&, WebCore::MouseButton& value);
 };
+
+template<> struct EncodingTraits<WebCore::PlatformEvent::Type> {
+    typedef WebCore::PlatformEvent::Type DecodedType;
+
+    static EncodedValue encodeValue(const WebCore::PlatformEvent::Type& value);
+    static bool decodeValue(EncodedValue&, WebCore::PlatformEvent::Type& value);
+};
 } // namespace JSC
 
 namespace Test {
index 83a4081..df57171 100644 (file)
@@ -86,7 +86,7 @@ bool EncodingTraits<WebCore::PlatformWheelEventPhase>::decodeValue(EncodedValue&
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "PlatformWheelEventPhaseNone")
             enumValue = static_cast<WebCore::PlatformWheelEventPhase>(enumValue | WebCore::PlatformWheelEventPhaseNone);
     }
index 8228f3d..b7bab8b 100644 (file)
@@ -107,10 +107,10 @@ bool EncodingTraits<WebCore::FormData1::Type>::decodeValue(EncodedValue& encoded
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "Text")
             enumValue = static_cast<WebCore::FormData1::Type>(enumValue | WebCore::FormData1::Text);
-        if (enumString == "Blob")
+        else if (enumString == "Blob")
             enumValue = static_cast<WebCore::FormData1::Type>(enumValue | WebCore::FormData1::Blob);
     }
 
@@ -162,10 +162,10 @@ bool EncodingTraits<PlatformEvent1::Type>::decodeValue(EncodedValue& encodedValu
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "Mouse")
             enumValue = static_cast<PlatformEvent1::Type>(enumValue | PlatformEvent1::Mouse);
-        if (enumString == "Keyboard")
+        else if (enumString == "Keyboard")
             enumValue = static_cast<PlatformEvent1::Type>(enumValue | PlatformEvent1::Keyboard);
     }
 
index 65d71a3..8df1772 100644 (file)
                 "flags": ["ENUM"],
                 "values": ["NoButton", "LeftButton", "MiddleButton", "RightButton"],
                 "header": "platform/PlatformMouseEvent.h"
+            },
+            {
+                "name": "Type", "mode": "SCALAR",
+                "flags": ["ENUM"],
+                "enclosing_class": "PlatformEvent",
+                "values": ["Mouse", "Key", "Touch", "Wheel"],
+                "header": "platform/PlatformEvent.h"
             }
         ]
     },