Title: [206776] trunk/Source/WebCore
Revision
206776
Author
[email protected]
Date
2016-10-04 11:51:44 -0700 (Tue, 04 Oct 2016)

Log Message

[Web IDL] Add support for dictionary inheritance
https://bugs.webkit.org/show_bug.cgi?id=162907

Reviewed by Sam Weinig.

Add support for dictionary inheritance to our Web IDL parser and
bindings generator. Leverage this new support for EventTarget's
EventListenerOptions / AddEventListenerOptions dictionaries, in
order to match the DOM specification:
- https://dom.spec.whatwg.org/#interface-eventtarget

Also update the bindings generator to convert the dictionary
members in lexicographical order, as per:
- https://heycam.github.io/webidl/#es-dictionary (Step 5.1)

No new tests, rebaselined bindings tests.

* bindings/scripts/CodeGenerator.pm:
(GetDictionaryByName):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDictionaryImplementationContent):
* bindings/scripts/IDLParser.pm:
(parseDictionary):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::convertDictionary<TestObj::Dictionary>):
(WebCore::convertDictionary<TestObj::DictionaryThatShouldNotTolerateNull>):
(WebCore::convertDictionary<TestObj::DictionaryThatShouldTolerateNull>):
(WebCore::convertDictionary<AlternateDictionaryName>):
(WebCore::convertDictionary<TestObj::ParentDictionary>):
(WebCore::convertDictionary<TestObj::ChildDictionary>):
* bindings/scripts/test/TestObj.idl:
* dom/EventTarget.idl:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (206775 => 206776)


--- trunk/Source/WebCore/ChangeLog	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/ChangeLog	2016-10-04 18:51:44 UTC (rev 206776)
@@ -1,3 +1,38 @@
+2016-10-04  Chris Dumez  <[email protected]>
+
+        [Web IDL] Add support for dictionary inheritance
+        https://bugs.webkit.org/show_bug.cgi?id=162907
+
+        Reviewed by Sam Weinig.
+
+        Add support for dictionary inheritance to our Web IDL parser and
+        bindings generator. Leverage this new support for EventTarget's
+        EventListenerOptions / AddEventListenerOptions dictionaries, in
+        order to match the DOM specification:
+        - https://dom.spec.whatwg.org/#interface-eventtarget
+
+        Also update the bindings generator to convert the dictionary
+        members in lexicographical order, as per:
+        - https://heycam.github.io/webidl/#es-dictionary (Step 5.1)
+
+        No new tests, rebaselined bindings tests.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (GetDictionaryByName):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateDictionaryImplementationContent):
+        * bindings/scripts/IDLParser.pm:
+        (parseDictionary):
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::convertDictionary<TestObj::Dictionary>):
+        (WebCore::convertDictionary<TestObj::DictionaryThatShouldNotTolerateNull>):
+        (WebCore::convertDictionary<TestObj::DictionaryThatShouldTolerateNull>):
+        (WebCore::convertDictionary<AlternateDictionaryName>):
+        (WebCore::convertDictionary<TestObj::ParentDictionary>):
+        (WebCore::convertDictionary<TestObj::ChildDictionary>):
+        * bindings/scripts/test/TestObj.idl:
+        * dom/EventTarget.idl:
+
 2016-10-04  Brent Fulgham  <[email protected]>
 
         [Win][Direct2D] Add initial D2D GraphicsContext implementation

Modified: trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm (206775 => 206776)


--- trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm	2016-10-04 18:51:44 UTC (rev 206776)
@@ -455,6 +455,16 @@
     return 0;
 }
 
+sub GetDictionaryByName
+{
+    my ($object, $name) = @_;
+    return unless defined($name);
+
+    for my $dictionary (@{$useDocument->dictionaries}) {
+        return $dictionary if $dictionary->name eq $name;
+    }
+}
+
 sub HasDictionaryImplementationNameOverride
 {
     my ($object, $type) = @_;

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (206775 => 206776)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-04 18:51:44 UTC (rev 206776)
@@ -953,10 +953,10 @@
 
 sub GenerateDictionaryImplementationContent
 {
-    my ($interface, $dictionaries) = @_;
+    my ($interface, $allDictionaries) = @_;
 
     my $result = "";
-    foreach my $dictionary (@$dictionaries) {
+    foreach my $dictionary (@$allDictionaries) {
         my $name = $dictionary->name;
 
         my $conditionalString = $codeGenerator->GenerateConditionalString($dictionary);
@@ -988,79 +988,90 @@
         $result .= "    }\n";
 
         # 3. Let dict be an empty dictionary value of type D; every dictionary member is initially considered to be not present.
+
         # 4. Let dictionaries be a list consisting of D and all of D’s inherited dictionaries, in order from least to most derived.
-        # FIXME: We do not support dictionary inheritence yet.
+        my @dictionaries;
+        push(@dictionaries, $dictionary);
+        my $parentDictionary = $codeGenerator->GetDictionaryByName($dictionary->parent);
+        while (defined($parentDictionary)) {
+            unshift(@dictionaries, $parentDictionary);
+            $parentDictionary = $codeGenerator->GetDictionaryByName($parentDictionary->parent);
+        }
 
+        my $arguments = "";
+        my $comma = "";
+
         # 5. For each dictionary dictionary in dictionaries, in order:
-        foreach my $member (@{$dictionary->members}) {
-            $member->default("undefined") if $member->type eq "any"; # Use undefined as default value for member of type 'any'.
+        foreach my $dictionary (@dictionaries) {
+            # For each dictionary member member declared on dictionary, in lexicographical order:
+            my @sortedMembers = sort { $a->name cmp $b->name } @{$dictionary->members};
+            foreach my $member (@sortedMembers) {
+                $member->default("undefined") if $member->type eq "any"; # Use undefined as default value for member of type 'any'.
 
-            my $type = $member->type;
+                my $type = $member->type;
 
-            # 5.1. Let key be the identifier of member.
-            my $key = $member->name;
+                # 5.1. Let key be the identifier of member.
+                my $key = $member->name;
 
-            # 5.2. Let value be an ECMAScript value, depending on Type(V):
-            $result .= "    JSValue ${key}Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, \"${key}\"));\n";
+                # 5.2. Let value be an ECMAScript value, depending on Type(V):
+                $result .= "    JSValue ${key}Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, \"${key}\"));\n";
 
-            my $nativeType = GetNativeTypeFromSignature($interface, $member);
-            if ($member->isOptional && !defined $member->default) {
-                $result .= "    Converter<$nativeType>::OptionalValue $key;\n";
-            } else {
-                $result .= "    $nativeType $key;\n";
-            }
+                my $nativeType = GetNativeTypeFromSignature($interface, $member);
+                if ($member->isOptional && !defined $member->default) {
+                    $result .= "    Converter<$nativeType>::OptionalValue $key;\n";
+                } else {
+                    $result .= "    $nativeType $key;\n";
+                }
 
-            # 5.3. If value is not undefined, then:
-            $result .= "    if (!${key}Value.isUndefined()) {\n";
-            # FIXME: Eventually we will want this to share a lot more code with JSValueToNative.
-            if ($codeGenerator->IsWrapperType($type)) {
-                AddToImplIncludes("JS${type}.h");
-                die "Dictionary members of non-nullable wrapper types must be marked as required" if !$member->isNullable && $member->isOptional;
-                my $nullableParameter = $member->isNullable ? "IsNullable::Yes" : "IsNullable::No";
-                $result .= "        $key = convertWrapperType<$type, JS${type}>(state, ${key}Value, $nullableParameter);\n";
-            } elsif ($codeGenerator->IsDictionaryType($type)) {
-                my $nativeType = GetNativeType($interface, $type);
-                $result .= "        $key = convertDictionary<${nativeType}>(state, ${key}Value);\n";
-            } else {
-                my $conversionRuleWithLeadingComma = GenerateConversionRuleWithLeadingComma($interface, $member);
-                $result .= "        $key = convert<${nativeType}>(state, ${key}Value${conversionRuleWithLeadingComma});\n";
+                # 5.3. If value is not undefined, then:
+                $result .= "    if (!${key}Value.isUndefined()) {\n";
+                # FIXME: Eventually we will want this to share a lot more code with JSValueToNative.
+                if ($codeGenerator->IsWrapperType($type)) {
+                    AddToImplIncludes("JS${type}.h");
+                    die "Dictionary members of non-nullable wrapper types must be marked as required" if !$member->isNullable && $member->isOptional;
+                    my $nullableParameter = $member->isNullable ? "IsNullable::Yes" : "IsNullable::No";
+                    $result .= "        $key = convertWrapperType<$type, JS${type}>(state, ${key}Value, $nullableParameter);\n";
+                } elsif ($codeGenerator->IsDictionaryType($type)) {
+                    my $nativeType = GetNativeType($interface, $type);
+                    $result .= "        $key = convertDictionary<${nativeType}>(state, ${key}Value);\n";
+                } else {
+                    my $conversionRuleWithLeadingComma = GenerateConversionRuleWithLeadingComma($interface, $member);
+                    $result .= "        $key = convert<${nativeType}>(state, ${key}Value${conversionRuleWithLeadingComma});\n";
+                }
+                $result .= "        RETURN_IF_EXCEPTION(throwScope, Nullopt);\n";
+                # Value is undefined.
+                # 5.4. Otherwise, if value is undefined but the dictionary member has a default value, then:
+                if ($member->isOptional && defined $member->default) {
+                    $result .= "    } else\n";
+                    $result .= "        $key = " . GenerateDefaultValue($interface, $member) . ";\n";
+                } elsif (!$member->isOptional) {
+                    # 5.5. Otherwise, if value is undefined and the dictionary member is a required dictionary member, then throw a TypeError.
+                    $result .= "    } else {\n";
+                    $result .= "        throwTypeError(&state, throwScope);\n";
+                    $result .= "        return Nullopt;\n";
+                    $result .= "    }\n";
+                } else {
+                    $result .= "    }\n";
+                }
             }
-            $result .= "        RETURN_IF_EXCEPTION(throwScope, Nullopt);\n";
-            # Value is undefined.
-            # 5.4. Otherwise, if value is undefined but the dictionary member has a default value, then:
-            if ($member->isOptional && defined $member->default) {
-                $result .= "    } else\n";
-                $result .= "        $key = " . GenerateDefaultValue($interface, $member) . ";\n";
-            } elsif (!$member->isOptional) {
-                # 5.5. Otherwise, if value is undefined and the dictionary member is a required dictionary member, then throw a TypeError.
-                $result .= "    } else {\n";
-                $result .= "        throwTypeError(&state, throwScope);\n";
-                $result .= "        return Nullopt;\n";
-                $result .= "    }\n";
-            } else {
-                $result .= "    }\n";
-            }
-        }
 
-        # 6. Return dict.
-        my $arguments = "";
-        my $comma = "";
-        foreach my $member (@{$dictionary->members}) {
-            my $value;
-            if ($codeGenerator->IsWrapperType($member->type) && !$member->isNullable) {
-                $value = "*" . $member->name;
-            } elsif ($codeGenerator->IsDictionaryType($member->type)) {
-                $value = $member->name . ".value()";
-            } else {
-                $value = "WTFMove(" . $member->name . ")";
+            # 6. Return dict.
+            foreach my $member (@{$dictionary->members}) {
+                my $value;
+                if ($codeGenerator->IsWrapperType($member->type) && !$member->isNullable) {
+                    $value = "*" . $member->name;
+                } elsif ($codeGenerator->IsDictionaryType($member->type)) {
+                    $value = $member->name . ".value()";
+                } else {
+                    $value = "WTFMove(" . $member->name . ")";
+                }
+                $arguments .= $comma . $value;
+                $comma = ", ";
             }
-            $arguments .= $comma . $value;
-            $comma = ", ";
         }
 
         $result .= "    return $className { " . $arguments . " };\n";
         $result .= "}\n\n";
-
         $result .= "#endif\n\n" if $conditionalString;
     }
     return $result;

Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (206775 => 206776)


--- trunk/Source/WebCore/bindings/scripts/IDLParser.pm	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/bindings/scripts/IDLParser.pm	2016-10-04 18:51:44 UTC (rev 206776)
@@ -130,6 +130,7 @@
 });
 
 struct( domDictionary => {
+    parent => '$',  # Parent class identifier
     name => '$',
     members => '@', # List of 'domSignature'
     extendedAttributes => '$',
@@ -659,7 +660,8 @@
         my $nameToken = $self->getToken();
         $self->assertTokenType($nameToken, IdentifierToken);
         $dictionary->name($nameToken->value());
-        $self->parseInheritance();
+        my $parents = $self->parseInheritance();
+        $dictionary->parent($parents->[0]);
         $self->assertTokenValue($self->getToken(), "{", __LINE__);
         $dictionary->members($self->parseDictionaryMembers());
         $self->assertTokenValue($self->getToken(), "}", __LINE__);

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (206775 => 206776)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-04 18:51:44 UTC (rev 206776)
@@ -530,12 +530,39 @@
         throwTypeError(&state, throwScope);
         return Nullopt;
     }
-    JSValue enumerationValueWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumerationValueWithoutDefault"));
-    Converter<TestObj::EnumType>::OptionalValue enumerationValueWithoutDefault;
-    if (!enumerationValueWithoutDefaultValue.isUndefined()) {
-        enumerationValueWithoutDefault = convert<TestObj::EnumType>(state, enumerationValueWithoutDefaultValue);
+    JSValue anyTypedefValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "anyTypedefValue"));
+    JSC::JSValue anyTypedefValue;
+    if (!anyTypedefValueValue.isUndefined()) {
+        anyTypedefValue = convert<JSC::JSValue>(state, anyTypedefValueValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        anyTypedefValue = jsUndefined();
+    JSValue anyValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "anyValue"));
+    JSC::JSValue anyValue;
+    if (!anyValueValue.isUndefined()) {
+        anyValue = convert<JSC::JSValue>(state, anyValueValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        anyValue = jsUndefined();
+    JSValue booleanWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithDefault"));
+    bool booleanWithDefault;
+    if (!booleanWithDefaultValue.isUndefined()) {
+        booleanWithDefault = convert<bool>(state, booleanWithDefaultValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        booleanWithDefault = false;
+    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
+    Converter<bool>::OptionalValue booleanWithoutDefault;
+    if (!booleanWithoutDefaultValue.isUndefined()) {
+        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
+    JSValue dictionaryMemberValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "dictionaryMember"));
+    Converter<TestObj::DictionaryThatShouldTolerateNull>::OptionalValue dictionaryMember;
+    if (!dictionaryMemberValue.isUndefined()) {
+        dictionaryMember = convertDictionary<TestObj::DictionaryThatShouldTolerateNull>(state, dictionaryMemberValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
     JSValue enumerationValueWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumerationValueWithDefault"));
     TestObj::EnumType enumerationValueWithDefault;
     if (!enumerationValueWithDefaultValue.isUndefined()) {
@@ -550,38 +577,45 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         enumerationValueWithEmptyStringDefault = TestObj::EnumType::EmptyString;
-    JSValue stringWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "stringWithDefault"));
-    String stringWithDefault;
-    if (!stringWithDefaultValue.isUndefined()) {
-        stringWithDefault = convert<String>(state, stringWithDefaultValue);
+    JSValue enumerationValueWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumerationValueWithoutDefault"));
+    Converter<TestObj::EnumType>::OptionalValue enumerationValueWithoutDefault;
+    if (!enumerationValueWithoutDefaultValue.isUndefined()) {
+        enumerationValueWithoutDefault = convert<TestObj::EnumType>(state, enumerationValueWithoutDefaultValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        stringWithDefault = "defaultString";
-    JSValue stringWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "stringWithoutDefault"));
-    Converter<String>::OptionalValue stringWithoutDefault;
-    if (!stringWithoutDefaultValue.isUndefined()) {
-        stringWithoutDefault = convert<String>(state, stringWithoutDefaultValue);
+    }
+    JSValue integerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "integer"));
+    Converter<int32_t>::OptionalValue integer;
+    if (!integerValue.isUndefined()) {
+        integer = convert<int32_t>(state, integerValue, NormalConversion);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue booleanWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithDefault"));
-    bool booleanWithDefault;
-    if (!booleanWithDefaultValue.isUndefined()) {
-        booleanWithDefault = convert<bool>(state, booleanWithDefaultValue);
+    JSValue integerWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "integerWithDefault"));
+    int32_t integerWithDefault;
+    if (!integerWithDefaultValue.isUndefined()) {
+        integerWithDefault = convert<int32_t>(state, integerWithDefaultValue, NormalConversion);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
-        booleanWithDefault = false;
-    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
-    Converter<bool>::OptionalValue booleanWithoutDefault;
-    if (!booleanWithoutDefaultValue.isUndefined()) {
-        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
+        integerWithDefault = 0;
+    JSValue largeIntegerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "largeInteger"));
+    Converter<int64_t>::OptionalValue largeInteger;
+    if (!largeIntegerValue.isUndefined()) {
+        largeInteger = convert<int64_t>(state, largeIntegerValue, NormalConversion);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue sequenceOfStringsValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "sequenceOfStrings"));
-    Converter<Vector<String>>::OptionalValue sequenceOfStrings;
-    if (!sequenceOfStringsValue.isUndefined()) {
-        sequenceOfStrings = convert<Vector<String>>(state, sequenceOfStringsValue);
+    JSValue largeIntegerWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "largeIntegerWithDefault"));
+    int64_t largeIntegerWithDefault;
+    if (!largeIntegerWithDefaultValue.isUndefined()) {
+        largeIntegerWithDefault = convert<int64_t>(state, largeIntegerWithDefaultValue, NormalConversion);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
+    } else
+        largeIntegerWithDefault = 0;
+    JSValue nullableNodeValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "nullableNode"));
+    Node* nullableNode;
+    if (!nullableNodeValue.isUndefined()) {
+        nullableNode = convertWrapperType<Node, JSNode>(state, nullableNodeValue, IsNullable::Yes);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        nullableNode = nullptr;
     JSValue restrictedDoubleValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "restrictedDouble"));
     Converter<double>::OptionalValue restrictedDouble;
     if (!restrictedDoubleValue.isUndefined()) {
@@ -588,12 +622,6 @@
         restrictedDouble = convert<double>(state, restrictedDoubleValue, ShouldAllowNonFinite::No);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue unrestrictedDoubleValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedDouble"));
-    Converter<double>::OptionalValue unrestrictedDouble;
-    if (!unrestrictedDoubleValue.isUndefined()) {
-        unrestrictedDouble = convert<double>(state, unrestrictedDoubleValue, ShouldAllowNonFinite::Yes);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
     JSValue restrictedDoubleWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "restrictedDoubleWithDefault"));
     double restrictedDoubleWithDefault;
     if (!restrictedDoubleWithDefaultValue.isUndefined()) {
@@ -601,13 +629,6 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         restrictedDoubleWithDefault = 0;
-    JSValue unrestrictedDoubleWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedDoubleWithDefault"));
-    double unrestrictedDoubleWithDefault;
-    if (!unrestrictedDoubleWithDefaultValue.isUndefined()) {
-        unrestrictedDoubleWithDefault = convert<double>(state, unrestrictedDoubleWithDefaultValue, ShouldAllowNonFinite::Yes);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        unrestrictedDoubleWithDefault = 0;
     JSValue restrictedFloatValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "restrictedFloat"));
     Converter<float>::OptionalValue restrictedFloat;
     if (!restrictedFloatValue.isUndefined()) {
@@ -614,12 +635,6 @@
         restrictedFloat = convert<float>(state, restrictedFloatValue, ShouldAllowNonFinite::No);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue unrestrictedFloatValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedFloat"));
-    Converter<float>::OptionalValue unrestrictedFloat;
-    if (!unrestrictedFloatValue.isUndefined()) {
-        unrestrictedFloat = convert<float>(state, unrestrictedFloatValue, ShouldAllowNonFinite::Yes);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
     JSValue restrictedFloatWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "restrictedFloatWithDefault"));
     float restrictedFloatWithDefault;
     if (!restrictedFloatWithDefaultValue.isUndefined()) {
@@ -627,13 +642,12 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         restrictedFloatWithDefault = 0;
-    JSValue unrestrictedFloatWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedFloatWithDefault"));
-    float unrestrictedFloatWithDefault;
-    if (!unrestrictedFloatWithDefaultValue.isUndefined()) {
-        unrestrictedFloatWithDefault = convert<float>(state, unrestrictedFloatWithDefaultValue, ShouldAllowNonFinite::Yes);
+    JSValue sequenceOfStringsValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "sequenceOfStrings"));
+    Converter<Vector<String>>::OptionalValue sequenceOfStrings;
+    if (!sequenceOfStringsValue.isUndefined()) {
+        sequenceOfStrings = convert<Vector<String>>(state, sequenceOfStringsValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        unrestrictedFloatWithDefault = 0;
+    }
     JSValue smallIntegerClampedValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "smallIntegerClamped"));
     Converter<int8_t>::OptionalValue smallIntegerClamped;
     if (!smallIntegerClampedValue.isUndefined()) {
@@ -659,19 +673,45 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         smallUnsignedIntegerWithDefault = 0;
-    JSValue integerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "integer"));
-    Converter<int32_t>::OptionalValue integer;
-    if (!integerValue.isUndefined()) {
-        integer = convert<int32_t>(state, integerValue, NormalConversion);
+    JSValue stringWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "stringWithDefault"));
+    String stringWithDefault;
+    if (!stringWithDefaultValue.isUndefined()) {
+        stringWithDefault = convert<String>(state, stringWithDefaultValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        stringWithDefault = "defaultString";
+    JSValue stringWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "stringWithoutDefault"));
+    Converter<String>::OptionalValue stringWithoutDefault;
+    if (!stringWithoutDefaultValue.isUndefined()) {
+        stringWithoutDefault = convert<String>(state, stringWithoutDefaultValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue integerWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "integerWithDefault"));
-    int32_t integerWithDefault;
-    if (!integerWithDefaultValue.isUndefined()) {
-        integerWithDefault = convert<int32_t>(state, integerWithDefaultValue, NormalConversion);
+    JSValue unrestrictedDoubleValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedDouble"));
+    Converter<double>::OptionalValue unrestrictedDouble;
+    if (!unrestrictedDoubleValue.isUndefined()) {
+        unrestrictedDouble = convert<double>(state, unrestrictedDoubleValue, ShouldAllowNonFinite::Yes);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    JSValue unrestrictedDoubleWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedDoubleWithDefault"));
+    double unrestrictedDoubleWithDefault;
+    if (!unrestrictedDoubleWithDefaultValue.isUndefined()) {
+        unrestrictedDoubleWithDefault = convert<double>(state, unrestrictedDoubleWithDefaultValue, ShouldAllowNonFinite::Yes);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
-        integerWithDefault = 0;
+        unrestrictedDoubleWithDefault = 0;
+    JSValue unrestrictedFloatValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedFloat"));
+    Converter<float>::OptionalValue unrestrictedFloat;
+    if (!unrestrictedFloatValue.isUndefined()) {
+        unrestrictedFloat = convert<float>(state, unrestrictedFloatValue, ShouldAllowNonFinite::Yes);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    JSValue unrestrictedFloatWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unrestrictedFloatWithDefault"));
+    float unrestrictedFloatWithDefault;
+    if (!unrestrictedFloatWithDefaultValue.isUndefined()) {
+        unrestrictedFloatWithDefault = convert<float>(state, unrestrictedFloatWithDefaultValue, ShouldAllowNonFinite::Yes);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else
+        unrestrictedFloatWithDefault = 0;
     JSValue unsignedIntegerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unsignedInteger"));
     Converter<uint32_t>::OptionalValue unsignedInteger;
     if (!unsignedIntegerValue.isUndefined()) {
@@ -685,19 +725,6 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         unsignedIntegerWithDefault = 0;
-    JSValue largeIntegerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "largeInteger"));
-    Converter<int64_t>::OptionalValue largeInteger;
-    if (!largeIntegerValue.isUndefined()) {
-        largeInteger = convert<int64_t>(state, largeIntegerValue, NormalConversion);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
-    JSValue largeIntegerWithDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "largeIntegerWithDefault"));
-    int64_t largeIntegerWithDefault;
-    if (!largeIntegerWithDefaultValue.isUndefined()) {
-        largeIntegerWithDefault = convert<int64_t>(state, largeIntegerWithDefaultValue, NormalConversion);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        largeIntegerWithDefault = 0;
     JSValue unsignedLargeIntegerValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "unsignedLargeInteger"));
     Converter<uint64_t>::OptionalValue unsignedLargeInteger;
     if (!unsignedLargeIntegerValue.isUndefined()) {
@@ -711,33 +738,6 @@
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     } else
         unsignedLargeIntegerWithDefault = 0;
-    JSValue nullableNodeValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "nullableNode"));
-    Node* nullableNode;
-    if (!nullableNodeValue.isUndefined()) {
-        nullableNode = convertWrapperType<Node, JSNode>(state, nullableNodeValue, IsNullable::Yes);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        nullableNode = nullptr;
-    JSValue anyValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "anyValue"));
-    JSC::JSValue anyValue;
-    if (!anyValueValue.isUndefined()) {
-        anyValue = convert<JSC::JSValue>(state, anyValueValue);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        anyValue = jsUndefined();
-    JSValue anyTypedefValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "anyTypedefValue"));
-    JSC::JSValue anyTypedefValue;
-    if (!anyTypedefValueValue.isUndefined()) {
-        anyTypedefValue = convert<JSC::JSValue>(state, anyTypedefValueValue);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else
-        anyTypedefValue = jsUndefined();
-    JSValue dictionaryMemberValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "dictionaryMember"));
-    Converter<TestObj::DictionaryThatShouldTolerateNull>::OptionalValue dictionaryMember;
-    if (!dictionaryMemberValue.isUndefined()) {
-        dictionaryMember = convertDictionary<TestObj::DictionaryThatShouldTolerateNull>(state, dictionaryMemberValue);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
     return TestObj::Dictionary { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings), WTFMove(restrictedDouble), WTFMove(unrestrictedDouble), WTFMove(restrictedDoubleWithDefault), WTFMove(unrestrictedDoubleWithDefault), WTFMove(restrictedFloat), WTFMove(unrestrictedFloat), WTFMove(restrictedFloatWithDefault), WTFMove(unrestrictedFloatWithDefault), WTFMove(smallIntegerClamped), WTFMove(smallIntegerWithDefault), WTFMove(smallUnsignedIntegerEnforcedRange), WTFMove(smallUnsignedIntegerWithDefault), WTFMove(integer), WTFMove(integerWithDefault), WTFMove(unsignedInteger), WTFMove(unsignedIntegerWithDefault), WTFMove(largeInteger), WTFMove(largeIntegerWithDefault), WTFMove(unsignedLargeInteger), WTFMove(unsignedLargeIntegerWithDefault), WTF
 Move(nullableNode), WTFMove(anyValue), WTFMove(anyTypedefValue), dictionaryMember.value() };
 }
 
@@ -755,15 +755,6 @@
         throwTypeError(&state, throwScope);
         return Nullopt;
     }
-    JSValue requiredEnumerationValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "requiredEnumerationValue"));
-    TestObj::EnumType requiredEnumerationValue;
-    if (!requiredEnumerationValueValue.isUndefined()) {
-        requiredEnumerationValue = convert<TestObj::EnumType>(state, requiredEnumerationValueValue);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    } else {
-        throwTypeError(&state, throwScope);
-        return Nullopt;
-    }
     JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
     Converter<bool>::OptionalValue booleanWithoutDefault;
     if (!booleanWithoutDefaultValue.isUndefined()) {
@@ -788,6 +779,15 @@
         throwTypeError(&state, throwScope);
         return Nullopt;
     }
+    JSValue requiredEnumerationValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "requiredEnumerationValue"));
+    TestObj::EnumType requiredEnumerationValue;
+    if (!requiredEnumerationValueValue.isUndefined()) {
+        requiredEnumerationValue = convert<TestObj::EnumType>(state, requiredEnumerationValueValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    } else {
+        throwTypeError(&state, throwScope);
+        return Nullopt;
+    }
     return TestObj::DictionaryThatShouldNotTolerateNull { WTFMove(requiredEnumerationValue), WTFMove(booleanWithoutDefault), *nonNullableNode, requiredDictionaryMember.value() };
 }
 
@@ -805,6 +805,12 @@
         throwTypeError(&state, throwScope);
         return Nullopt;
     }
+    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
+    Converter<bool>::OptionalValue booleanWithoutDefault;
+    if (!booleanWithoutDefaultValue.isUndefined()) {
+        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
     JSValue enumerationValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumerationValue"));
     Converter<TestObj::EnumType>::OptionalValue enumerationValue;
     if (!enumerationValueValue.isUndefined()) {
@@ -811,12 +817,6 @@
         enumerationValue = convert<TestObj::EnumType>(state, enumerationValueValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
-    Converter<bool>::OptionalValue booleanWithoutDefault;
-    if (!booleanWithoutDefaultValue.isUndefined()) {
-        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
-        RETURN_IF_EXCEPTION(throwScope, Nullopt);
-    }
     return TestObj::DictionaryThatShouldTolerateNull { WTFMove(enumerationValue), WTFMove(booleanWithoutDefault) };
 }
 
@@ -834,6 +834,12 @@
         throwTypeError(&state, throwScope);
         return Nullopt;
     }
+    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
+    Converter<bool>::OptionalValue booleanWithoutDefault;
+    if (!booleanWithoutDefaultValue.isUndefined()) {
+        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
     JSValue enumerationValueValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "enumerationValue"));
     Converter<TestObj::EnumType>::OptionalValue enumerationValue;
     if (!enumerationValueValue.isUndefined()) {
@@ -840,15 +846,79 @@
         enumerationValue = convert<TestObj::EnumType>(state, enumerationValueValue);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    JSValue booleanWithoutDefaultValue = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "booleanWithoutDefault"));
-    Converter<bool>::OptionalValue booleanWithoutDefault;
-    if (!booleanWithoutDefaultValue.isUndefined()) {
-        booleanWithoutDefault = convert<bool>(state, booleanWithoutDefaultValue);
+    return AlternateDictionaryName { WTFMove(enumerationValue), WTFMove(booleanWithoutDefault) };
+}
+
+template<> Optional<TestObj::ParentDictionary> convertDictionary<TestObj::ParentDictionary>(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 Nullopt;
+    }
+    if (UNLIKELY(object && object->type() == RegExpObjectType)) {
+        throwTypeError(&state, throwScope);
+        return Nullopt;
+    }
+    JSValue parentMember1Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "parentMember1"));
+    Converter<bool>::OptionalValue parentMember1;
+    if (!parentMember1Value.isUndefined()) {
+        parentMember1 = convert<bool>(state, parentMember1Value);
         RETURN_IF_EXCEPTION(throwScope, Nullopt);
     }
-    return AlternateDictionaryName { WTFMove(enumerationValue), WTFMove(booleanWithoutDefault) };
+    JSValue parentMember2Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "parentMember2"));
+    Converter<bool>::OptionalValue parentMember2;
+    if (!parentMember2Value.isUndefined()) {
+        parentMember2 = convert<bool>(state, parentMember2Value);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    return TestObj::ParentDictionary { WTFMove(parentMember2), WTFMove(parentMember1) };
 }
 
+template<> Optional<TestObj::ChildDictionary> convertDictionary<TestObj::ChildDictionary>(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 Nullopt;
+    }
+    if (UNLIKELY(object && object->type() == RegExpObjectType)) {
+        throwTypeError(&state, throwScope);
+        return Nullopt;
+    }
+    JSValue parentMember1Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "parentMember1"));
+    Converter<bool>::OptionalValue parentMember1;
+    if (!parentMember1Value.isUndefined()) {
+        parentMember1 = convert<bool>(state, parentMember1Value);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    JSValue parentMember2Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "parentMember2"));
+    Converter<bool>::OptionalValue parentMember2;
+    if (!parentMember2Value.isUndefined()) {
+        parentMember2 = convert<bool>(state, parentMember2Value);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    JSValue childMember1Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "childMember1"));
+    Converter<bool>::OptionalValue childMember1;
+    if (!childMember1Value.isUndefined()) {
+        childMember1 = convert<bool>(state, childMember1Value);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    JSValue childMember2Value = isNullOrUndefined ? jsUndefined() : object->get(&state, Identifier::fromString(&state, "childMember2"));
+    Converter<bool>::OptionalValue childMember2;
+    if (!childMember2Value.isUndefined()) {
+        childMember2 = convert<bool>(state, childMember2Value);
+        RETURN_IF_EXCEPTION(throwScope, Nullopt);
+    }
+    return TestObj::ChildDictionary { WTFMove(parentMember2), WTFMove(parentMember1), WTFMove(childMember2), WTFMove(childMember1) };
+}
+
 // Functions
 
 #if ENABLE(TEST_FEATURE)

Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (206775 => 206776)


--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-10-04 18:51:44 UTC (rev 206776)
@@ -474,3 +474,14 @@
     TestEnumType enumerationValue;
     boolean booleanWithoutDefault;
 };
+
+dictionary ParentDictionary {
+    boolean parentMember2;
+    boolean parentMember1;
+};
+
+dictionary ChildDictionary : ParentDictionary {
+    boolean childMember2;
+    boolean childMember1;
+};
+

Modified: trunk/Source/WebCore/dom/EventTarget.idl (206775 => 206776)


--- trunk/Source/WebCore/dom/EventTarget.idl	2016-10-04 18:45:20 UTC (rev 206775)
+++ trunk/Source/WebCore/dom/EventTarget.idl	2016-10-04 18:51:44 UTC (rev 206776)
@@ -42,8 +42,7 @@
     boolean capture = false;
 };
 
-dictionary AddEventListenerOptions {
-    boolean capture = false;
+dictionary AddEventListenerOptions : EventListenerOptions {
     boolean passive = false;
     boolean _once_ = false;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to