diff options
Diffstat (limited to 'components/script/dom/bindings/codegen')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 118 |
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 = [ |