Auto merge of #9304 - ecoal95:sequence-in-unions, r=nox

webidl: Implement sequences in unions

Unblocks #9053

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9304)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-01-17 17:19:49 +05:30
commit 2f0daa1d47
4 changed files with 67 additions and 23 deletions

View file

@ -700,10 +700,13 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
# Use the same type that for return values
declType = getRetvalDeclarationForType(type, descriptorProvider)
innerInfo = getJSToNativeConversionInfo(type.unroll(), descriptorProvider)
declType = CGWrapper(innerInfo.declType, pre="Vec<", post=">")
config = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=" >")
templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
" Ok(value) => value,\n"
" Err(()) => { %s },\n"
@ -1221,7 +1224,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 +3574,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 +3583,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 +3671,22 @@ class CGUnionConversionStruct(CGThing):
names = []
conversions = []
def get_name(memberType):
if self.type.isGeckoInterface():
return memberType.inner.identifier.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)
interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
if len(interfaceMemberTypes) > 0:
def get_name(memberType):
if self.type.isGeckoInterface():
return memberType.inner.identifier.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)
typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
interfaceObject = CGList(CGGeneric(get_match(typeName)) for typeName in typeNames)
names.extend(typeNames)
@ -3689,7 +3696,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 +3736,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 = [

View file

@ -94,6 +94,17 @@ impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite
}
}
impl <T: Reflectable + IDLInterface> FromJSValConvertible for Root<T> {
type Config = ();
unsafe fn from_jsval(_cx: *mut JSContext,
value: HandleValue,
_config: Self::Config)
-> Result<Root<T>, ()> {
root_from_handlevalue(value)
}
}
/// Convert the given `jsid` to a `DOMString`. Fails if the `jsid` is not a
/// string, or if the string does not contain valid UTF-16.
pub fn jsid_to_str(cx: *mut JSContext, id: HandleId) -> DOMString {