aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py118
1 files changed, 74 insertions, 44 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 82fcc4581d5..84d80124df9 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -700,7 +700,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
- raise TypeError("Can't handle sequence arguments yet")
+ 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"
+ "}" % (config, exceptionCode))
+
+ return handleOptional(templateBody, declType, handleDefaultNull("None"))
if type.isUnion():
declType = CGGeneric(union_native_type(type))
@@ -775,20 +787,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle SpiderMonkey interface arguments yet")
if type.isDOMString():
- assert not isEnforceRange and not isClamp
-
- treatAs = {
- "Default": "StringificationBehavior::Default",
- "EmptyString": "StringificationBehavior::Empty",
- }
- if treatNullAs not in treatAs:
- raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs)
- if type.nullable():
- # Note: the actual behavior passed here doesn't matter for nullable
- # strings.
- nullBehavior = "StringificationBehavior::Default"
- else:
- nullBehavior = treatAs[treatNullAs]
+ nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
conversionCode = (
"match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
@@ -1002,16 +1001,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if not type.isPrimitive():
raise TypeError("Need conversion for argument type '%s'" % str(type))
- if type.isInteger():
- if isEnforceRange:
- conversionBehavior = "ConversionBehavior::EnforceRange"
- elif isClamp:
- conversionBehavior = "ConversionBehavior::Clamp"
- else:
- conversionBehavior = "ConversionBehavior::Default"
- else:
- assert not isEnforceRange and not isClamp
- conversionBehavior = "()"
+ conversionBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
if failureCode is None:
failureCode = 'return false'
@@ -1215,6 +1205,36 @@ def typeNeedsCx(type, retVal=False):
return type.isAny() or type.isObject()
+# Returns a conversion behavior suitable for a type
+def getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs):
+ if type.isSequence():
+ return getConversionConfigForType(type.unroll(), isEnforceRange, isClamp, treatNullAs)
+ if type.isDOMString():
+ assert not isEnforceRange and not isClamp
+
+ treatAs = {
+ "Default": "StringificationBehavior::Default",
+ "EmptyString": "StringificationBehavior::Empty",
+ }
+ if treatNullAs not in treatAs:
+ raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs)
+ if type.nullable():
+ # Note: the actual behavior passed here doesn't matter for nullable
+ # strings.
+ return "StringificationBehavior::Default"
+ else:
+ return treatAs[treatNullAs]
+ if type.isPrimitive() and type.isInteger():
+ if isEnforceRange:
+ return "ConversionBehavior::EnforceRange"
+ elif isClamp:
+ return "ConversionBehavior::Clamp"
+ else:
+ return "ConversionBehavior::Default"
+ assert not isEnforceRange and not isClamp
+ return "()"
+
+
# Returns a CGThing containing the type of the return value.
def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType is None or returnType.isVoid():
@@ -3554,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
@@ -3563,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 + "*/"
@@ -3647,22 +3671,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)
@@ -3672,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
@@ -3710,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 = [