aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-14 04:41:04 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-15 13:42:08 +0100
commit4ad1a8ddccc29c8502ac43066922b40102e166a5 (patch)
tree52d2376b5b8b154003adf4ceef002878c9e021f9
parentb26c7bd7ea92bdbf7cdcaa0e3d826a880b9cd0ca (diff)
downloadservo-4ad1a8ddccc29c8502ac43066922b40102e166a5.tar.gz
servo-4ad1a8ddccc29c8502ac43066922b40102e166a5.zip
webidl: Implement sequences in unions
Unblocks #9053
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py50
-rw-r--r--components/script/dom/testbinding.rs7
-rw-r--r--components/script/dom/webidls/TestBinding.webidl4
3 files changed, 41 insertions, 20 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 2a04db77cc9..643c396febc 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1221,7 +1221,7 @@ def getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs):
return "StringificationBehavior::Default"
else:
return treatAs[treatNullAs]
- if type.isInteger():
+ if type.isPrimitive() and type.isInteger():
if isEnforceRange:
return "ConversionBehavior::EnforceRange"
elif isClamp:
@@ -3571,8 +3571,8 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
# for getJSToNativeConversionInfo.
# Also, for dictionaries we would need to handle conversion of
# null/undefined to the dictionary correctly.
- if type.isDictionary() or type.isSequence():
- raise TypeError("Can't handle dictionaries or sequences in unions")
+ if type.isDictionary():
+ raise TypeError("Can't handle dictionaries in unions")
if type.isGeckoInterface():
name = type.inner.identifier.name
@@ -3580,7 +3580,11 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
elif type.isEnum():
name = type.inner.identifier.name
typeName = name
- elif type.isArray() or type.isSequence():
+ elif type.isSequence():
+ name = type.name
+ inner = getUnionTypeTemplateVars(type.unroll(), descriptorProvider)
+ typeName = "Vec<" + inner["typeName"] + ">"
+ elif type.isArray():
name = str(type)
# XXXjdm dunno about typeName here
typeName = "/*" + type.name + "*/"
@@ -3664,22 +3668,22 @@ class CGUnionConversionStruct(CGThing):
names = []
conversions = []
- interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
- if len(interfaceMemberTypes) > 0:
- def get_name(memberType):
- if self.type.isGeckoInterface():
- return memberType.inner.identifier.name
+ def get_name(memberType):
+ if self.type.isGeckoInterface():
+ return memberType.inner.identifier.name
- return memberType.name
+ return memberType.name
- def get_match(name):
- return (
- "match %s::TryConvertTo%s(cx, value) {\n"
- " Err(_) => return Err(()),\n"
- " Ok(Some(value)) => return Ok(%s::e%s(value)),\n"
- " Ok(None) => (),\n"
- "}\n") % (self.type, name, self.type, name)
+ def get_match(name):
+ return (
+ "match %s::TryConvertTo%s(cx, value) {\n"
+ " Err(_) => return Err(()),\n"
+ " Ok(Some(value)) => return Ok(%s::e%s(value)),\n"
+ " Ok(None) => (),\n"
+ "}\n") % (self.type, name, self.type, name)
+ interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
+ if len(interfaceMemberTypes) > 0:
typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
interfaceObject = CGList(CGGeneric(get_match(typeName)) for typeName in typeNames)
names.extend(typeNames)
@@ -3689,7 +3693,9 @@ class CGUnionConversionStruct(CGThing):
arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
if len(arrayObjectMemberTypes) > 0:
assert len(arrayObjectMemberTypes) == 1
- raise TypeError("Can't handle arrays or sequences in unions.")
+ typeName = arrayObjectMemberTypes[0].name
+ arrayObject = CGGeneric(get_match(typeName))
+ names.append(typeName)
else:
arrayObject = None
@@ -3727,8 +3733,12 @@ class CGUnionConversionStruct(CGThing):
hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
if hasObjectTypes:
- assert interfaceObject
- templateBody = CGList([interfaceObject], "\n")
+ assert interfaceObject or arrayObject
+ templateBody = CGList([], "\n")
+ if interfaceObject:
+ templateBody.append(interfaceObject)
+ if arrayObject:
+ templateBody.append(arrayObject)
conversions.append(CGIfWrapper("value.get().is_object()", templateBody))
otherMemberTypes = [
diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs
index 687d68a5eb9..473f96f5704 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -9,6 +9,7 @@ use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::TestBindingBinding::{self, TestBindingMethods, TestEnum};
use dom::bindings::codegen::UnionTypes::{BlobOrString, EventOrString};
use dom::bindings::codegen::UnionTypes::{EventOrUSVString, HTMLElementOrLong};
+use dom::bindings::codegen::UnionTypes::{StringOrLongSequence, StringOrStringSequence};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -188,6 +189,8 @@ impl TestBindingMethods for TestBinding {
fn ReceiveObject(&self, _: *mut JSContext) -> *mut JSObject { panic!() }
fn ReceiveUnion(&self) -> HTMLElementOrLong { HTMLElementOrLong::eLong(0) }
fn ReceiveUnion2(&self) -> EventOrString { EventOrString::eString(DOMString::new()) }
+ fn ReceiveUnion3(&self) -> StringOrLongSequence { StringOrLongSequence::eLongSequence(vec![]) }
+ fn ReceiveUnion4(&self) -> StringOrStringSequence { StringOrStringSequence::eStringSequence(vec![]) }
fn ReceiveSequence(&self) -> Vec<i32> { vec![1] }
fn ReceiveNullableBoolean(&self) -> Option<bool> { Some(false) }
@@ -217,6 +220,9 @@ impl TestBindingMethods for TestBinding {
fn ReceiveNullableUnion2(&self) -> Option<EventOrString> {
Some(EventOrString::eString(DOMString::new()))
}
+ fn ReceiveNullableUnion3(&self) -> Option<StringOrLongSequence> {
+ Some(StringOrLongSequence::eString(DOMString::new()))
+ }
fn ReceiveNullableSequence(&self) -> Option<Vec<i32>> { Some(vec![1]) }
fn PassBoolean(&self, _: bool) {}
@@ -240,6 +246,7 @@ impl TestBindingMethods for TestBinding {
fn PassUnion(&self, _: HTMLElementOrLong) {}
fn PassUnion2(&self, _: EventOrString) {}
fn PassUnion3(&self, _: BlobOrString) {}
+ fn PassUnion4(&self, _: StringOrStringSequence) {}
fn PassAny(&self, _: *mut JSContext, _: HandleValue) {}
fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {}
fn PassCallbackFunction(&self, _: Rc<Function>) {}
diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl
index 7934182621e..ee3250427fe 100644
--- a/components/script/dom/webidls/TestBinding.webidl
+++ b/components/script/dom/webidls/TestBinding.webidl
@@ -149,6 +149,8 @@ interface TestBinding {
object receiveObject();
(HTMLElement or long) receiveUnion();
(Event or DOMString) receiveUnion2();
+ (DOMString or sequence<long>) receiveUnion3();
+ (DOMString or sequence<DOMString>) receiveUnion4();
sequence<long> receiveSequence();
byte? receiveNullableByte();
@@ -172,6 +174,7 @@ interface TestBinding {
object? receiveNullableObject();
(HTMLElement or long)? receiveNullableUnion();
(Event or DOMString)? receiveNullableUnion2();
+ (DOMString or sequence<long>)? receiveNullableUnion3();
sequence<long>? receiveNullableSequence();
void passBoolean(boolean arg);
@@ -195,6 +198,7 @@ interface TestBinding {
void passUnion((HTMLElement or long) arg);
void passUnion2((Event or DOMString) data);
void passUnion3((Blob or DOMString) data);
+ void passUnion4((DOMString or sequence<DOMString>) seq);
void passAny(any arg);
void passObject(object arg);
void passCallbackFunction(Function fun);