[CodeGeneratorJS] Support enums for standalone dictionaries
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Oct 2016 18:24:12 +0000 (18:24 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Oct 2016 18:24:12 +0000 (18:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163885

Reviewed by Youenn Fablet.

Add support for enumerations in WebIDL files that specify
standalone dictionaries. Implementation of this is pretty
straight-forward and mirrors interface and callback generators
by calling GenerateEnumerations{Header,Implementation}Content()
functions in GenerateDictionary{Header,Implementation}().

In GenerateEnumerationsImplementationContent(), the
NeverDestroyed.h header is added to the implementation includes
since that class is used to hold an array of possible enum
values.

A test enum is added to the TestStandaloneDictionary.idl file
and the baselines are updated to reflect the new capability.

* bindings/scripts/CodeGenerator.pm:
(ProcessDocument):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDictionary):
(GenerateEnumerationsImplementationContent):
(GenerateDictionaryHeader):
(GenerateDictionaryImplementation):
* bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
(WebCore::convertEnumerationToJS):
(WebCore::parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
(WebCore::convertEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
(WebCore::expectedEnumerationValues<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
(WebCore::convertDictionary<DictionaryImplName>):
* bindings/scripts/test/JS/JSTestStandaloneDictionary.h:
* bindings/scripts/test/TestStandaloneDictionary.idl:

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGenerator.pm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestStandaloneDictionary.h
Source/WebCore/bindings/scripts/test/TestStandaloneDictionary.idl

index c80cabd..e6c3c3c 100644 (file)
@@ -1,3 +1,40 @@
+2016-10-24  Zan Dobersek  <zdobersek@igalia.com>
+
+        [CodeGeneratorJS] Support enums for standalone dictionaries
+        https://bugs.webkit.org/show_bug.cgi?id=163885
+
+        Reviewed by Youenn Fablet.
+
+        Add support for enumerations in WebIDL files that specify
+        standalone dictionaries. Implementation of this is pretty
+        straight-forward and mirrors interface and callback generators
+        by calling GenerateEnumerations{Header,Implementation}Content()
+        functions in GenerateDictionary{Header,Implementation}().
+
+        In GenerateEnumerationsImplementationContent(), the
+        NeverDestroyed.h header is added to the implementation includes
+        since that class is used to hold an array of possible enum
+        values.
+
+        A test enum is added to the TestStandaloneDictionary.idl file
+        and the baselines are updated to reflect the new capability.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (ProcessDocument):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateDictionary):
+        (GenerateEnumerationsImplementationContent):
+        (GenerateDictionaryHeader):
+        (GenerateDictionaryImplementation):
+        * bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
+        (WebCore::convertEnumerationToJS):
+        (WebCore::parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
+        (WebCore::convertEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
+        (WebCore::expectedEnumerationValues<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>):
+        (WebCore::convertDictionary<DictionaryImplName>):
+        * bindings/scripts/test/JS/JSTestStandaloneDictionary.h:
+        * bindings/scripts/test/TestStandaloneDictionary.idl:
+
 2016-10-24  Dave Hyatt  <hyatt@apple.com>
 
         Remove CSSCharsetRule from the CSS OM
index bf47a3b..90279b9 100644 (file)
@@ -216,7 +216,7 @@ sub ProcessDocument
     # It is possible to have dictionaries in an IDL file without any interface.
     unless (@$interfaces) {
         foreach my $dictionary (@{$useDocument->dictionaries}) {
-            $codeGenerator->GenerateDictionary($dictionary);
+            $codeGenerator->GenerateDictionary($dictionary, $useDocument->enumerations);
             $codeGenerator->WriteData($dictionary, $useOutputDir, $useOutputHeadersDir);
         }
     }
index 5f31454..f4d5f1c 100644 (file)
@@ -134,11 +134,11 @@ sub new
 
 sub GenerateDictionary
 {
-    my ($object, $dictionary) = @_;
+    my ($object, $dictionary, $enumerations) = @_;
 
     my $className = GetDictionaryClassName($dictionary->name);
-    $object->GenerateDictionaryHeader($dictionary, $className);
-    $object->GenerateDictionaryImplementation($dictionary, $className);
+    $object->GenerateDictionaryHeader($dictionary, $className, $enumerations);
+    $object->GenerateDictionaryImplementation($dictionary, $className, $enumerations);
 }
 
 sub GenerateInterface
@@ -889,6 +889,7 @@ sub GenerateEnumerationsImplementationContent
         $result .= "{\n";
         # FIXME: Might be nice to make this global be "const", but NeverDestroyed does not currently support that.
         # FIXME: Might be nice to make the entire array be NeverDestroyed instead of each value, but not sure what the syntax for that is.
+        AddToImplIncludes("<wtf/NeverDestroyed.h>");
         $result .= "    static NeverDestroyed<const String> values[] = {\n";
         foreach my $value (@{$enumeration->values}) {
             if ($value eq "") {
@@ -4454,7 +4455,7 @@ sub GenerateReturnParameters
 
 sub GenerateDictionaryHeader
 {
-    my ($object, $dictionary, $className) = @_;
+    my ($object, $dictionary, $className, $enumerations) = @_;
 
     my $dictionaryName = $dictionary->name;
 
@@ -4466,6 +4467,7 @@ sub GenerateDictionaryHeader
 
     push(@headerContent, "\nnamespace WebCore {\n\n");
     push(@headerContent, GenerateDictionaryHeaderContent($dictionary, $className));
+    push(@headerContent, GenerateEnumerationsHeaderContent($dictionary, $enumerations));
     push(@headerContent, "} // namespace WebCore\n");
 
     my $conditionalString = $codeGenerator->GenerateConditionalString($dictionary);
@@ -4488,13 +4490,14 @@ sub GenerateDictionaryHeader
 
 sub GenerateDictionaryImplementation
 {
-    my ($object, $dictionary, $className) = @_;
+    my ($object, $dictionary, $className, $enumerations) = @_;
 
     # - Add default header template
     push(@implContentHeader, GenerateImplementationContentHeader($dictionary));
 
     push(@implContent, "\nusing namespace JSC;\n\n");
     push(@implContent, "namespace WebCore {\n\n");
+    push(@implContent, GenerateEnumerationsImplementationContent($dictionary, $enumerations));
     push(@implContent, GenerateDictionaryImplementationContent($dictionary, $className));
     push(@implContent, "} // namespace WebCore\n");
 
index a044ccf..1a23e93 100644 (file)
 
 #include "JSTestStandaloneDictionary.h"
 
+#include <runtime/JSString.h>
+#include <wtf/NeverDestroyed.h>
 
 using namespace JSC;
 
 namespace WebCore {
 
+template<> JSString* convertEnumerationToJS(ExecState& state, TestStandaloneDictionary::EnumInStandaloneDictionaryFile enumerationValue)
+{
+    static NeverDestroyed<const String> values[] = {
+        ASCIILiteral("enumValue1"),
+        ASCIILiteral("enumValue2"),
+    };
+    static_assert(static_cast<size_t>(TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1) == 0, "TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1 is not 0 as expected");
+    static_assert(static_cast<size_t>(TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2) == 1, "TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2 is not 1 as expected");
+    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
+    return jsStringWithCache(&state, values[static_cast<size_t>(enumerationValue)]);
+}
+
+template<> Optional<TestStandaloneDictionary::EnumInStandaloneDictionaryFile> parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(ExecState& state, JSValue value)
+{
+    auto stringValue = value.toWTFString(&state);
+    if (stringValue == "enumValue1")
+        return TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1;
+    if (stringValue == "enumValue2")
+        return TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2;
+    return Nullopt;
+}
+
+template<> TestStandaloneDictionary::EnumInStandaloneDictionaryFile convertEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto result = parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(state, value);
+    if (UNLIKELY(!result)) {
+        throwTypeError(&state, throwScope);
+        return { };
+    }
+    return result.value();
+}
+
+template<> const char* expectedEnumerationValues<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>()
+{
+    return "\"enumValue1\", \"enumValue2\"";
+}
+
 template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& state, JSValue value)
 {
     VM& vm = state.vm();
@@ -49,6 +90,11 @@ template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& s
         result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
         RETURN_IF_EXCEPTION(throwScope, { });
     }
+    JSValue enumMemberValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumMember"));
+    if (!enumMemberValue.isUndefined()) {
+        result.enumMember = convert<IDLEnumeration<TestEnumInStandaloneDictionaryFile>>(state, enumMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
     JSValue stringMemberValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "stringMember"));
     if (!stringMemberValue.isUndefined()) {
         result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
index e3b199b..faf1108 100644 (file)
@@ -29,6 +29,12 @@ namespace WebCore {
 
 template<> DictionaryImplName convertDictionary<DictionaryImplName>(JSC::ExecState&, JSC::JSValue);
 
+template<> JSC::JSString* convertEnumerationToJS(JSC::ExecState&, TestStandaloneDictionary::EnumInStandaloneDictionaryFile);
+
+template<> Optional<TestStandaloneDictionary::EnumInStandaloneDictionaryFile> parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(JSC::ExecState&, JSC::JSValue);
+template<> TestStandaloneDictionary::EnumInStandaloneDictionaryFile convertEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(JSC::ExecState&, JSC::JSValue);
+template<> const char* expectedEnumerationValues<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>();
+
 } // namespace WebCore
 
 #endif // ENABLE(Condition1)
index fef5974..b56d477 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+enum TestEnumInStandaloneDictionaryFile { "enumValue1", "enumValue2" };
+
 [
     ImplementedAs=DictionaryImplName,
     Conditional=Condition1,
 ] dictionary TestStandaloneDictionary {
     boolean boolMember;
     DOMString stringMember;
+    TestEnumInStandaloneDictionaryFile enumMember;
 };