<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207575] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207575">207575</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-10-19 16:31:14 -0700 (Wed, 19 Oct 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add support for sequences and dictionaries in unions
https://bugs.webkit.org/show_bug.cgi?id=163695
Reviewed by Chris Dumez.
Source/WebCore:
Tests:
- Updated js/dom/webidl-type-mapping.html
* bindings/generic/IDLTypes.h:
Add additional helper predicates and fix formatting.
* bindings/js/JSDOMBinding.h:
Export hasIteratorMethod for use in testing.
* bindings/js/JSDOMConvert.h:
- Change return type of Converter<IDLDictionary<T>> to T, from Optional<T>.
- Add support for unions conversion step 12 (parts 1-3).
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDefaultValue):
Support complex default value computations for unions using the convert infrastructure.
(GenerateParametersCheck):
(GenerateConstructorDefinition):
Remove incorrect .value() calls now that Converter<IDLDictionary<T>> returns T.
* bindings/scripts/test/JS/JSTestEventConstructor.cpp:
* bindings/scripts/test/JS/JSTestObj.cpp:
Update bindings test results.
* testing/TypeConversions.h:
(WebCore::TypeConversions::setTypeConversionsDictionary):
(WebCore::TypeConversions::typeConversionsDictionaryLongValue):
(WebCore::TypeConversions::typeConversionsDictionaryStringValue):
(WebCore::TypeConversions::typeConversionsDictionarySequenceValue):
(WebCore::TypeConversions::typeConversionsDictionaryUnionType):
* testing/TypeConversions.idl:
Add some complex types to allow testing IDL conversions from tests.
LayoutTests:
* js/dom/webidl-type-mapping-expected.txt:
* js/dom/webidl-type-mapping.html:
Add tests for more complex conversions.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomwebidltypemappingexpectedtxt">trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomwebidltypemappinghtml">trunk/LayoutTests/js/dom/webidl-type-mapping.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsgenericIDLTypesh">trunk/Source/WebCore/bindings/generic/IDLTypes.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingh">trunk/Source/WebCore/bindings/js/JSDOMBinding.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMConverth">trunk/Source/WebCore/bindings/js/JSDOMConvert.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestEventConstructorcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingTypeConversionsh">trunk/Source/WebCore/testing/TypeConversions.h</a></li>
<li><a href="#trunkSourceWebCoretestingTypeConversionsidl">trunk/Source/WebCore/testing/TypeConversions.idl</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/ChangeLog        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-10-19 Sam Weinig <sam@webkit.org>
+
+ Add support for sequences and dictionaries in unions
+ https://bugs.webkit.org/show_bug.cgi?id=163695
+
+ Reviewed by Chris Dumez.
+
+ * js/dom/webidl-type-mapping-expected.txt:
+ * js/dom/webidl-type-mapping.html:
+ Add tests for more complex conversions.
+
</ins><span class="cx"> 2016-10-19 Ryan Haddad <ryanhaddad@apple.com>
</span><span class="cx">
</span><span class="cx"> Marking platform/mac-wk2/plugins/muted-state.html as failing.
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomwebidltypemappingexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1059,6 +1059,24 @@
</span><span class="cx"> converter.testString = undefined
</span><span class="cx"> PASS converter.testUSVString is "undefined"
</span><span class="cx"> PASS converter.testString is "undefined"
</span><ins>+converter.setTypeConversionsDictionary({ longValue: 1 })
+PASS converter.typeConversionsDictionaryLongValue is 1
+converter.setTypeConversionsDictionary({ stringValue: 'hello' })
+PASS converter.typeConversionsDictionaryStringValue is 'hello'
+converter.setTypeConversionsDictionary({ sequenceValue: ['hi', 'there'] })
+PASS converter.typeConversionsDictionarySequenceValue is ['hi', 'there']
+converter.setTypeConversionsDictionary({ unionValue: document })
+PASS converter.typeConversionsDictionaryUnionType is 'node'
+converter.setTypeConversionsDictionary({ unionValue: ['a', 'sequence'] })
+PASS converter.typeConversionsDictionaryUnionType is 'sequence'
+converter.setTypeConversionsDictionary({ unionValue: { longValue: 1 } })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ unionValue: null })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ unionValue: undefined })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx">
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomwebidltypemappinghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/webidl-type-mapping.html (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -586,5 +586,25 @@
</span><span class="cx"> shouldBeEqualToString("converter.testString", value);
</span><span class="cx"> });
</span><span class="cx">
</span><ins>+evalAndLog("converter.setTypeConversionsDictionary({ longValue: 1 })");
+shouldBe("converter.typeConversionsDictionaryLongValue", "1");
+evalAndLog("converter.setTypeConversionsDictionary({ stringValue: 'hello' })");
+shouldBe("converter.typeConversionsDictionaryStringValue", "'hello'");
+evalAndLog("converter.setTypeConversionsDictionary({ sequenceValue: ['hi', 'there'] })");
+shouldBe("converter.typeConversionsDictionarySequenceValue", "['hi', 'there']");
+
+evalAndLog("converter.setTypeConversionsDictionary({ unionValue: document })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'node'");
+evalAndLog("converter.setTypeConversionsDictionary({ unionValue: ['a', 'sequence'] })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'sequence'");
+evalAndLog("converter.setTypeConversionsDictionary({ unionValue: { longValue: 1 } })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'dictionary'");
+evalAndLog("converter.setTypeConversionsDictionary({ unionValue: null })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'dictionary'");
+evalAndLog("converter.setTypeConversionsDictionary({ unionValue: undefined })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'dictionary'");
+evalAndLog("converter.setTypeConversionsDictionary({ })");
+shouldBe("converter.typeConversionsDictionaryUnionType", "'dictionary'");
+
</ins><span class="cx"> </script>
</span><span class="cx"> <script src="../../resources/js-test-post.js"></script>
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/ChangeLog        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-10-19 Sam Weinig <sam@webkit.org>
+
+ Add support for sequences and dictionaries in unions
+ https://bugs.webkit.org/show_bug.cgi?id=163695
+
+ Reviewed by Chris Dumez.
+
+ Tests:
+ - Updated js/dom/webidl-type-mapping.html
+
+ * bindings/generic/IDLTypes.h:
+ Add additional helper predicates and fix formatting.
+
+ * bindings/js/JSDOMBinding.h:
+ Export hasIteratorMethod for use in testing.
+
+ * bindings/js/JSDOMConvert.h:
+ - Change return type of Converter<IDLDictionary<T>> to T, from Optional<T>.
+ - Add support for unions conversion step 12 (parts 1-3).
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateDefaultValue):
+ Support complex default value computations for unions using the convert infrastructure.
+
+ (GenerateParametersCheck):
+ (GenerateConstructorDefinition):
+ Remove incorrect .value() calls now that Converter<IDLDictionary<T>> returns T.
+
+ * bindings/scripts/test/JS/JSTestEventConstructor.cpp:
+ * bindings/scripts/test/JS/JSTestObj.cpp:
+ Update bindings test results.
+
+ * testing/TypeConversions.h:
+ (WebCore::TypeConversions::setTypeConversionsDictionary):
+ (WebCore::TypeConversions::typeConversionsDictionaryLongValue):
+ (WebCore::TypeConversions::typeConversionsDictionaryStringValue):
+ (WebCore::TypeConversions::typeConversionsDictionarySequenceValue):
+ (WebCore::TypeConversions::typeConversionsDictionaryUnionType):
+ * testing/TypeConversions.idl:
+ Add some complex types to allow testing IDL conversions from tests.
+
</ins><span class="cx"> 2016-10-19 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> Annotate more DOM and HTML IDLs with CEReactions
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsgenericIDLTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/generic/IDLTypes.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -123,16 +123,25 @@
</span><span class="cx">
</span><span class="cx"> // Helper predicates
</span><span class="cx">
</span><del>-template <typename T>
</del><ins>+template<typename T>
</ins><span class="cx"> struct IsIDLInterface : public std::integral_constant<bool, WTF::IsTemplate<T, IDLInterface>::value> { };
</span><span class="cx">
</span><del>-template <typename T>
</del><ins>+template<typename T>
</ins><span class="cx"> struct IsIDLDictionary : public std::integral_constant<bool, WTF::IsTemplate<T, IDLDictionary>::value> { };
</span><span class="cx">
</span><del>-template <typename T>
</del><ins>+template<typename T>
+struct IsIDLEnumeration : public std::integral_constant<bool, WTF::IsTemplate<T, IDLEnumeration>::value> { };
+
+template<typename T>
+struct IsIDLSequence : public std::integral_constant<bool, WTF::IsTemplate<T, IDLSequence>::value> { };
+
+template<typename T>
+struct IsIDLFrozenArray : public std::integral_constant<bool, WTF::IsTemplate<T, IDLFrozenArray>::value> { };
+
+template<typename T>
</ins><span class="cx"> struct IsIDLNumber : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLNumber, T>::value> { };
</span><span class="cx">
</span><del>-template <typename T>
</del><ins>+template<typename T>
</ins><span class="cx"> struct IsIDLInteger : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLInteger, T>::value> { };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -301,7 +301,7 @@
</span><span class="cx"> RefPtr<JSC::Float64Array> toFloat64Array(JSC::JSValue);
</span><span class="cx">
</span><span class="cx"> template<typename T, typename JSType> Vector<Ref<T>> toRefNativeArray(JSC::ExecState&, JSC::JSValue);
</span><del>-bool hasIteratorMethod(JSC::ExecState&, JSC::JSValue);
</del><ins>+WEBCORE_EXPORT bool hasIteratorMethod(JSC::ExecState&, JSC::JSValue);
</ins><span class="cx">
</span><span class="cx"> bool shouldAllowAccessToNode(JSC::ExecState*, Node*);
</span><span class="cx"> bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMConverth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -408,7 +408,7 @@
</span><span class="cx"> // MARK: Dictionary type
</span><span class="cx">
</span><span class="cx"> template<typename T> struct Converter<IDLDictionary<T>> : DefaultConverter<IDLDictionary<T>> {
</span><del>- using ReturnType = Optional<T>;
</del><ins>+ using ReturnType = T;
</ins><span class="cx">
</span><span class="cx"> static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
</span><span class="cx"> {
</span><span class="lines">@@ -476,18 +476,34 @@
</span><span class="cx"> using TypeList = typename Type::TypeList;
</span><span class="cx"> using ReturnType = typename Type::ImplementationType;
</span><span class="cx">
</span><del>- using DictionaryTypeList = brigand::find<TypeList, IsIDLDictionary<brigand::_1>>;
- using DictionaryType = ConditionalFront<DictionaryTypeList, brigand::size<DictionaryTypeList>::value != 0>;
- static_assert(brigand::size<DictionaryTypeList>::value == 0 || brigand::size<DictionaryTypeList>::value == 1, "There can be 0 or 1 dictionary types in an IDLUnion.");
</del><ins>+ using NumericTypeList = brigand::filter<TypeList, IsIDLNumber<brigand::_1>>;
+ static constexpr size_t numberOfNumericTypes = brigand::size<NumericTypeList>::value;
+ static_assert(numberOfNumericTypes == 0 || numberOfNumericTypes == 1, "There can be 0 or 1 numeric types in an IDLUnion.");
+ using NumericType = ConditionalFront<NumericTypeList, numberOfNumericTypes != 0>;
</ins><span class="cx">
</span><del>- using NumericTypeList = brigand::find<TypeList, IsIDLNumber<brigand::_1>>;
- using NumericType = ConditionalFront<NumericTypeList, brigand::size<NumericTypeList>::value != 0>;
- static_assert(brigand::size<NumericTypeList>::value == 0 || brigand::size<NumericTypeList>::value == 1, "There can be 0 or 1 numeric types in an IDLUnion.");
</del><ins>+ // FIXME: This should also check for IDLEnumeration<T>.
+ using StringTypeList = brigand::filter<TypeList, std::is_base_of<IDLString, brigand::_1>>;
+ static constexpr size_t numberOfStringTypes = brigand::size<StringTypeList>::value;
+ static_assert(numberOfStringTypes == 0 || numberOfStringTypes == 1, "There can be 0 or 1 string types in an IDLUnion.");
+ using StringType = ConditionalFront<StringTypeList, numberOfStringTypes != 0>;
</ins><span class="cx">
</span><del>- using StringTypeList = brigand::find<TypeList, std::is_base_of<IDLString, brigand::_1>>;
- using StringType = ConditionalFront<StringTypeList, brigand::size<StringTypeList>::value != 0>;
- static_assert(brigand::size<StringTypeList>::value == 0 || brigand::size<StringTypeList>::value == 1, "There can be 0 or 1 string types in an IDLUnion.");
</del><ins>+ using SequenceTypeList = brigand::filter<TypeList, IsIDLSequence<brigand::_1>>;
+ static constexpr size_t numberOfSequenceTypes = brigand::size<SequenceTypeList>::value;
+ static_assert(numberOfSequenceTypes == 0 || numberOfSequenceTypes == 1, "There can be 0 or 1 sequence types in an IDLUnion.");
+ using SequenceType = ConditionalFront<SequenceTypeList, numberOfSequenceTypes != 0>;
</ins><span class="cx">
</span><ins>+ using FrozenArrayTypeList = brigand::filter<TypeList, IsIDLFrozenArray<brigand::_1>>;
+ static constexpr size_t numberOfFrozenArrayTypes = brigand::size<FrozenArrayTypeList>::value;
+ static_assert(numberOfFrozenArrayTypes == 0 || numberOfFrozenArrayTypes == 1, "There can be 0 or 1 FrozenArray types in an IDLUnion.");
+ using FrozenArrayType = ConditionalFront<FrozenArrayTypeList, numberOfFrozenArrayTypes != 0>;
+
+ using DictionaryTypeList = brigand::filter<TypeList, IsIDLDictionary<brigand::_1>>;
+ static constexpr size_t numberOfDictionaryTypes = brigand::size<DictionaryTypeList>::value;
+ static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, "There can be 0 or 1 dictionary types in an IDLUnion.");
+ using DictionaryType = ConditionalFront<DictionaryTypeList, numberOfDictionaryTypes != 0>;
+
+ static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes) > 0;
+
</ins><span class="cx"> using InterfaceTypeList = brigand::filter<TypeList, IsIDLInterface<brigand::_1>>;
</span><span class="cx">
</span><span class="cx"> static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
</span><span class="lines">@@ -505,7 +521,7 @@
</span><span class="cx"> // NOTE: Union is expected to be pre-flattented.
</span><span class="cx">
</span><span class="cx"> // 3. If V is null or undefined, and types includes a dictionary type, then return the result of converting V to that dictionary type.
</span><del>- constexpr bool hasDictionaryType = brigand::size<DictionaryTypeList>::value != 0;
</del><ins>+ constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
</ins><span class="cx"> if (hasDictionaryType) {
</span><span class="cx"> if (value.isUndefinedOrNull())
</span><span class="cx"> return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(state, value).value());
</span><span class="lines">@@ -535,8 +551,57 @@
</span><span class="cx"> return WTFMove(returnValue.value());
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // FIXME: Add support for steps 5 - 12.
-
</del><ins>+ // FIXME: Add support for steps 5 - 11.
+
+ // 12. If V is any kind of object except for a native RegExp object, then:
+ if (hasObjectType) {
+ if (value.isCell()) {
+ JSC::JSCell* cell = value.asCell();
+ if (cell->isObject() && cell->type() != JSC::RegExpObjectType) {
+ // FIXME: We should be able to optimize the following code by making use
+ // of the fact that we have proved that the value is an object.
+
+ // 1. If types includes a sequence type, then:
+ // 1. Let method be the result of GetMethod(V, @@iterator).
+ // 2. ReturnIfAbrupt(method).
+ // 3. If method is not undefined, return the result of creating a
+ // sequence of that type from V and method.
+ constexpr bool hasSequenceType = numberOfSequenceTypes != 0;
+ if (hasSequenceType) {
+ bool hasIterator = hasIteratorMethod(state, value);
+ RETURN_IF_EXCEPTION(scope, ReturnType());
+ if (hasIterator)
+ return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, SequenceType, hasSequenceType>::convert(state, value).value());
+ }
+
+ // 2. If types includes a frozen array type, then:
+ // 1. Let method be the result of GetMethod(V, @@iterator).
+ // 2. ReturnIfAbrupt(method).
+ // 3. If method is not undefined, return the result of creating a
+ // frozen array of that type from V and method.
+ constexpr bool hasFrozenArrayType = numberOfFrozenArrayTypes != 0;
+ if (hasFrozenArrayType) {
+ bool hasIterator = hasIteratorMethod(state, value);
+ RETURN_IF_EXCEPTION(scope, ReturnType());
+ if (hasIterator)
+ return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, FrozenArrayType, hasFrozenArrayType>::convert(state, value).value());
+ }
+
+ // 3. If types includes a dictionary type, then return the result of
+ // converting V to that dictionary type.
+ if (hasDictionaryType)
+ return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(state, value).value());
+
+ // 4. If types includes a record type, then return the result of converting V to that record type.
+ // (FIXME: Add support for record types and step 12.4)
+ // 5. If types includes a callback interface type, then return the result of converting V to that interface type.
+ // (FIXME: Add support for callback interface type and step 12.5)
+ // 6. If types includes object, then return the IDL value that is a reference to the object V.
+ // (FIXME: Add support for object and step 12.6)
+ }
+ }
+ }
+
</ins><span class="cx"> // 13. If V is a Boolean value, then:
</span><span class="cx"> // 1. If types includes a boolean, then return the result of converting V to boolean.
</span><span class="cx"> constexpr bool hasBooleanType = brigand::any<TypeList, std::is_same<IDLBoolean, brigand::_1>>::value;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1008,7 +1008,12 @@
</span><span class="cx"> return $className . "::" . $enumerationValueName;
</span><span class="cx"> }
</span><span class="cx"> if ($defaultValue eq "null") {
</span><del>- return "Nullopt" if $signature->idlType->isUnion;
</del><ins>+ if ($signature->idlType->isUnion) {
+ return "Nullopt" if $signature->idlType->isNullable;
+
+ my $IDLType = GetIDLType($interface, $signature->idlType);
+ return "convert<${IDLType}>(state, jsNull());";
+ }
</ins><span class="cx"> return "jsNull()" if $signature->type eq "any";
</span><span class="cx"> return "nullptr" if $codeGenerator->IsWrapperType($signature->type) || $codeGenerator->IsTypedArrayType($signature->type);
</span><span class="cx"> return "String()" if $codeGenerator->IsStringType($signature->type);
</span><span class="lines">@@ -4364,7 +4369,7 @@
</span><span class="cx"> if ($codeGenerator->IsTypedArrayType($type) and $parameter->type ne "ArrayBuffer") {
</span><span class="cx"> $value = $shouldPassByReference ? "$name.releaseNonNull()" : "WTFMove($name)";
</span><span class="cx"> } elsif ($codeGenerator->IsDictionaryType($type)) {
</span><del>- $value = "${name}.value()";
</del><ins>+ $value = "${name}";
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -5763,7 +5768,7 @@
</span><span class="cx"> if (ShouldPassWrapperByReference($parameter, $interface)) {
</span><span class="cx"> push(@constructorArgList, "*" . $parameter->name);
</span><span class="cx"> } elsif ($codeGenerator->IsDictionaryType($parameter->type)) {
</span><del>- push(@constructorArgList, $parameter->name . ".value()");
</del><ins>+ push(@constructorArgList, $parameter->name);
</ins><span class="cx"> } else {
</span><span class="cx"> push(@constructorArgList, "WTFMove(" . $parameter->name . ")");
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestEventConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx"> RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><span class="cx"> auto eventInitDict = convert<IDLDictionary<TestEventConstructor::Init>>(*state, state->argument(1));
</span><span class="cx"> RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>- auto object = TestEventConstructor::create(WTFMove(type), eventInitDict.value());
</del><ins>+ auto object = TestEventConstructor::create(WTFMove(type), eventInitDict);
</ins><span class="cx"> return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -7710,7 +7710,7 @@
</span><span class="cx"> return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
</span><span class="cx"> auto init = convert<IDLDictionary<TestObj::Dictionary>>(*state, state->uncheckedArgument(0));
</span><span class="cx"> RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>- impl.attachShadowRoot(init.value());
</del><ins>+ impl.attachShadowRoot(init);
</ins><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -7730,7 +7730,7 @@
</span><span class="cx"> return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
</span><span class="cx"> auto dict = convert<IDLDictionary<DictionaryImplName>>(*state, state->uncheckedArgument(0));
</span><span class="cx"> RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>- impl.operationWithExternalDictionaryParameter(dict.value());
</del><ins>+ impl.operationWithExternalDictionaryParameter(dict);
</ins><span class="cx"> return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/testing/TypeConversions.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -26,8 +26,11 @@
</span><span class="cx"> #ifndef TypeConversions_h
</span><span class="cx"> #define TypeConversions_h
</span><span class="cx">
</span><ins>+#include "Node.h"
</ins><span class="cx"> #include <wtf/FastMalloc.h>
</span><span class="cx"> #include <wtf/RefCounted.h>
</span><ins>+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
</ins><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -36,6 +39,24 @@
</span><span class="cx"> public:
</span><span class="cx"> static Ref<TypeConversions> create() { return adoptRef(*new TypeConversions()); }
</span><span class="cx">
</span><ins>+ enum class UnionType {
+ Node,
+ Sequence,
+ Dictionary
+ };
+
+ struct OtherDictionary {
+ int longValue;
+ String stringValue;
+ };
+
+ struct Dictionary {
+ int longValue;
+ String stringValue;
+ Vector<String> sequenceValue;
+ Variant<RefPtr<Node>, Vector<String>, OtherDictionary> unionValue;
+ };
+
</ins><span class="cx"> long testLong() { return m_long; }
</span><span class="cx"> void setTestLong(long value) { m_long = value; }
</span><span class="cx"> long testEnforceRangeLong() { return m_long; }
</span><span class="lines">@@ -77,21 +98,46 @@
</span><span class="cx"> const String& testUSVString() const { return m_usvstring; }
</span><span class="cx"> void setTestUSVString(const String& usvstring) { m_usvstring = usvstring; }
</span><span class="cx">
</span><ins>+ void setTypeConversionsDictionary(Dictionary& dictionary)
+ {
+ m_typeConversionsDictionaryLongValue = dictionary.longValue;
+ m_typeConversionsDictionaryStringValue = dictionary.stringValue;
+ m_typeConversionsDictionarySequenceValue = dictionary.sequenceValue;
+ m_typeConversionsDictionaryUnionValue = dictionary.unionValue;
+ }
+
+ int typeConversionsDictionaryLongValue() { return m_typeConversionsDictionaryLongValue; }
+ String typeConversionsDictionaryStringValue() { return m_typeConversionsDictionaryStringValue; }
+ Vector<String> typeConversionsDictionarySequenceValue() { return m_typeConversionsDictionarySequenceValue; }
+ UnionType typeConversionsDictionaryUnionType()
+ {
+ return WTF::visit(WTF::makeVisitor(
+ [](const RefPtr<Node>&) -> UnionType { return UnionType::Node; },
+ [](const Vector<String>&) -> UnionType { return UnionType::Sequence; },
+ [](const OtherDictionary&) -> UnionType { return UnionType::Dictionary; }
+ ), m_typeConversionsDictionaryUnionValue);
+ }
+
</ins><span class="cx"> private:
</span><span class="cx"> TypeConversions()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- long m_long;
- unsigned long m_unsignedLong;
- long long m_longLong;
- unsigned long long m_unsignedLongLong;
- int8_t m_byte;
- uint8_t m_octet;
- int16_t m_short;
- uint16_t m_UnsignedShort;
</del><ins>+ long m_long { 0 };
+ unsigned long m_unsignedLong { 0 };
+ long long m_longLong { 0 };
+ unsigned long long m_unsignedLongLong { 0 };
+ int8_t m_byte { 0 };
+ uint8_t m_octet { 0 };
+ int16_t m_short { 0 };
+ uint16_t m_UnsignedShort { 0 };
</ins><span class="cx"> String m_string;
</span><span class="cx"> String m_usvstring;
</span><ins>+
+ int m_typeConversionsDictionaryLongValue { 0 };
+ String m_typeConversionsDictionaryStringValue;
+ Vector<String> m_typeConversionsDictionarySequenceValue;
+ Variant<RefPtr<Node>, Vector<String>, OtherDictionary> m_typeConversionsDictionaryUnionValue;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.idl (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.idl        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/testing/TypeConversions.idl        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -23,6 +23,8 @@
</span><span class="cx"> * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><ins>+enum UnionType { "node", "sequence", "dictionary" };
+
</ins><span class="cx"> [
</span><span class="cx"> NoInterfaceObject,
</span><span class="cx"> ImplementationLacksVTable,
</span><span class="lines">@@ -50,4 +52,22 @@
</span><span class="cx">
</span><span class="cx"> attribute DOMString testString;
</span><span class="cx"> attribute USVString testUSVString;
</span><ins>+
+ void setTypeConversionsDictionary(TypeConversionsDictionary d);
+ readonly attribute long typeConversionsDictionaryLongValue;
+ readonly attribute DOMString typeConversionsDictionaryStringValue;
+ readonly attribute sequence<DOMString> typeConversionsDictionarySequenceValue;
+ readonly attribute UnionType typeConversionsDictionaryUnionType;
</ins><span class="cx"> };
</span><ins>+
+dictionary TypeConversionsOtherDictionary {
+ long longValue = 0;
+ DOMString stringValue = "";
+};
+
+dictionary TypeConversionsDictionary {
+ long longValue = 0;
+ DOMString stringValue = "";
+ sequence<DOMString> sequenceValue = [];
+ (Node or sequence<DOMString> or TypeConversionsOtherDictionary) unionValue = null;
+};
</ins></span></pre>
</div>
</div>
</body>
</html>