[WebIDL] Support partial dictionaries and conditional dictionary members
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Aug 2019 22:52:17 +0000 (22:52 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Aug 2019 22:52:17 +0000 (22:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200441

Reviewed by Alex Christensen.

Added new bindings tests.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDictionaryImplementationContent):
* bindings/scripts/IDLParser.pm:
(parsePartialDefinition):
(parsePartialInterface): Deleted.
(parsePartialDictionary): Deleted.
* bindings/scripts/generate-bindings.pl:
(generateBindings):
* bindings/scripts/preprocess-idls.pl:
(getPartialNamesFromIDL):
(getPartialInterfaceNameFromIDL): Deleted.
* bindings/scripts/test/JS/JSTestEventConstructor.cpp:
(WebCore::convertDictionary<TestEventConstructor::Init>):
* bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
(WebCore::convertDictionary<DictionaryImplName>):
(WebCore::convertDictionaryToJS):
* bindings/scripts/test/JS/JSTestStandaloneDictionary.h:
* bindings/scripts/test/TestStandaloneDictionary.idl:
* bindings/scripts/test/TestSupplemental.idl:

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/IDLParser.pm
Source/WebCore/bindings/scripts/generate-bindings.pl
Source/WebCore/bindings/scripts/preprocess-idls.pl
Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestStandaloneDictionary.h
Source/WebCore/bindings/scripts/test/TestStandaloneDictionary.idl
Source/WebCore/bindings/scripts/test/TestSupplemental.idl

index a18fb73..b2523bb 100644 (file)
@@ -1,3 +1,32 @@
+2019-08-05  Andy Estes  <aestes@apple.com>
+
+        [WebIDL] Support partial dictionaries and conditional dictionary members
+        https://bugs.webkit.org/show_bug.cgi?id=200441
+
+        Reviewed by Alex Christensen.
+
+        Added new bindings tests.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateDictionaryImplementationContent):
+        * bindings/scripts/IDLParser.pm:
+        (parsePartialDefinition):
+        (parsePartialInterface): Deleted.
+        (parsePartialDictionary): Deleted.
+        * bindings/scripts/generate-bindings.pl:
+        (generateBindings):
+        * bindings/scripts/preprocess-idls.pl:
+        (getPartialNamesFromIDL):
+        (getPartialInterfaceNameFromIDL): Deleted.
+        * bindings/scripts/test/JS/JSTestEventConstructor.cpp:
+        (WebCore::convertDictionary<TestEventConstructor::Init>):
+        * bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
+        (WebCore::convertDictionary<DictionaryImplName>):
+        (WebCore::convertDictionaryToJS):
+        * bindings/scripts/test/JS/JSTestStandaloneDictionary.h:
+        * bindings/scripts/test/TestStandaloneDictionary.idl:
+        * bindings/scripts/test/TestSupplemental.idl:
+
 2019-08-05  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: rename "Stylesheet" to "Style Sheet" to match spec text
index 4341717..c0b0f32 100644 (file)
@@ -2332,6 +2332,12 @@ sub GenerateDictionaryImplementationContent
             my $type = $member->type;
             AddToImplIncludesForIDLType($type);
 
+            my $conditional = $member->extendedAttributes->{Conditional};
+            if ($conditional) {
+                my $conditionalString = $codeGenerator->GenerateConditionalStringFromAttributeValue($conditional);
+                $result .= "#if ${conditionalString}\n";
+            }
+
             # 4.1. Let key be the identifier of member.
             my $key = $member->name;
             my $implementedAsKey = $member->extendedAttributes->{ImplementedAs} || $key;
@@ -2368,6 +2374,8 @@ sub GenerateDictionaryImplementationContent
             } else {
                 $result .= "    }\n";
             }
+
+            $result .= "#endif\n" if $conditional;
         }
     }
 
@@ -2399,6 +2407,12 @@ sub GenerateDictionaryImplementationContent
                 my $implementedAsKey = $member->extendedAttributes->{ImplementedAs} || $key;
                 my $valueExpression = "dictionary.${implementedAsKey}";
 
+                my $conditional = $member->extendedAttributes->{Conditional};
+                if ($conditional) {
+                    my $conditionalString = $codeGenerator->GenerateConditionalStringFromAttributeValue($conditional);
+                    $result .= "#if ${conditionalString}\n";
+                }
+
                 # 1. Let key be the identifier of member.
                 # 2. If the dictionary member named key is present in V, then:
                     # 1. Let idlValue be the value of member on V.
@@ -2430,6 +2444,8 @@ sub GenerateDictionaryImplementationContent
                 if ($needsRuntimeCheck) {
                     $result .= "    }\n";
                 }
+
+                $result .= "#endif\n" if $conditional;
             }
         }
 
index bf9813a..ddf4976 100644 (file)
@@ -169,6 +169,7 @@ struct( IDLDictionary => {
     parentType => 'IDLType',
     members => '@', # List of 'IDLDictionaryMember'
     extendedAttributes => '$',
+    isPartial => '$', # Used for partial interfaces
 });
 
 # https://heycam.github.io/webidl/#idl-callback-functions
@@ -887,25 +888,9 @@ sub parsePartialDefinition
         return $interface;
     }
     if ($next->value() eq "dictionary") {
-        return $self->parsePartialDictionary($extendedAttributeList);
-    }
-    $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
-sub parsePartialInterface
-{
-    my $self = shift;
-    my $extendedAttributeList = shift;
-
-    my $next = $self->nextToken();
-    if ($next->value() eq "interface") {
-        $self->assertTokenValue($self->getToken(), "interface", __LINE__);
-        $self->assertTokenType($self->getToken(), IdentifierToken);
-        $self->assertTokenValue($self->getToken(), "{", __LINE__);
-        $self->parseInterfaceMembers();
-        $self->assertTokenValue($self->getToken(), "}", __LINE__);
-        $self->assertTokenValue($self->getToken(), ";", __LINE__);
-        return;
+        my $dictionary = $self->parseDictionary($extendedAttributeList);
+        $dictionary->isPartial(1);
+        return $dictionary;
     }
     $self->assertUnexpectedToken($next->value(), __LINE__);
 }
@@ -1060,22 +1045,6 @@ sub parseDictionaryMember
     $self->assertUnexpectedToken($next->value(), __LINE__);
 }
 
-sub parsePartialDictionary
-{
-    my $self = shift;
-    my $next = $self->nextToken();
-    if ($next->value() eq "dictionary") {
-        $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
-        $self->assertTokenType($self->getToken(), IdentifierToken);
-        $self->assertTokenValue($self->getToken(), "{", __LINE__);
-        $self->parseDictionaryMembers();
-        $self->assertTokenValue($self->getToken(), "}", __LINE__);
-        $self->assertTokenValue($self->getToken(), ";", __LINE__);
-        return;
-    }
-    $self->assertUnexpectedToken($next->value(), __LINE__);
-}
-
 sub parseDefault
 {
     my $self = shift;
index 340e11d..4ab56f2 100755 (executable)
@@ -157,63 +157,92 @@ sub generateBindings
         my $document = $parser->Parse($idlFile, $defines, $preprocessor, $idlAttributes);
 
         foreach my $interface (@{$document->interfaces}) {
-            if (!$interface->isPartial || $interface->type->name eq $targetInterfaceName) {
-                my $targetDataNode;
-                my @targetGlobalContexts;
-                foreach my $interface (@{$targetDocument->interfaces}) {
-                    if ($interface->type->name eq $targetInterfaceName) {
-                        $targetDataNode = $interface;
-                        my $exposedAttribute = $targetDataNode->extendedAttributes->{"Exposed"} || "Window";
-                        $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "(";
-                        @targetGlobalContexts = split(",", $exposedAttribute);
-                        last;
-                    }
+            next unless !$interface->isPartial || $interface->type->name eq $targetInterfaceName;
+
+            my $targetDataNode;
+            my @targetGlobalContexts;
+            foreach my $interface (@{$targetDocument->interfaces}) {
+                if ($interface->type->name eq $targetInterfaceName) {
+                    $targetDataNode = $interface;
+                    my $exposedAttribute = $targetDataNode->extendedAttributes->{"Exposed"} || "Window";
+                    $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "(";
+                    @targetGlobalContexts = split(",", $exposedAttribute);
+                    last;
                 }
-                die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
+            }
+            die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
+
+            # Support for attributes of partial interfaces.
+            foreach my $attribute (@{$interface->attributes}) {
+                next unless shouldPropertyBeExposed($attribute, \@targetGlobalContexts);
+
+                # Record that this attribute is implemented by $interfaceName.
+                $attribute->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial && !$attribute->extendedAttributes->{Reflect};
+
+                # Add interface-wide extended attributes to each attribute.
+                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                    $attribute->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                }
+                push(@{$targetDataNode->attributes}, $attribute);
+            }
 
-                # Support for attributes of partial interfaces.
-                foreach my $attribute (@{$interface->attributes}) {
-                    next unless shouldPropertyBeExposed($attribute, \@targetGlobalContexts);
+            # Support for methods of partial interfaces.
+            foreach my $operation (@{$interface->operations}) {
+                next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
 
-                    # Record that this attribute is implemented by $interfaceName.
-                    $attribute->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial && !$attribute->extendedAttributes->{Reflect};
+                # Record that this method is implemented by $interfaceName.
+                $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
 
-                    # Add interface-wide extended attributes to each attribute.
-                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                        $attribute->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
-                    }
-                    push(@{$targetDataNode->attributes}, $attribute);
+                # Add interface-wide extended attributes to each method.
+                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                    $operation->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
                 }
+                push(@{$targetDataNode->operations}, $operation);
+            }
+
+            # Support for constants of partial interfaces.
+            foreach my $constant (@{$interface->constants}) {
+                next unless shouldPropertyBeExposed($constant, \@targetGlobalContexts);
 
-                # Support for methods of partial interfaces.
-                foreach my $operation (@{$interface->operations}) {
-                    next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
+                # Record that this constant is implemented by $interfaceName.
+                $constant->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
 
-                    # Record that this method is implemented by $interfaceName.
-                    $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
+                # Add interface-wide extended attributes to each constant.
+                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                    $constant->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                }
+                push(@{$targetDataNode->constants}, $constant);
+            }
+        }
 
-                    # Add interface-wide extended attributes to each method.
-                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                        $operation->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
-                    }
-                    push(@{$targetDataNode->operations}, $operation);
+        foreach my $dictionary (@{$document->dictionaries}) {
+            next unless $dictionary->isPartial && $dictionary->type->name eq $targetInterfaceName;
+
+            my $targetDataNode;
+            my @targetGlobalContexts;
+            foreach my $dictionary (@{$targetDocument->dictionaries}) {
+                if ($dictionary->type->name eq $targetInterfaceName) {
+                    $targetDataNode = $dictionary;
+                    my $exposedAttribute = $targetDataNode->extendedAttributes->{"Exposed"} || "Window";
+                    $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "(";
+                    @targetGlobalContexts = split(",", $exposedAttribute);
+                    last;
                 }
+            }
+            die "Could not find dictionary ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
 
-                # Support for constants of partial interfaces.
-                foreach my $constant (@{$interface->constants}) {
-                    next unless shouldPropertyBeExposed($constant, \@targetGlobalContexts);
+            # Support for members of partial dictionaries
+            foreach my $member (@{$dictionary->members}) {
+                next unless shouldPropertyBeExposed($member, \@targetGlobalContexts);
 
-                    # Record that this constant is implemented by $interfaceName.
-                    $constant->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
+                # Record that this member is implemented by $interfaceName.
+                $member->extendedAttributes->{"ImplementedBy"} = $interfaceName;
 
-                    # Add interface-wide extended attributes to each constant.
-                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                        $constant->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
-                    }
-                    push(@{$targetDataNode->constants}, $constant);
+                # Add interface-wide extended attributes to each member.
+                foreach my $extendedAttributeName (keys %{$dictionary->extendedAttributes}) {
+                    $member->extendedAttributes->{$extendedAttributeName} = $dictionary->extendedAttributes->{$extendedAttributeName};
                 }
-            } else {
-                die "$idlFile is not a supplemental dependency of $targetIdlFile. There maybe a bug in the supplemental dependency generator (preprocess-idls.pl).\n";
+                push(@{$targetDataNode->members}, $member);
             }
         }
     }
index 5ea57af..42c51fe 100644 (file)
@@ -112,10 +112,10 @@ foreach my $idlFile (sort keys %idlFileHash) {
 foreach my $idlFile (sort keys %idlFileHash) {
     my $fullPath = Cwd::realpath($idlFile);
     my $idlFileContents = getFileContents($fullPath);
-    # Handle partial interfaces.
-    my $partialInterfaceName = getPartialInterfaceNameFromIDL($idlFileContents);
-    if ($partialInterfaceName) {
-        $supplementalDependencies{$fullPath} = [$partialInterfaceName];
+    # Handle partial names.
+    my $partialNames = getPartialNamesFromIDL($idlFileContents);
+    if (@{$partialNames}) {
+        $supplementalDependencies{$fullPath} = $partialNames;
         next;
     }
 
@@ -333,13 +333,14 @@ sub getFileContents
     return join('', @lines);
 }
 
-sub getPartialInterfaceNameFromIDL
+sub getPartialNamesFromIDL
 {
     my $fileContents = shift;
-
-    if ($fileContents =~ /partial\s+interface\s+(\w+)/gs) {
-        return $1;
+    my @partialNames = ();
+    while ($fileContents =~ /partial\s+(interface|dictionary)\s+(\w+)/mg) {
+        push(@partialNames, $2);
     }
+    return \@partialNames;
 }
 
 # identifier-A implements identifier-B;
index 33e2f9d..663ea57 100644 (file)
@@ -99,6 +99,7 @@ template<> TestEventConstructor::Init convertDictionary<TestEventConstructor::In
         RETURN_IF_EXCEPTION(throwScope, { });
     } else
         result.attr2 = emptyString();
+#if ENABLE(SPECIAL_EVENT)
     JSValue attr3Value;
     if (isNullOrUndefined)
         attr3Value = jsUndefined();
@@ -111,6 +112,7 @@ template<> TestEventConstructor::Init convertDictionary<TestEventConstructor::In
         RETURN_IF_EXCEPTION(throwScope, { });
     } else
         result.attr3 = emptyString();
+#endif
     return result;
 }
 
index e21259e..7f95a1a 100644 (file)
 
 #include "JSTestStandaloneDictionary.h"
 
+#include "Document.h"
 #include "JSDOMConvertBoolean.h"
 #include "JSDOMConvertCallbacks.h"
+#include "JSDOMConvertNumbers.h"
 #include "JSDOMConvertStrings.h"
 #include "JSDOMGlobalObject.h"
 #include "JSVoidCallback.h"
+#include "Settings.h"
 #include <JavaScriptCore/JSCInlines.h>
 #include <JavaScriptCore/JSString.h>
+#include <JavaScriptCore/ObjectConstructor.h>
 #include <wtf/NeverDestroyed.h>
 
 
@@ -83,6 +87,113 @@ template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& s
         result.enumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, enumMemberValue);
         RETURN_IF_EXCEPTION(throwScope, { });
     }
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialBooleanMemberValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberValue = jsUndefined();
+    else {
+        partialBooleanMemberValue = object->get(&state, Identifier::fromString(&state, "partialBooleanMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberValue.isUndefined()) {
+        result.partialBooleanMember = convert<IDLBoolean>(state, partialBooleanMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialBooleanMemberWithIgnoredConditionalValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberWithIgnoredConditionalValue = jsUndefined();
+    else {
+        partialBooleanMemberWithIgnoredConditionalValue = object->get(&state, Identifier::fromString(&state, "partialBooleanMemberWithIgnoredConditional"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberWithIgnoredConditionalValue.isUndefined()) {
+        result.partialBooleanMemberWithIgnoredConditional = convert<IDLBoolean>(state, partialBooleanMemberWithIgnoredConditionalValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialCallbackMemberValue;
+    if (isNullOrUndefined)
+        partialCallbackMemberValue = jsUndefined();
+    else {
+        partialCallbackMemberValue = object->get(&state, Identifier::fromString(&state, "partialCallbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialCallbackMemberValue.isUndefined()) {
+        result.partialCallbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, partialCallbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialEnumMemberValue;
+    if (isNullOrUndefined)
+        partialEnumMemberValue = jsUndefined();
+    else {
+        partialEnumMemberValue = object->get(&state, Identifier::fromString(&state, "partialEnumMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialEnumMemberValue.isUndefined()) {
+        result.partialEnumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, partialEnumMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialRequiredLongMemberValue;
+    if (isNullOrUndefined)
+        partialRequiredLongMemberValue = jsUndefined();
+    else {
+        partialRequiredLongMemberValue = object->get(&state, Identifier::fromString(&state, "partialRequiredLongMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialRequiredLongMemberValue.isUndefined()) {
+        result.partialRequiredLongMember = convert<IDLLong>(state, partialRequiredLongMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    } else {
+        throwRequiredMemberTypeError(state, throwScope, "partialRequiredLongMember", "TestStandaloneDictionary", "long");
+        return { };
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialStringMemberValue;
+    if (isNullOrUndefined)
+        partialStringMemberValue = jsUndefined();
+    else {
+        partialStringMemberValue = object->get(&state, Identifier::fromString(&state, "partialStringMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberValue.isUndefined()) {
+        result.partialStringMember = convert<IDLDOMString>(state, partialStringMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialStringMemberWithEnabledBySettingValue;
+    if (isNullOrUndefined)
+        partialStringMemberWithEnabledBySettingValue = jsUndefined();
+    else {
+        partialStringMemberWithEnabledBySettingValue = object->get(&state, Identifier::fromString(&state, "partialStringMemberWithEnabledBySetting"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberWithEnabledBySettingValue.isUndefined()) {
+        result.partialStringMemberWithEnabledBySetting = convert<IDLDOMString>(state, partialStringMemberWithEnabledBySettingValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    JSValue partialUnsignedLongMemberWithImplementedAsValue;
+    if (isNullOrUndefined)
+        partialUnsignedLongMemberWithImplementedAsValue = jsUndefined();
+    else {
+        partialUnsignedLongMemberWithImplementedAsValue = object->get(&state, Identifier::fromString(&state, "partialUnsignedLongMemberWithImplementedAs"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialUnsignedLongMemberWithImplementedAsValue.isUndefined()) {
+        result.partialUnsignedLongMember = convert<IDLUnsignedLong>(state, partialUnsignedLongMemberWithImplementedAsValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
     JSValue stringMemberValue;
     if (isNullOrUndefined)
         stringMemberValue = jsUndefined();
@@ -97,6 +208,79 @@ template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& s
     return result;
 }
 
+JSC::JSObject* convertDictionaryToJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const DictionaryImplName& dictionary)
+{
+    auto& vm = state.vm();
+
+    auto result = constructEmptyObject(&state, globalObject.objectPrototype());
+
+    if (!IDLBoolean::isNullValue(dictionary.boolMember)) {
+        auto boolMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.boolMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "boolMember"), boolMemberValue);
+    }
+    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.callbackMember)) {
+        auto callbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.callbackMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "callbackMember"), callbackMemberValue);
+    }
+    if (!IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::isNullValue(dictionary.enumMember)) {
+        auto enumMemberValue = toJS<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::extractValueFromNullable(dictionary.enumMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "enumMember"), enumMemberValue);
+    }
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMember)) {
+        auto partialBooleanMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialBooleanMember"), partialBooleanMemberValue);
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMemberWithIgnoredConditional)) {
+        auto partialBooleanMemberWithIgnoredConditionalValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMemberWithIgnoredConditional));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialBooleanMemberWithIgnoredConditional"), partialBooleanMemberWithIgnoredConditionalValue);
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.partialCallbackMember)) {
+        auto partialCallbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.partialCallbackMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialCallbackMember"), partialCallbackMemberValue);
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::isNullValue(dictionary.partialEnumMember)) {
+        auto partialEnumMemberValue = toJS<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::extractValueFromNullable(dictionary.partialEnumMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialEnumMember"), partialEnumMemberValue);
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    auto partialRequiredLongMemberValue = toJS<IDLLong>(dictionary.partialRequiredLongMember);
+    result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialRequiredLongMember"), partialRequiredLongMemberValue);
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLDOMString::isNullValue(dictionary.partialStringMember)) {
+        auto partialStringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialStringMember"), partialStringMemberValue);
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (downcast<Document>(jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext())->settings().testSettingEnabled()) {
+        if (!IDLDOMString::isNullValue(dictionary.partialStringMemberWithEnabledBySetting)) {
+            auto partialStringMemberWithEnabledBySettingValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMemberWithEnabledBySetting));
+            result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialStringMemberWithEnabledBySetting"), partialStringMemberWithEnabledBySettingValue);
+        }
+    }
+#endif
+#if ENABLE(Conditional13) || ENABLE(Conditional14)
+    if (!IDLUnsignedLong::isNullValue(dictionary.partialUnsignedLongMember)) {
+        auto partialUnsignedLongMemberWithImplementedAsValue = toJS<IDLUnsignedLong>(IDLUnsignedLong::extractValueFromNullable(dictionary.partialUnsignedLongMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "partialUnsignedLongMemberWithImplementedAs"), partialUnsignedLongMemberWithImplementedAsValue);
+    }
+#endif
+    if (!IDLDOMString::isNullValue(dictionary.stringMember)) {
+        auto stringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.stringMember));
+        result->putDirect(vm, JSC::Identifier::fromString(&vm, "stringMember"), stringMemberValue);
+    }
+    return result;
+}
+
 #endif
 
 String convertEnumerationToString(TestStandaloneDictionary::EnumInStandaloneDictionaryFile enumerationValue)
index 3467869..1df29f3 100644 (file)
@@ -30,6 +30,8 @@ namespace WebCore {
 
 template<> WEBCORE_EXPORT DictionaryImplName convertDictionary<DictionaryImplName>(JSC::ExecState&, JSC::JSValue);
 
+WEBCORE_EXPORT JSC::JSObject* convertDictionaryToJS(JSC::ExecState&, JSDOMGlobalObject&, const DictionaryImplName&);
+
 String convertEnumerationToString(TestStandaloneDictionary::EnumInStandaloneDictionaryFile);
 template<> JSC::JSString* convertEnumerationToJS(JSC::ExecState&, TestStandaloneDictionary::EnumInStandaloneDictionaryFile);
 
index 5727bac..f68dafc 100644 (file)
@@ -32,6 +32,7 @@ enum TestEnumInStandaloneDictionaryFile { "enumValue1", "enumValue2" };
     ImplementedAs=DictionaryImplName,
     Conditional=Condition1,
     ExportMacro=WEBCORE_EXPORT,
+    JSGenerateToJSObject,
 ] dictionary TestStandaloneDictionary {
     boolean boolMember;
     DOMString stringMember;
index 1cf9876..247fe5b 100644 (file)
     [JSBuiltin] void builtinFunction();
     [JSBuiltin] attribute unsigned short builtinAttribute;
 };
+
+[
+    Conditional=Conditional13|Conditional14,
+] partial dictionary TestStandaloneDictionary {
+    required long partialRequiredLongMember;
+    boolean partialBooleanMember;
+    DOMString partialStringMember;
+    TestEnumInStandaloneDictionaryFile partialEnumMember;
+    VoidCallback partialCallbackMember;
+    [ImplementedAs=partialUnsignedLongMember] unsigned long partialUnsignedLongMemberWithImplementedAs;
+    [Conditional=Conditional15] boolean partialBooleanMemberWithIgnoredConditional;
+    [EnabledBySetting=TestSetting] DOMString partialStringMemberWithEnabledBySetting;
+};