aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/script_bindings/codegen/CodegenRust.py')
-rw-r--r--components/script_bindings/codegen/CodegenRust.py44
1 files changed, 34 insertions, 10 deletions
diff --git a/components/script_bindings/codegen/CodegenRust.py b/components/script_bindings/codegen/CodegenRust.py
index 20d6d30681e..37d62ff2e1b 100644
--- a/components/script_bindings/codegen/CodegenRust.py
+++ b/components/script_bindings/codegen/CodegenRust.py
@@ -39,6 +39,7 @@ from WebIDL import (
from Configuration import (
Configuration,
Descriptor,
+ DescriptorProvider,
MakeNativeName,
MemberIsLegacyUnforgeable,
getModuleFromObject,
@@ -617,16 +618,16 @@ class JSToNativeConversionInfo():
def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
- isDefinitelyObject=False,
- isMember=False,
+ isDefinitelyObject: bool = False,
+ isMember: bool | str = False,
isArgument=False,
isAutoRooted=False,
invalidEnumValueFatal=True,
defaultValue=None,
exceptionCode=None,
- allowTreatNonObjectAsNull=False,
+ allowTreatNonObjectAsNull: bool = False,
isCallbackReturnValue=False,
- sourceDescription="value"):
+ sourceDescription="value") -> JSToNativeConversionInfo:
"""
Get a template for converting a JS value to a native object based on the
given type and descriptor. If failureCode is given, then we're actually
@@ -5071,7 +5072,7 @@ class CGConstant(CGThing):
return f"pub const {name}: {const_type} = {value};\n"
-def getUnionTypeTemplateVars(type, descriptorProvider):
+def getUnionTypeTemplateVars(type, descriptorProvider: DescriptorProvider):
if type.isGeckoInterface():
name = type.inner.identifier.name
typeName = descriptorProvider.getDescriptor(name).returnType
@@ -5108,6 +5109,12 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
elif type.isCallback():
name = type.name
typeName = f"{name}<D>"
+ elif type.isUndefined():
+ return {
+ "name": type.name,
+ "typeName": "()",
+ "jsConversion": CGGeneric("if value.is_undefined() { Ok(Some(())) } else { Ok(None) }")
+ }
else:
raise TypeError(f"Can't handle {type} in unions yet")
@@ -5173,7 +5180,7 @@ impl{self.generic} Clone for {self.type}{self.genericSuffix} {{
def manualImpl(self, t, templateVars):
if t == "Clone":
return self.manualImplClone(templateVars)
- raise f"Don't know how to impl {t} for union"
+ raise ValueError(f"Don't know how to impl {t} for union")
def define(self):
def getTypeWrapper(t):
@@ -5330,31 +5337,44 @@ class CGUnionConversionStruct(CGThing):
stringTypes = [t for t in memberTypes if t.isString() or t.isEnum()]
numericTypes = [t for t in memberTypes if t.isNumeric()]
booleanTypes = [t for t in memberTypes if t.isBoolean()]
- if stringTypes or numericTypes or booleanTypes:
+ numUndefinedVariants = [t.isUndefined() for t in memberTypes].count(True)
+ if stringTypes or numericTypes or booleanTypes or numUndefinedVariants != 0:
assert len(stringTypes) <= 1
assert len(numericTypes) <= 1
assert len(booleanTypes) <= 1
+ assert numUndefinedVariants <= 1
def getStringOrPrimitiveConversion(memberType):
typename = get_name(memberType)
return CGGeneric(get_match(typename))
+
other = []
stringConversion = list(map(getStringOrPrimitiveConversion, stringTypes))
numericConversion = list(map(getStringOrPrimitiveConversion, numericTypes))
booleanConversion = list(map(getStringOrPrimitiveConversion, booleanTypes))
+ undefinedConversion = CGGeneric("return Ok(ConversionResult::Success(Self::Undefined(())));")
+
if stringConversion:
if booleanConversion:
other.append(CGIfWrapper("value.get().is_boolean()", booleanConversion[0]))
if numericConversion:
other.append(CGIfWrapper("value.get().is_number()", numericConversion[0]))
+ if numUndefinedVariants != 0:
+ other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
other.append(stringConversion[0])
elif numericConversion:
if booleanConversion:
other.append(CGIfWrapper("value.get().is_boolean()", booleanConversion[0]))
+ if numUndefinedVariants != 0:
+ other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
other.append(numericConversion[0])
- else:
- assert booleanConversion
+ elif booleanConversion:
+ if numUndefinedVariants != 0:
+ other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
other.append(booleanConversion[0])
+ else:
+ assert numUndefinedVariants != 0
+ other.append(undefinedConversion)
conversions.append(CGList(other, "\n\n"))
conversions.append(CGGeneric(
f'Ok(ConversionResult::Failure("argument could not be converted to any of: {", ".join(names)}".into()))'
@@ -5376,6 +5396,10 @@ class CGUnionConversionStruct(CGThing):
post="\n}")
def try_method(self, t):
+ if t.isUndefined():
+ # undefined does not require a conversion method, so we don't generate one
+ return CGGeneric("")
+
templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
actualType = templateVars["typeName"]
if type_needs_tracing(t):
@@ -7151,7 +7175,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS
def manualImpl(self, t):
if t == "Clone":
return self.manualImplClone()
- raise f"Don't know how to impl {t} for dicts."
+ raise ValueError(f"Don't know how to impl {t} for dicts.")
def struct(self):
d = self.dictionary