Commit 3aa53e44 authored by Jeremy Roman's avatar Jeremy Roman Committed by Commit Bot

bindings: Support using the [] literal as the default value for a union containing a sequence.

Bug: 791121
Change-Id: Ief7110aae72a25201af687e03c82a88821fd7a2b
Reviewed-on: https://chromium-review.googlesource.com/809906Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522095}
parent 6afdb0f6
......@@ -369,6 +369,11 @@ class IdlUnionType(IdlTypeBase):
return self.single_matching_member_type(
lambda member_type: member_type.base_type == 'boolean')
@property
def sequence_member_type(self):
return self.single_matching_member_type(
lambda member_type: member_type.is_sequence_type)
@property
def as_union_type(self):
# Note: Use this to "look through" a possible IdlNullableType wrapper.
......
......@@ -1034,6 +1034,8 @@ def union_literal_cpp_value(idl_type, idl_literal):
member_type = idl_type.numeric_member_type
elif idl_literal.idl_type == 'boolean':
member_type = idl_type.boolean_member_type
elif idl_literal.idl_type == 'sequence':
member_type = idl_type.sequence_member_type
else:
raise ValueError('Unsupported literal type: ' + idl_literal.idl_type)
......
......@@ -48,4 +48,5 @@ dictionary TestDictionary {
(Float or BooleanType) unionWithTypedefs;
[Clamp] long applicableToTypeLongMember;
[TreatNullAs=EmptyString] DOMString applicableToTypeStringMember;
(double or sequence<double>) unionMemberWithSequenceDefault = [];
};
......@@ -30,6 +30,7 @@ TestDictionary::TestDictionary() {
setTestInterfaceGarbageCollectedSequenceMember(HeapVector<Member<TestInterfaceGarbageCollected>>());
setTestInterfaceSequenceMember(HeapVector<Member<TestInterfaceImplementation>>());
setTreatNullAsStringSequenceMember(Vector<String>());
setUnionMemberWithSequenceDefault(DoubleOrDoubleSequence::FromDoubleSequence(Vector<double>()));
setUnrestrictedDoubleMember(3.14);
}
......@@ -130,6 +131,10 @@ void TestDictionary::setUnionInRecordMember(const HeapVector<std::pair<String, L
has_union_in_record_member_ = true;
}
void TestDictionary::setUnionMemberWithSequenceDefault(const DoubleOrDoubleSequence& value) {
union_member_with_sequence_default_ = value;
}
void TestDictionary::setUnionWithTypedefs(const FloatOrBoolean& value) {
union_with_typedefs_ = value;
}
......@@ -152,6 +157,7 @@ void TestDictionary::Trace(blink::Visitor* visitor) {
visitor->Trace(test_object_sequence_member_);
visitor->Trace(uint8_array_member_);
visitor->Trace(union_in_record_member_);
visitor->Trace(union_member_with_sequence_default_);
visitor->Trace(union_with_typedefs_);
IDLDictionaryBase::Trace(visitor);
}
......
......@@ -14,6 +14,7 @@
#include "bindings/core/v8/Dictionary.h"
#include "bindings/core/v8/IDLDictionaryBase.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/double_or_double_sequence.h"
#include "bindings/core/v8/double_or_string.h"
#include "bindings/core/v8/float_or_boolean.h"
#include "bindings/core/v8/long_or_boolean.h"
......@@ -318,6 +319,12 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
}
void setUnionInRecordMember(const HeapVector<std::pair<String, LongOrBoolean>>&);
bool hasUnionMemberWithSequenceDefault() const { return !union_member_with_sequence_default_.IsNull(); }
const DoubleOrDoubleSequence& unionMemberWithSequenceDefault() const {
return union_member_with_sequence_default_;
}
void setUnionMemberWithSequenceDefault(const DoubleOrDoubleSequence&);
bool hasUnionWithTypedefs() const { return !union_with_typedefs_.IsNull(); }
const FloatOrBoolean& unionWithTypedefs() const {
return union_with_typedefs_;
......@@ -401,6 +408,7 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
Vector<String> treat_null_as_string_sequence_member_;
Member<DOMUint8Array> uint8_array_member_;
HeapVector<std::pair<String, LongOrBoolean>> union_in_record_member_;
DoubleOrDoubleSequence union_member_with_sequence_default_;
FloatOrBoolean union_with_typedefs_;
double unrestricted_double_member_;
......
......@@ -76,6 +76,7 @@ static const v8::Eternal<v8::Name>* eternalV8TestDictionaryKeys(v8::Isolate* iso
"treatNullAsStringSequenceMember",
"uint8ArrayMember",
"unionInRecordMember",
"unionMemberWithSequenceDefault",
"unionWithTypedefs",
"unrestrictedDoubleMember",
};
......@@ -685,8 +686,23 @@ void V8TestDictionary::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value
impl.setUnionInRecordMember(unionInRecordMemberCppValue);
}
v8::Local<v8::Value> unionMemberWithSequenceDefaultValue;
if (!v8Object->Get(context, keys[42].Get(isolate)).ToLocal(&unionMemberWithSequenceDefaultValue)) {
exceptionState.RethrowV8Exception(block.Exception());
return;
}
if (unionMemberWithSequenceDefaultValue.IsEmpty() || unionMemberWithSequenceDefaultValue->IsUndefined()) {
// Do nothing.
} else {
DoubleOrDoubleSequence unionMemberWithSequenceDefaultCppValue;
V8DoubleOrDoubleSequence::ToImpl(isolate, unionMemberWithSequenceDefaultValue, unionMemberWithSequenceDefaultCppValue, UnionTypeConversionMode::kNotNullable, exceptionState);
if (exceptionState.HadException())
return;
impl.setUnionMemberWithSequenceDefault(unionMemberWithSequenceDefaultCppValue);
}
v8::Local<v8::Value> unionWithTypedefsValue;
if (!v8Object->Get(context, keys[42].Get(isolate)).ToLocal(&unionWithTypedefsValue)) {
if (!v8Object->Get(context, keys[43].Get(isolate)).ToLocal(&unionWithTypedefsValue)) {
exceptionState.RethrowV8Exception(block.Exception());
return;
}
......@@ -701,7 +717,7 @@ void V8TestDictionary::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value
}
v8::Local<v8::Value> unrestrictedDoubleMemberValue;
if (!v8Object->Get(context, keys[43].Get(isolate)).ToLocal(&unrestrictedDoubleMemberValue)) {
if (!v8Object->Get(context, keys[44].Get(isolate)).ToLocal(&unrestrictedDoubleMemberValue)) {
exceptionState.RethrowV8Exception(block.Exception());
return;
}
......@@ -1258,6 +1274,20 @@ bool toV8TestDictionary(const TestDictionary& impl, v8::Local<v8::Object> dictio
return false;
}
v8::Local<v8::Value> unionMemberWithSequenceDefaultValue;
bool unionMemberWithSequenceDefaultHasValueOrDefault = false;
if (impl.hasUnionMemberWithSequenceDefault()) {
unionMemberWithSequenceDefaultValue = ToV8(impl.unionMemberWithSequenceDefault(), creationContext, isolate);
unionMemberWithSequenceDefaultHasValueOrDefault = true;
} else {
unionMemberWithSequenceDefaultValue = ToV8(DoubleOrDoubleSequence::FromDoubleSequence(Vector<double>()), creationContext, isolate);
unionMemberWithSequenceDefaultHasValueOrDefault = true;
}
if (unionMemberWithSequenceDefaultHasValueOrDefault &&
!V8CallBoolean(dictionary->CreateDataProperty(context, keys[42].Get(isolate), unionMemberWithSequenceDefaultValue))) {
return false;
}
v8::Local<v8::Value> unionWithTypedefsValue;
bool unionWithTypedefsHasValueOrDefault = false;
if (impl.hasUnionWithTypedefs()) {
......@@ -1265,7 +1295,7 @@ bool toV8TestDictionary(const TestDictionary& impl, v8::Local<v8::Object> dictio
unionWithTypedefsHasValueOrDefault = true;
}
if (unionWithTypedefsHasValueOrDefault &&
!V8CallBoolean(dictionary->CreateDataProperty(context, keys[42].Get(isolate), unionWithTypedefsValue))) {
!V8CallBoolean(dictionary->CreateDataProperty(context, keys[43].Get(isolate), unionWithTypedefsValue))) {
return false;
}
......@@ -1279,7 +1309,7 @@ bool toV8TestDictionary(const TestDictionary& impl, v8::Local<v8::Object> dictio
unrestrictedDoubleMemberHasValueOrDefault = true;
}
if (unrestrictedDoubleMemberHasValueOrDefault &&
!V8CallBoolean(dictionary->CreateDataProperty(context, keys[43].Get(isolate), unrestrictedDoubleMemberValue))) {
!V8CallBoolean(dictionary->CreateDataProperty(context, keys[44].Get(isolate), unrestrictedDoubleMemberValue))) {
return false;
}
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file has been auto-generated from the Jinja2 template
// third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
// by the script code_generator_v8.py.
// DO NOT MODIFY!
// clang-format off
#include "double_or_double_sequence.h"
#include "bindings/core/v8/IDLTypes.h"
#include "bindings/core/v8/NativeValueTraitsImpl.h"
#include "bindings/core/v8/ToV8ForCore.h"
namespace blink {
DoubleOrDoubleSequence::DoubleOrDoubleSequence() : type_(SpecificType::kNone) {}
double DoubleOrDoubleSequence::GetAsDouble() const {
DCHECK(IsDouble());
return double_;
}
void DoubleOrDoubleSequence::SetDouble(double value) {
DCHECK(IsNull());
double_ = value;
type_ = SpecificType::kDouble;
}
DoubleOrDoubleSequence DoubleOrDoubleSequence::FromDouble(double value) {
DoubleOrDoubleSequence container;
container.SetDouble(value);
return container;
}
const Vector<double>& DoubleOrDoubleSequence::GetAsDoubleSequence() const {
DCHECK(IsDoubleSequence());
return double_sequence_;
}
void DoubleOrDoubleSequence::SetDoubleSequence(const Vector<double>& value) {
DCHECK(IsNull());
double_sequence_ = value;
type_ = SpecificType::kDoubleSequence;
}
DoubleOrDoubleSequence DoubleOrDoubleSequence::FromDoubleSequence(const Vector<double>& value) {
DoubleOrDoubleSequence container;
container.SetDoubleSequence(value);
return container;
}
DoubleOrDoubleSequence::DoubleOrDoubleSequence(const DoubleOrDoubleSequence&) = default;
DoubleOrDoubleSequence::~DoubleOrDoubleSequence() = default;
DoubleOrDoubleSequence& DoubleOrDoubleSequence::operator=(const DoubleOrDoubleSequence&) = default;
void DoubleOrDoubleSequence::Trace(blink::Visitor* visitor) {
}
void V8DoubleOrDoubleSequence::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, DoubleOrDoubleSequence& impl, UnionTypeConversionMode conversionMode, ExceptionState& exceptionState) {
if (v8Value.IsEmpty())
return;
if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value))
return;
if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) {
Vector<double> cppValue = NativeValueTraits<IDLSequence<IDLDouble>>::NativeValue(isolate, v8Value, exceptionState);
if (exceptionState.HadException())
return;
impl.SetDoubleSequence(cppValue);
return;
}
if (v8Value->IsNumber()) {
double cppValue = NativeValueTraits<IDLDouble>::NativeValue(isolate, v8Value, exceptionState);
if (exceptionState.HadException())
return;
impl.SetDouble(cppValue);
return;
}
{
double cppValue = NativeValueTraits<IDLDouble>::NativeValue(isolate, v8Value, exceptionState);
if (exceptionState.HadException())
return;
impl.SetDouble(cppValue);
return;
}
}
v8::Local<v8::Value> ToV8(const DoubleOrDoubleSequence& impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) {
switch (impl.type_) {
case DoubleOrDoubleSequence::SpecificType::kNone:
return v8::Null(isolate);
case DoubleOrDoubleSequence::SpecificType::kDouble:
return v8::Number::New(isolate, impl.GetAsDouble());
case DoubleOrDoubleSequence::SpecificType::kDoubleSequence:
return ToV8(impl.GetAsDoubleSequence(), creationContext, isolate);
default:
NOTREACHED();
}
return v8::Local<v8::Value>();
}
DoubleOrDoubleSequence NativeValueTraits<DoubleOrDoubleSequence>::NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) {
DoubleOrDoubleSequence impl;
V8DoubleOrDoubleSequence::ToImpl(isolate, value, impl, UnionTypeConversionMode::kNotNullable, exceptionState);
return impl;
}
} // namespace blink
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file has been auto-generated from the Jinja2 template
// third_party/WebKit/Source/bindings/templates/union_container.h.tmpl
// by the script code_generator_v8.py.
// DO NOT MODIFY!
// clang-format off
#ifndef DoubleOrDoubleSequence_h
#define DoubleOrDoubleSequence_h
#include "bindings/core/v8/Dictionary.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/NativeValueTraits.h"
#include "bindings/core/v8/V8BindingForCore.h"
#include "core/CoreExport.h"
#include "platform/heap/Handle.h"
namespace blink {
class CORE_EXPORT DoubleOrDoubleSequence final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
DoubleOrDoubleSequence();
bool IsNull() const { return type_ == SpecificType::kNone; }
bool IsDouble() const { return type_ == SpecificType::kDouble; }
double GetAsDouble() const;
void SetDouble(double);
static DoubleOrDoubleSequence FromDouble(double);
bool IsDoubleSequence() const { return type_ == SpecificType::kDoubleSequence; }
const Vector<double>& GetAsDoubleSequence() const;
void SetDoubleSequence(const Vector<double>&);
static DoubleOrDoubleSequence FromDoubleSequence(const Vector<double>&);
DoubleOrDoubleSequence(const DoubleOrDoubleSequence&);
~DoubleOrDoubleSequence();
DoubleOrDoubleSequence& operator=(const DoubleOrDoubleSequence&);
void Trace(blink::Visitor*);
private:
enum class SpecificType {
kNone,
kDouble,
kDoubleSequence,
};
SpecificType type_;
double double_;
Vector<double> double_sequence_;
friend CORE_EXPORT v8::Local<v8::Value> ToV8(const DoubleOrDoubleSequence&, v8::Local<v8::Object>, v8::Isolate*);
};
class V8DoubleOrDoubleSequence final {
public:
CORE_EXPORT static void ToImpl(v8::Isolate*, v8::Local<v8::Value>, DoubleOrDoubleSequence&, UnionTypeConversionMode, ExceptionState&);
};
CORE_EXPORT v8::Local<v8::Value> ToV8(const DoubleOrDoubleSequence&, v8::Local<v8::Object>, v8::Isolate*);
template <class CallbackInfo>
inline void V8SetReturnValue(const CallbackInfo& callbackInfo, DoubleOrDoubleSequence& impl) {
V8SetReturnValue(callbackInfo, ToV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}
template <class CallbackInfo>
inline void V8SetReturnValue(const CallbackInfo& callbackInfo, DoubleOrDoubleSequence& impl, v8::Local<v8::Object> creationContext) {
V8SetReturnValue(callbackInfo, ToV8(impl, creationContext, callbackInfo.GetIsolate()));
}
template <>
struct NativeValueTraits<DoubleOrDoubleSequence> : public NativeValueTraitsBase<DoubleOrDoubleSequence> {
CORE_EXPORT static DoubleOrDoubleSequence NativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};
template <>
struct V8TypeOf<DoubleOrDoubleSequence> {
typedef V8DoubleOrDoubleSequence Type;
};
} // namespace blink
// We need to set canInitializeWithMemset=true because HeapVector supports
// items that can initialize with memset or have a vtable. It is safe to
// set canInitializeWithMemset=true for a union type object in practice.
// See https://codereview.chromium.org/1118993002/#msg5 for more details.
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrDoubleSequence);
#endif // DoubleOrDoubleSequence_h
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