diff options
Diffstat (limited to 'components/script_bindings/codegen/CodegenRust.py')
-rw-r--r-- | components/script_bindings/codegen/CodegenRust.py | 44 |
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 |