[WebIDL] Derived dictionaries should inherit their inherited dictionaries' partials
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Sep 2019 00:41:07 +0000 (00:41 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Sep 2019 00:41:07 +0000 (00:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201802

Reviewed by Sam Weinig.

Prior to this change, a dictionary D that inherits from dictionary B would not inherit B's
partial dictionaries. Fixed this by moving supplemental dependencies processing from
generate-bindings.pl to CodeGenerator.pm and reusing it in GetDictionaryByType.

Added new bindings tests.

* bindings/scripts/CodeGenerator.pm:
(new):
(ProcessDocument):
(ProcessSupplementalDependencies):
(shouldPropertyBeExposed):
(GetDictionaryByType):
* bindings/scripts/generate-bindings.pl:
(generateBindings):
(shouldPropertyBeExposed): Deleted.
* bindings/scripts/test/JS/JSTestDerivedDictionary.cpp: Added.
(WebCore::convertDictionary<TestDerivedDictionary>):
(WebCore::convertDictionaryToJS):
* bindings/scripts/test/JS/JSTestDerivedDictionary.h: Added.
* bindings/scripts/test/JS/JSTestInheritedDictionary.cpp: Added.
(WebCore::convertDictionary<TestInheritedDictionary>):
(WebCore::convertDictionaryToJS):
* bindings/scripts/test/JS/JSTestInheritedDictionary.h: Added.
* bindings/scripts/test/TestDerivedDictionary.idl: Added.
* bindings/scripts/test/TestInheritedDictionary.idl: Added.
* bindings/scripts/test/TestSupplemental.idl:

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

Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGenerator.pm
Source/WebCore/bindings/scripts/generate-bindings.pl
Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.cpp [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.h [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.cpp [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.h [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/TestDerivedDictionary.idl [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/TestInheritedDictionary.idl [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/TestSupplemental.idl

index 9dc3254..2cefb1f 100644 (file)
@@ -1,3 +1,37 @@
+2019-09-15  Andy Estes  <aestes@apple.com>
+
+        [WebIDL] Derived dictionaries should inherit their inherited dictionaries' partials
+        https://bugs.webkit.org/show_bug.cgi?id=201802
+
+        Reviewed by Sam Weinig.
+
+        Prior to this change, a dictionary D that inherits from dictionary B would not inherit B's
+        partial dictionaries. Fixed this by moving supplemental dependencies processing from
+        generate-bindings.pl to CodeGenerator.pm and reusing it in GetDictionaryByType.
+
+        Added new bindings tests.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (new):
+        (ProcessDocument):
+        (ProcessSupplementalDependencies):
+        (shouldPropertyBeExposed):
+        (GetDictionaryByType):
+        * bindings/scripts/generate-bindings.pl:
+        (generateBindings):
+        (shouldPropertyBeExposed): Deleted.
+        * bindings/scripts/test/JS/JSTestDerivedDictionary.cpp: Added.
+        (WebCore::convertDictionary<TestDerivedDictionary>):
+        (WebCore::convertDictionaryToJS):
+        * bindings/scripts/test/JS/JSTestDerivedDictionary.h: Added.
+        * bindings/scripts/test/JS/JSTestInheritedDictionary.cpp: Added.
+        (WebCore::convertDictionary<TestInheritedDictionary>):
+        (WebCore::convertDictionaryToJS):
+        * bindings/scripts/test/JS/JSTestInheritedDictionary.h: Added.
+        * bindings/scripts/test/TestDerivedDictionary.idl: Added.
+        * bindings/scripts/test/TestInheritedDictionary.idl: Added.
+        * bindings/scripts/test/TestSupplemental.idl:
+
 2019-09-15  David Kilzer  <ddkilzer@apple.com>
 
         Missing call to [self init] in -[WebScrollbarPartAnimation initWithScrollbar:featureToAnimate:animateFrom:animateTo:duration:]
index dd55279..70eebd9 100644 (file)
@@ -43,6 +43,7 @@ my $idlAttributes;
 my $writeDependencies = 0;
 my $defines = "";
 my $targetIdlFilePath = "";
+my $supplementalDependencies;
 
 my $codeGenerator = 0;
 
@@ -147,6 +148,7 @@ sub new
     $verbose = shift;
     $targetIdlFilePath = shift;
     $idlAttributes = shift;
+    $supplementalDependencies = shift;
 
     bless($reference, $object);
     return $reference;
@@ -158,6 +160,8 @@ sub ProcessDocument
     $useDocument = shift;
     $defines = shift;
 
+    $object->ProcessSupplementalDependencies($useDocument);
+
     my $ifaceName = "CodeGenerator" . $useGenerator;
     require $ifaceName . ".pm";
 
@@ -243,6 +247,134 @@ sub ProcessDocument
     die "Processing document " . $useDocument->fileName . " did not generate anything"
 }
 
+sub ProcessSupplementalDependencies
+{
+    my ($object, $targetDocument) = @_;
+    my $targetFileName = fileparse($targetDocument->fileName);
+    my $targetInterfaceName = fileparse($targetFileName, ".idl");
+
+    if (!$supplementalDependencies) {
+        return;
+    }
+
+    foreach my $idlFile (@{$supplementalDependencies->{$targetFileName}}) {
+        next if fileparse($idlFile) eq $targetFileName;
+
+        my $interfaceName = fileparse($idlFile, ".idl");
+        my $parser = IDLParser->new(!$verbose);
+        my $document = $parser->Parse($idlFile, $defines, $preprocessor, $idlAttributes);
+
+        foreach my $interface (@{$document->interfaces}) {
+            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;
+
+            # 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 methods of partial interfaces.
+            foreach my $operation (@{$interface->operations}) {
+                next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
+
+                # Record that this method is implemented by $interfaceName.
+                $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
+
+                # 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);
+
+                # Record that this constant is implemented by $interfaceName.
+                $constant->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);
+            }
+        }
+
+        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 members of partial dictionaries
+            foreach my $member (@{$dictionary->members}) {
+                next unless shouldPropertyBeExposed($member, \@targetGlobalContexts);
+
+                # Record that this member is implemented by $interfaceName.
+                $member->extendedAttributes->{"ImplementedBy"} = $interfaceName;
+
+                # Add interface-wide extended attributes to each member.
+                foreach my $extendedAttributeName (keys %{$dictionary->extendedAttributes}) {
+                    $member->extendedAttributes->{$extendedAttributeName} = $dictionary->extendedAttributes->{$extendedAttributeName};
+                }
+                push(@{$targetDataNode->members}, $member);
+            }
+        }
+    }
+}
+
+# Attributes / Operations / Constants of supplemental interfaces can have an [Exposed=XX] attribute which restricts
+# on which global contexts they should be exposed.
+sub shouldPropertyBeExposed
+{
+    my ($context, $targetGlobalContexts) = @_;
+
+    my $exposed = $context->extendedAttributes->{Exposed};
+
+    return 1 unless $exposed;
+
+    $exposed = substr($exposed, 1, -1) if substr($exposed, 0, 1) eq "(";
+    my @sourceGlobalContexts = split(",", $exposed);
+
+    for my $targetGlobalContext (@$targetGlobalContexts) {
+        return 1 if grep(/^$targetGlobalContext$/, @sourceGlobalContexts);
+    }
+    return 0;
+}
+
 sub FileNamePrefix
 {
     my $object = shift;
@@ -553,6 +685,8 @@ sub GetDictionaryByType
         my $parser = IDLParser->new(1);
         my $document = $parser->Parse($filename, $defines, $preprocessor, $idlAttributes);
 
+        $object->ProcessSupplementalDependencies($document);
+
         foreach my $dictionary (@{$document->dictionaries}) {
             next unless $dictionary->type->name eq $name;
 
index 4ab56f2..53eeeea 100755 (executable)
@@ -94,7 +94,7 @@ sub generateBindings
     my $targetInterfaceName = fileparse($targetIdlFile, ".idl");
 
     my $idlFound = 0;
-    my @supplementedIdlFiles;
+    my %supplementalDependencies;
     if ($supplementalDependencyFile) {
         # The format of a supplemental dependency file:
         #
@@ -109,13 +109,14 @@ sub generateBindings
         open FH, "< $supplementalDependencyFile" or die "Cannot open $supplementalDependencyFile\n";
         while (my $line = <FH>) {
             my ($idlFile, @followingIdlFiles) = split(/\s+/, $line);
-            if ($idlFile and fileparse($idlFile) eq fileparse($targetIdlFile)) {
-                $idlFound = 1;
-                @supplementedIdlFiles = sort @followingIdlFiles;
-            }
+            $supplementalDependencies{fileparse($idlFile)} = [sort @followingIdlFiles] if $idlFile;
         }
         close FH;
 
+        if (exists $supplementalDependencies{fileparse($targetIdlFile)}) {
+            $idlFound = 1;
+        }
+
         # $additionalIdlFiles is list of IDL files which should not be included in
         # DerivedSources*.cpp (i.e. they are not described in the supplemental
         # dependency file) but should generate .h and .cpp files.
@@ -149,128 +150,11 @@ sub generateBindings
     my $targetParser = IDLParser->new(!$verbose);
     my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocessor, $idlAttributes);
 
-    foreach my $idlFile (@supplementedIdlFiles) {
-        next if $idlFile eq $targetIdlFile;
-
-        my $interfaceName = fileparse($idlFile, ".idl");
-        my $parser = IDLParser->new(!$verbose);
-        my $document = $parser->Parse($idlFile, $defines, $preprocessor, $idlAttributes);
-
-        foreach my $interface (@{$document->interfaces}) {
-            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;
-
-            # 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 methods of partial interfaces.
-            foreach my $operation (@{$interface->operations}) {
-                next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
-
-                # Record that this method is implemented by $interfaceName.
-                $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
-
-                # 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);
-
-                # Record that this constant is implemented by $interfaceName.
-                $constant->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);
-            }
-        }
-
-        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 members of partial dictionaries
-            foreach my $member (@{$dictionary->members}) {
-                next unless shouldPropertyBeExposed($member, \@targetGlobalContexts);
-
-                # Record that this member is implemented by $interfaceName.
-                $member->extendedAttributes->{"ImplementedBy"} = $interfaceName;
-
-                # Add interface-wide extended attributes to each member.
-                foreach my $extendedAttributeName (keys %{$dictionary->extendedAttributes}) {
-                    $member->extendedAttributes->{$extendedAttributeName} = $dictionary->extendedAttributes->{$extendedAttributeName};
-                }
-                push(@{$targetDataNode->members}, $member);
-            }
-        }
-    }
-
     # Generate desired output for the target IDL file.
-    my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose, $targetIdlFile, $idlAttributes);
+    my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose, $targetIdlFile, $idlAttributes, \%supplementalDependencies);
     $codeGen->ProcessDocument($targetDocument, $defines);
 }
 
-# Attributes / Operations / Constants of supplemental interfaces can have an [Exposed=XX] attribute which restricts
-# on which global contexts they should be exposed.
-sub shouldPropertyBeExposed
-{
-    my ($context, $targetGlobalContexts) = @_;
-
-    my $exposed = $context->extendedAttributes->{Exposed};
-
-    return 1 unless $exposed;
-
-    $exposed = substr($exposed, 1, -1) if substr($exposed, 0, 1) eq "(";
-    my @sourceGlobalContexts = split(",", $exposed);
-
-    for my $targetGlobalContext (@$targetGlobalContexts) {
-        return 1 if grep(/^$targetGlobalContext$/, @sourceGlobalContexts);
-    }
-    return 0;
-}
-
 sub generateEmptyHeaderAndCpp
 {
     my ($prefix, $targetInterfaceName, $outputHeadersDirectory, $outputDirectory) = @_;
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.cpp
new file mode 100644 (file)
index 0000000..0ba3db1
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestDerivedDictionary.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/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+template<> TestDerivedDictionary convertDictionary<TestDerivedDictionary>(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    bool isNullOrUndefined = value.isUndefinedOrNull();
+    auto* object = isNullOrUndefined ? nullptr : value.getObject();
+    if (UNLIKELY(!isNullOrUndefined && !object)) {
+        throwTypeError(&state, throwScope);
+        return { };
+    }
+    TestDerivedDictionary result;
+    JSValue boolMemberValue;
+    if (isNullOrUndefined)
+        boolMemberValue = jsUndefined();
+    else {
+        boolMemberValue = object->get(&state, Identifier::fromString(vm, "boolMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!boolMemberValue.isUndefined()) {
+        result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue callbackMemberValue;
+    if (isNullOrUndefined)
+        callbackMemberValue = jsUndefined();
+    else {
+        callbackMemberValue = object->get(&state, Identifier::fromString(vm, "callbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!callbackMemberValue.isUndefined()) {
+        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialBooleanMemberValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberValue = jsUndefined();
+    else {
+        partialBooleanMemberValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberValue.isUndefined()) {
+        result.partialBooleanMember = convert<IDLBoolean>(state, partialBooleanMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#if ENABLE(Conditional15)
+    JSValue partialBooleanMemberWithConditionalValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberWithConditionalValue = jsUndefined();
+    else {
+        partialBooleanMemberWithConditionalValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMemberWithConditional"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberWithConditionalValue.isUndefined()) {
+        result.partialBooleanMemberWithConditional = convert<IDLBoolean>(state, partialBooleanMemberWithConditionalValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+    JSValue partialCallbackMemberValue;
+    if (isNullOrUndefined)
+        partialCallbackMemberValue = jsUndefined();
+    else {
+        partialCallbackMemberValue = object->get(&state, Identifier::fromString(vm, "partialCallbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialCallbackMemberValue.isUndefined()) {
+        result.partialCallbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, partialCallbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialRequiredLongMemberValue;
+    if (isNullOrUndefined)
+        partialRequiredLongMemberValue = jsUndefined();
+    else {
+        partialRequiredLongMemberValue = object->get(&state, Identifier::fromString(vm, "partialRequiredLongMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialRequiredLongMemberValue.isUndefined()) {
+        result.partialRequiredLongMember = convert<IDLLong>(state, partialRequiredLongMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    } else {
+        throwRequiredMemberTypeError(state, throwScope, "partialRequiredLongMember", "TestDerivedDictionary", "long");
+        return { };
+    }
+    JSValue partialStringMemberValue;
+    if (isNullOrUndefined)
+        partialStringMemberValue = jsUndefined();
+    else {
+        partialStringMemberValue = object->get(&state, Identifier::fromString(vm, "partialStringMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberValue.isUndefined()) {
+        result.partialStringMember = convert<IDLDOMString>(state, partialStringMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialStringMemberWithEnabledBySettingValue;
+    if (isNullOrUndefined)
+        partialStringMemberWithEnabledBySettingValue = jsUndefined();
+    else {
+        partialStringMemberWithEnabledBySettingValue = object->get(&state, Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberWithEnabledBySettingValue.isUndefined()) {
+        result.partialStringMemberWithEnabledBySetting = convert<IDLDOMString>(state, partialStringMemberWithEnabledBySettingValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialUnsignedLongMemberWithImplementedAsValue;
+    if (isNullOrUndefined)
+        partialUnsignedLongMemberWithImplementedAsValue = jsUndefined();
+    else {
+        partialUnsignedLongMemberWithImplementedAsValue = object->get(&state, Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialUnsignedLongMemberWithImplementedAsValue.isUndefined()) {
+        result.partialUnsignedLongMember = convert<IDLUnsignedLong>(state, partialUnsignedLongMemberWithImplementedAsValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue stringMemberValue;
+    if (isNullOrUndefined)
+        stringMemberValue = jsUndefined();
+    else {
+        stringMemberValue = object->get(&state, Identifier::fromString(vm, "stringMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!stringMemberValue.isUndefined()) {
+        result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue derivedBoolMemberValue;
+    if (isNullOrUndefined)
+        derivedBoolMemberValue = jsUndefined();
+    else {
+        derivedBoolMemberValue = object->get(&state, Identifier::fromString(vm, "derivedBoolMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!derivedBoolMemberValue.isUndefined()) {
+        result.derivedBoolMember = convert<IDLBoolean>(state, derivedBoolMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const TestDerivedDictionary& 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 (!IDLBoolean::isNullValue(dictionary.partialBooleanMember)) {
+        auto partialBooleanMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMember"), partialBooleanMemberValue);
+    }
+#if ENABLE(Conditional15)
+    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMemberWithConditional)) {
+        auto partialBooleanMemberWithConditionalValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMemberWithConditional));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMemberWithConditional"), partialBooleanMemberWithConditionalValue);
+    }
+#endif
+    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);
+    }
+    auto partialRequiredLongMemberValue = toJS<IDLLong>(dictionary.partialRequiredLongMember);
+    result->putDirect(vm, JSC::Identifier::fromString(vm, "partialRequiredLongMember"), partialRequiredLongMemberValue);
+    if (!IDLDOMString::isNullValue(dictionary.partialStringMember)) {
+        auto partialStringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMember"), partialStringMemberValue);
+    }
+    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);
+        }
+    }
+    if (!IDLUnsignedLong::isNullValue(dictionary.partialUnsignedLongMember)) {
+        auto partialUnsignedLongMemberWithImplementedAsValue = toJS<IDLUnsignedLong>(IDLUnsignedLong::extractValueFromNullable(dictionary.partialUnsignedLongMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"), partialUnsignedLongMemberWithImplementedAsValue);
+    }
+    if (!IDLDOMString::isNullValue(dictionary.stringMember)) {
+        auto stringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.stringMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "stringMember"), stringMemberValue);
+    }
+    if (!IDLBoolean::isNullValue(dictionary.derivedBoolMember)) {
+        auto derivedBoolMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.derivedBoolMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "derivedBoolMember"), derivedBoolMemberValue);
+    }
+    return result;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.h b/Source/WebCore/bindings/scripts/test/JS/JSTestDerivedDictionary.h
new file mode 100644 (file)
index 0000000..04200e6
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMConvertDictionary.h"
+#include "TestDerivedDictionary.h"
+
+namespace WebCore {
+
+template<> TestDerivedDictionary convertDictionary<TestDerivedDictionary>(JSC::ExecState&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::ExecState&, JSDOMGlobalObject&, const TestDerivedDictionary&);
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.cpp
new file mode 100644 (file)
index 0000000..d107c78
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestInheritedDictionary.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/ObjectConstructor.h>
+
+
+namespace WebCore {
+using namespace JSC;
+
+template<> TestInheritedDictionary convertDictionary<TestInheritedDictionary>(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    bool isNullOrUndefined = value.isUndefinedOrNull();
+    auto* object = isNullOrUndefined ? nullptr : value.getObject();
+    if (UNLIKELY(!isNullOrUndefined && !object)) {
+        throwTypeError(&state, throwScope);
+        return { };
+    }
+    TestInheritedDictionary result;
+    JSValue boolMemberValue;
+    if (isNullOrUndefined)
+        boolMemberValue = jsUndefined();
+    else {
+        boolMemberValue = object->get(&state, Identifier::fromString(vm, "boolMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!boolMemberValue.isUndefined()) {
+        result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue callbackMemberValue;
+    if (isNullOrUndefined)
+        callbackMemberValue = jsUndefined();
+    else {
+        callbackMemberValue = object->get(&state, Identifier::fromString(vm, "callbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!callbackMemberValue.isUndefined()) {
+        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialBooleanMemberValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberValue = jsUndefined();
+    else {
+        partialBooleanMemberValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberValue.isUndefined()) {
+        result.partialBooleanMember = convert<IDLBoolean>(state, partialBooleanMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#if ENABLE(Conditional15)
+    JSValue partialBooleanMemberWithConditionalValue;
+    if (isNullOrUndefined)
+        partialBooleanMemberWithConditionalValue = jsUndefined();
+    else {
+        partialBooleanMemberWithConditionalValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMemberWithConditional"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialBooleanMemberWithConditionalValue.isUndefined()) {
+        result.partialBooleanMemberWithConditional = convert<IDLBoolean>(state, partialBooleanMemberWithConditionalValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+#endif
+    JSValue partialCallbackMemberValue;
+    if (isNullOrUndefined)
+        partialCallbackMemberValue = jsUndefined();
+    else {
+        partialCallbackMemberValue = object->get(&state, Identifier::fromString(vm, "partialCallbackMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialCallbackMemberValue.isUndefined()) {
+        result.partialCallbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, partialCallbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialRequiredLongMemberValue;
+    if (isNullOrUndefined)
+        partialRequiredLongMemberValue = jsUndefined();
+    else {
+        partialRequiredLongMemberValue = object->get(&state, Identifier::fromString(vm, "partialRequiredLongMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialRequiredLongMemberValue.isUndefined()) {
+        result.partialRequiredLongMember = convert<IDLLong>(state, partialRequiredLongMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    } else {
+        throwRequiredMemberTypeError(state, throwScope, "partialRequiredLongMember", "TestInheritedDictionary", "long");
+        return { };
+    }
+    JSValue partialStringMemberValue;
+    if (isNullOrUndefined)
+        partialStringMemberValue = jsUndefined();
+    else {
+        partialStringMemberValue = object->get(&state, Identifier::fromString(vm, "partialStringMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberValue.isUndefined()) {
+        result.partialStringMember = convert<IDLDOMString>(state, partialStringMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialStringMemberWithEnabledBySettingValue;
+    if (isNullOrUndefined)
+        partialStringMemberWithEnabledBySettingValue = jsUndefined();
+    else {
+        partialStringMemberWithEnabledBySettingValue = object->get(&state, Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialStringMemberWithEnabledBySettingValue.isUndefined()) {
+        result.partialStringMemberWithEnabledBySetting = convert<IDLDOMString>(state, partialStringMemberWithEnabledBySettingValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue partialUnsignedLongMemberWithImplementedAsValue;
+    if (isNullOrUndefined)
+        partialUnsignedLongMemberWithImplementedAsValue = jsUndefined();
+    else {
+        partialUnsignedLongMemberWithImplementedAsValue = object->get(&state, Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!partialUnsignedLongMemberWithImplementedAsValue.isUndefined()) {
+        result.partialUnsignedLongMember = convert<IDLUnsignedLong>(state, partialUnsignedLongMemberWithImplementedAsValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    JSValue stringMemberValue;
+    if (isNullOrUndefined)
+        stringMemberValue = jsUndefined();
+    else {
+        stringMemberValue = object->get(&state, Identifier::fromString(vm, "stringMember"));
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    if (!stringMemberValue.isUndefined()) {
+        result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+    }
+    return result;
+}
+
+JSC::JSObject* convertDictionaryToJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const TestInheritedDictionary& 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 (!IDLBoolean::isNullValue(dictionary.partialBooleanMember)) {
+        auto partialBooleanMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMember"), partialBooleanMemberValue);
+    }
+#if ENABLE(Conditional15)
+    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMemberWithConditional)) {
+        auto partialBooleanMemberWithConditionalValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMemberWithConditional));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMemberWithConditional"), partialBooleanMemberWithConditionalValue);
+    }
+#endif
+    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);
+    }
+    auto partialRequiredLongMemberValue = toJS<IDLLong>(dictionary.partialRequiredLongMember);
+    result->putDirect(vm, JSC::Identifier::fromString(vm, "partialRequiredLongMember"), partialRequiredLongMemberValue);
+    if (!IDLDOMString::isNullValue(dictionary.partialStringMember)) {
+        auto partialStringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMember"), partialStringMemberValue);
+    }
+    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);
+        }
+    }
+    if (!IDLUnsignedLong::isNullValue(dictionary.partialUnsignedLongMember)) {
+        auto partialUnsignedLongMemberWithImplementedAsValue = toJS<IDLUnsignedLong>(IDLUnsignedLong::extractValueFromNullable(dictionary.partialUnsignedLongMember));
+        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"), partialUnsignedLongMemberWithImplementedAsValue);
+    }
+    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;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.h b/Source/WebCore/bindings/scripts/test/JS/JSTestInheritedDictionary.h
new file mode 100644 (file)
index 0000000..348e6e0
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMConvertDictionary.h"
+#include "TestInheritedDictionary.h"
+
+namespace WebCore {
+
+template<> TestInheritedDictionary convertDictionary<TestInheritedDictionary>(JSC::ExecState&, JSC::JSValue);
+
+JSC::JSObject* convertDictionaryToJS(JSC::ExecState&, JSDOMGlobalObject&, const TestInheritedDictionary&);
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/scripts/test/TestDerivedDictionary.idl b/Source/WebCore/bindings/scripts/test/TestDerivedDictionary.idl
new file mode 100644 (file)
index 0000000..705967a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 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 met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    JSGenerateToJSObject
+] dictionary TestDerivedDictionary : TestInheritedDictionary {
+    boolean derivedBoolMember;
+};
diff --git a/Source/WebCore/bindings/scripts/test/TestInheritedDictionary.idl b/Source/WebCore/bindings/scripts/test/TestInheritedDictionary.idl
new file mode 100644 (file)
index 0000000..786df31
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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 met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    JSGenerateToJSObject
+] dictionary TestInheritedDictionary {
+    boolean boolMember;
+    DOMString stringMember;
+    VoidCallback callbackMember;
+};
index 247fe5b..6fa893e 100644 (file)
     [Conditional=Conditional15] boolean partialBooleanMemberWithIgnoredConditional;
     [EnabledBySetting=TestSetting] DOMString partialStringMemberWithEnabledBySetting;
 };
+
+partial dictionary TestInheritedDictionary {
+    required long partialRequiredLongMember;
+    boolean partialBooleanMember;
+    DOMString partialStringMember;
+    VoidCallback partialCallbackMember;
+    [ImplementedAs=partialUnsignedLongMember] unsigned long partialUnsignedLongMemberWithImplementedAs;
+    [Conditional=Conditional15] boolean partialBooleanMemberWithConditional;
+    [EnabledBySetting=TestSetting] DOMString partialStringMemberWithEnabledBySetting;
+};