Commit 39649c68 authored by bashi@chromium.org's avatar bashi@chromium.org

IDL: Support union type arrays and sequences for method arguments

toImplArray() template can convert arrays (or sequences) of T to
Vector<T> when T has NativeValueTraits. Generate them for union type
containers so that we can use (A or B)[] (or sequence<(A or B)>)
in method arguments.

Note that we can't use union type arrays and sequences for
return values yet. Follow-up CLs will support return values.

BUG=240176

Review URL: https://codereview.chromium.org/700733003

git-svn-id: svn://svn.chromium.org/blink/trunk@185096 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 2d68b9a1
......@@ -22,6 +22,22 @@ PASS unionTypesTest.doubleOrStringArg([]) is "string is passed: "
PASS typeof unionTypesTest.doubleOrStringArg(new Date) is "string"
PASS unionTypesTest.doubleOrStringArg() threw exception TypeError: Failed to execute 'doubleOrStringArg' on 'UnionTypesTest': 1 argument required, but only 0 present..
PASS unionTypesTest.doubleOrStringArrayArg([]) is ""
PASS unionTypesTest.doubleOrStringArrayArg([3.14, "foo"]) is "double: 3.14, string: foo"
PASS unionTypesTest.doubleOrStringArrayArg([1, "foo", "bar", 2]) is "double: 1, string: foo, string: bar, double: 2"
PASS unionTypesTest.doubleOrStringArrayArg([null, undefined, {}, []]) is "string: null, string: undefined, string: [object Object], string: "
PASS unionTypesTest.doubleOrStringArrayArg(null) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
PASS unionTypesTest.doubleOrStringArrayArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
PASS unionTypesTest.doubleOrStringArrayArg({}) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
PASS unionTypesTest.doubleOrStringSequenceArg([]) is ""
PASS unionTypesTest.doubleOrStringSequenceArg([3.14, "foo"]) is "double: 3.14, string: foo"
PASS unionTypesTest.doubleOrStringSequenceArg([1, "foo", "bar", 2]) is "double: 1, string: foo, string: bar, double: 2"
PASS unionTypesTest.doubleOrStringSequenceArg([null, undefined, {}, []]) is "string: null, string: undefined, string: [object Object], string: "
PASS unionTypesTest.doubleOrStringSequenceArg(null) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
PASS unionTypesTest.doubleOrStringSequenceArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
PASS unionTypesTest.doubleOrStringSequenceArg({}) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties..
Tests for method arguments with defaults
PASS unionTypesTest.doubleOrStringDefaultDoubleArg() is "double is passed: 3.14"
PASS unionTypesTest.doubleOrStringDefaultDoubleArg(undefined) is "double is passed: 3.14"
......
......@@ -38,6 +38,24 @@ if (window.internals) {
shouldThrow('unionTypesTest.doubleOrStringArg()');
debug('');
shouldBeEqualToString('unionTypesTest.doubleOrStringArrayArg([])', '');
shouldBeEqualToString('unionTypesTest.doubleOrStringArrayArg([3.14, "foo"])', 'double: 3.14, string: foo');
shouldBeEqualToString('unionTypesTest.doubleOrStringArrayArg([1, "foo", "bar", 2])', 'double: 1, string: foo, string: bar, double: 2');
shouldBeEqualToString('unionTypesTest.doubleOrStringArrayArg([null, undefined, {}, []])', 'string: null, string: undefined, string: [object Object], string: ');
shouldThrow('unionTypesTest.doubleOrStringArrayArg(null)');
shouldThrow('unionTypesTest.doubleOrStringArrayArg(undefined)');
shouldThrow('unionTypesTest.doubleOrStringArrayArg({})');
debug('');
shouldBeEqualToString('unionTypesTest.doubleOrStringSequenceArg([])', '');
shouldBeEqualToString('unionTypesTest.doubleOrStringSequenceArg([3.14, "foo"])', 'double: 3.14, string: foo');
shouldBeEqualToString('unionTypesTest.doubleOrStringSequenceArg([1, "foo", "bar", 2])', 'double: 1, string: foo, string: bar, double: 2');
shouldBeEqualToString('unionTypesTest.doubleOrStringSequenceArg([null, undefined, {}, []])', 'string: null, string: undefined, string: [object Object], string: ');
shouldThrow('unionTypesTest.doubleOrStringSequenceArg(null)');
shouldThrow('unionTypesTest.doubleOrStringSequenceArg(undefined)');
shouldThrow('unionTypesTest.doubleOrStringSequenceArg({})');
debug('');
debug('Tests for method arguments with defaults');
shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultDoubleArg()', 'double is passed: 3.14');
shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultDoubleArg(undefined)', 'double is passed: 3.14');
......
......@@ -151,5 +151,12 @@ v8::Handle<v8::Value> toV8({{container.cpp_class}}& impl, v8::Handle<v8::Object>
return v8::Handle<v8::Value>();
}
{{container.cpp_class}} NativeValueTraits<{{container.cpp_class}}>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
{{container.cpp_class}} impl;
V8{{container.cpp_class}}::toImpl(isolate, value, impl, exceptionState);
return impl;
}
{% endfor %}
} // namespace blink
......@@ -63,6 +63,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, {{container.cpp_c
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<{{container.cpp_class}}> {
static {{container.cpp_class}} nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
{% endfor %}
{% for cpp_type in nullable_cpp_types %}
class V8{{cpp_type}}OrNull final {
......
......@@ -112,6 +112,13 @@ v8::Handle<v8::Value> toV8(BooleanOrStringOrUnrestrictedDouble& impl, v8::Handle
return v8::Handle<v8::Value>();
}
BooleanOrStringOrUnrestrictedDouble NativeValueTraits<BooleanOrStringOrUnrestrictedDouble>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
BooleanOrStringOrUnrestrictedDouble impl;
V8BooleanOrStringOrUnrestrictedDouble::toImpl(isolate, value, impl, exceptionState);
return impl;
}
DoubleOrString::DoubleOrString()
: m_type(SpecificTypeNone)
{
......@@ -177,6 +184,13 @@ v8::Handle<v8::Value> toV8(DoubleOrString& impl, v8::Handle<v8::Object> creation
return v8::Handle<v8::Value>();
}
DoubleOrString NativeValueTraits<DoubleOrString>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
DoubleOrString impl;
V8DoubleOrString::toImpl(isolate, value, impl, exceptionState);
return impl;
}
NodeOrNodeList::NodeOrNodeList()
: m_type(SpecificTypeNone)
{
......@@ -249,6 +263,13 @@ v8::Handle<v8::Value> toV8(NodeOrNodeList& impl, v8::Handle<v8::Object> creation
return v8::Handle<v8::Value>();
}
NodeOrNodeList NativeValueTraits<NodeOrNodeList>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
NodeOrNodeList impl;
V8NodeOrNodeList::toImpl(isolate, value, impl, exceptionState);
return impl;
}
StringOrArrayBufferOrArrayBufferView::StringOrArrayBufferOrArrayBufferView()
: m_type(SpecificTypeNone)
{
......@@ -335,6 +356,13 @@ v8::Handle<v8::Value> toV8(StringOrArrayBufferOrArrayBufferView& impl, v8::Handl
return v8::Handle<v8::Value>();
}
StringOrArrayBufferOrArrayBufferView NativeValueTraits<StringOrArrayBufferOrArrayBufferView>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
StringOrArrayBufferOrArrayBufferView impl;
V8StringOrArrayBufferOrArrayBufferView::toImpl(isolate, value, impl, exceptionState);
return impl;
}
StringOrDouble::StringOrDouble()
: m_type(SpecificTypeNone)
{
......@@ -400,6 +428,13 @@ v8::Handle<v8::Value> toV8(StringOrDouble& impl, v8::Handle<v8::Object> creation
return v8::Handle<v8::Value>();
}
StringOrDouble NativeValueTraits<StringOrDouble>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
StringOrDouble impl;
V8StringOrDouble::toImpl(isolate, value, impl, exceptionState);
return impl;
}
TestInterfaceGarbageCollectedOrString::TestInterfaceGarbageCollectedOrString()
: m_type(SpecificTypeNone)
{
......@@ -470,6 +505,13 @@ v8::Handle<v8::Value> toV8(TestInterfaceGarbageCollectedOrString& impl, v8::Hand
return v8::Handle<v8::Value>();
}
TestInterfaceGarbageCollectedOrString NativeValueTraits<TestInterfaceGarbageCollectedOrString>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
TestInterfaceGarbageCollectedOrString impl;
V8TestInterfaceGarbageCollectedOrString::toImpl(isolate, value, impl, exceptionState);
return impl;
}
TestInterfaceOrLong::TestInterfaceOrLong()
: m_type(SpecificTypeNone)
{
......@@ -541,6 +583,13 @@ v8::Handle<v8::Value> toV8(TestInterfaceOrLong& impl, v8::Handle<v8::Object> cre
return v8::Handle<v8::Value>();
}
TestInterfaceOrLong NativeValueTraits<TestInterfaceOrLong>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
TestInterfaceOrLong impl;
V8TestInterfaceOrLong::toImpl(isolate, value, impl, exceptionState);
return impl;
}
TestInterfaceOrTestInterfaceEmpty::TestInterfaceOrTestInterfaceEmpty()
: m_type(SpecificTypeNone)
{
......@@ -607,6 +656,13 @@ v8::Handle<v8::Value> toV8(TestInterfaceOrTestInterfaceEmpty& impl, v8::Handle<v
return v8::Handle<v8::Value>();
}
TestInterfaceOrTestInterfaceEmpty NativeValueTraits<TestInterfaceOrTestInterfaceEmpty>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
TestInterfaceOrTestInterfaceEmpty impl;
V8TestInterfaceOrTestInterfaceEmpty::toImpl(isolate, value, impl, exceptionState);
return impl;
}
TestInterfaceWillBeGarbageCollectedOrTestDictionary::TestInterfaceWillBeGarbageCollectedOrTestDictionary()
: m_type(SpecificTypeNone)
{
......@@ -679,4 +735,11 @@ v8::Handle<v8::Value> toV8(TestInterfaceWillBeGarbageCollectedOrTestDictionary&
return v8::Handle<v8::Value>();
}
TestInterfaceWillBeGarbageCollectedOrTestDictionary NativeValueTraits<TestInterfaceWillBeGarbageCollectedOrTestDictionary>::nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate, ExceptionState& exceptionState)
{
TestInterfaceWillBeGarbageCollectedOrTestDictionary impl;
V8TestInterfaceWillBeGarbageCollectedOrTestDictionary::toImpl(isolate, value, impl, exceptionState);
return impl;
}
} // namespace blink
......@@ -70,6 +70,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, BooleanOrStringOr
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<BooleanOrStringOrUnrestrictedDouble> {
static BooleanOrStringOrUnrestrictedDouble nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class DoubleOrString final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -111,6 +116,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, DoubleOrString& i
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<DoubleOrString> {
static DoubleOrString nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class NodeOrNodeList final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -154,6 +164,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, NodeOrNodeList& i
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<NodeOrNodeList> {
static NodeOrNodeList nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class StringOrArrayBufferOrArrayBufferView final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -201,6 +216,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, StringOrArrayBuff
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<StringOrArrayBufferOrArrayBufferView> {
static StringOrArrayBufferOrArrayBufferView nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class StringOrDouble final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -242,6 +262,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, StringOrDouble& i
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<StringOrDouble> {
static StringOrDouble nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class TestInterfaceGarbageCollectedOrString final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -285,6 +310,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceGarb
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<TestInterfaceGarbageCollectedOrString> {
static TestInterfaceGarbageCollectedOrString nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class TestInterfaceOrLong final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -326,6 +356,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceOrLo
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<TestInterfaceOrLong> {
static TestInterfaceOrLong nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class TestInterfaceOrTestInterfaceEmpty final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -367,6 +402,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceOrTe
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<TestInterfaceOrTestInterfaceEmpty> {
static TestInterfaceOrTestInterfaceEmpty nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class TestInterfaceWillBeGarbageCollectedOrTestDictionary final {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
......@@ -410,6 +450,11 @@ inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceWill
v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<TestInterfaceWillBeGarbageCollectedOrTestDictionary> {
static TestInterfaceWillBeGarbageCollectedOrTestDictionary nativeValue(const v8::Handle<v8::Value>&, v8::Isolate*, ExceptionState&);
};
class V8DoubleOrStringOrNull final {
public:
static void toImpl(v8::Isolate* isolate, v8::Handle<v8::Value> v8Value, DoubleOrString& impl, ExceptionState& exceptionState)
......
......@@ -5,6 +5,8 @@
#include "config.h"
#include "UnionTypesTest.h"
#include "wtf/text/StringBuilder.h"
namespace blink {
void UnionTypesTest::doubleOrStringAttribute(DoubleOrString& doubleOrString)
......@@ -50,4 +52,28 @@ String UnionTypesTest::doubleOrStringArg(DoubleOrString& doubleOrString)
return String();
}
String UnionTypesTest::doubleOrStringArrayArg(Vector<DoubleOrString>& array)
{
if (!array.size())
return "";
StringBuilder builder;
for (DoubleOrString& doubleOrString : array) {
ASSERT(!doubleOrString.isNull());
if (doubleOrString.isDouble())
builder.append("double: " + String::numberToStringECMAScript(doubleOrString.getAsDouble()));
else if (doubleOrString.isString())
builder.append("string: " + doubleOrString.getAsString());
else
ASSERT_NOT_REACHED();
builder.append(", ");
}
return builder.substring(0, builder.length() - 2);
}
String UnionTypesTest::doubleOrStringSequenceArg(Vector<DoubleOrString>& sequence)
{
return doubleOrStringArrayArg(sequence);
}
}
......@@ -23,6 +23,8 @@ public:
void setDoubleOrStringAttribute(const DoubleOrString&);
String doubleOrStringArg(DoubleOrString&);
String doubleOrStringArrayArg(Vector<DoubleOrString>&);
String doubleOrStringSequenceArg(Vector<DoubleOrString>&);
void trace(Visitor*) { }
......
......@@ -12,4 +12,6 @@
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultDoubleArg(optional (double or DOMString) arg = 3.14);
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultStringArg(optional (double or DOMString) arg = "foo");
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultNullArg(optional (double or DOMString)? arg = null);
DOMString doubleOrStringArrayArg((double or DOMString)[] arg);
DOMString doubleOrStringSequenceArg(sequence<(double or DOMString)> arg);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment