diff --git a/components/script_bindings/codegen/codegen.py b/components/script_bindings/codegen/codegen.py index 4329f04b421..111787903bd 100644 --- a/components/script_bindings/codegen/codegen.py +++ b/components/script_bindings/codegen/codegen.py @@ -52,6 +52,8 @@ from WebIDL import ( IDLEnum, IDLCallbackType, IDLUnresolvedIdentifier, + IDLMaplikeOrSetlikeOrIterableBase, + IDLConstructor, ) from configuration import ( @@ -60,11 +62,12 @@ from configuration import ( DescriptorProvider, MakeNativeName, MemberIsLegacyUnforgeable, + assert_type, getModuleFromObject, getTypesFromCallback, getTypesFromDescriptor, getTypesFromDictionary, - iteratorNativeType + iteratorNativeType, ) AUTOGENERATED_WARNING_COMMENT = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n" @@ -2845,9 +2848,9 @@ def UnionTypes( def DomTypes(descriptors: list[Descriptor], descriptorProvider: DescriptorProvider, - dictionaries: IDLDictionary, - callbacks: IDLCallback, - typedefs: IDLTypedef, + dictionaries: list[IDLDictionary], + callbacks: list[IDLCallback], + typedefs: list[IDLTypedef], config: Configuration ) -> CGThing: traits = [ @@ -2962,9 +2965,9 @@ def DomTypes(descriptors: list[Descriptor], def DomTypeHolder(descriptors: list[Descriptor], descriptorProvider: DescriptorProvider, - dictionaries: IDLDictionary, - callbacks: IDLCallback, - typedefs: IDLTypedef, + dictionaries: list[IDLDictionary], + callbacks: list[IDLCallback], + typedefs: list[IDLTypedef], config: Configuration ) -> CGThing: elements = [ @@ -4415,7 +4418,7 @@ let global = D::GlobalScope::from_object(args.callee()); raise NotImplementedError -def GetConstructorNameForReporting(descriptor: Descriptor, ctor: IDLInterfaceOrNamespace) -> str: +def GetConstructorNameForReporting(descriptor: Descriptor, ctor: IDLConstructor) -> str: # Figure out the name of our constructor for reporting purposes. # For unnamed webidl constructors, identifier.name is "constructor" but # the name JS sees is the interface name; for legacy factory functions @@ -5431,6 +5434,7 @@ impl{self.generic} Clone for {self.type}{self.genericSuffix} {{ return "" assert self.type.flatMemberTypes is not None + templateVars = [(getUnionTypeTemplateVars(t, self.descriptorProvider), getTypeWrapper(t)) for t in self.type.flatMemberTypes] enumValues = [ @@ -5464,7 +5468,7 @@ impl{self.generic} ToJSValConvertible for {self.type}{self.genericSuffix} {{ class CGUnionConversionStruct(CGThing): - def __init__(self, type, descriptorProvider) -> None: + def __init__(self, type: IDLUnionType, descriptorProvider: DescriptorProvider) -> None: assert not type.nullable() assert not type.hasNullableType @@ -5473,18 +5477,20 @@ class CGUnionConversionStruct(CGThing): self.descriptorProvider = descriptorProvider def membersNeedTracing(self) -> bool: + assert self.type.flatMemberTypes is not None for t in self.type.flatMemberTypes: if type_needs_tracing(t): return True return False - def from_jsval(self) -> CGThing: - memberTypes = self.type.flatMemberTypes + def from_jsval(self) -> CGWrapper: + memberTypes = cast(list[IDLType], self.type.flatMemberTypes) names = [] conversions = [] - def get_name(memberType) -> str: + def get_name(memberType: IDLType) -> str: if self.type.isGeckoInterface(): + # pyrefly: ignore # missing-attribute return memberType.inner.identifier.name return memberType.name @@ -5585,7 +5591,7 @@ class CGUnionConversionStruct(CGThing): assert len(booleanTypes) <= 1 assert numUndefinedVariants <= 1 - def getStringOrPrimitiveConversion(memberType) -> CGThing: + def getStringOrPrimitiveConversion(memberType: IDLType) -> CGThing: typename = get_name(memberType) return CGGeneric(get_match(typename)) @@ -5636,7 +5642,7 @@ class CGUnionConversionStruct(CGThing): pre=f"impl{generic} FromJSValConvertible for {self.type}{genericSuffix} {{\n", post="\n}") - def try_method(self, t) -> CGThing | CGWrapper: + def try_method(self, t: IDLType) -> CGThing: if t.isUndefined(): # undefined does not require a conversion method, so we don't generate one return CGGeneric("") @@ -5657,6 +5663,7 @@ class CGUnionConversionStruct(CGThing): def define(self) -> str: from_jsval = self.from_jsval() + assert self.type.flatMemberTypes is not None methods = CGIndenter(CGList([ self.try_method(t) for t in self.type.flatMemberTypes ], "\n\n")) @@ -5672,25 +5679,25 @@ impl{generic} {self.type}{genericSuffix} {{ class ClassItem: """ Use with CGClass """ - def __init__(self, name, visibility) -> None: + def __init__(self, name: str | None, visibility: str) -> None: self.name = name self.visibility = visibility - def declare(self, cgClass) -> str | None: + def declare(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return assert False - def define(self, cgClass) -> str | None: + def define(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return assert False class ClassBase(ClassItem): - def __init__(self, name, visibility='pub') -> None: + def __init__(self, name: str, visibility: str = 'pub') -> None: ClassItem.__init__(self, name, visibility) - def declare(self, cgClass) -> str: + def declare(self, cgClass: CGClass) -> str: return f'{self.visibility} {self.name}' - def define(self, cgClass) -> str | None: + def define(self, cgClass: CGClass) -> str: # Only in the header return '' @@ -5772,8 +5779,8 @@ class ClassMethod(ClassItem): f"{returnType}{const}{override}{body}{self.breakAfterSelf}" ) - def define(self, cgClass) -> None: - pass + def define(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return + assert False class ClassConstructor(ClassItem): @@ -5798,9 +5805,9 @@ class ClassConstructor(ClassItem): body contains a string with the code for the constructor, defaults to empty. """ - def __init__(self, args, inline=False, bodyInHeader=False, - visibility="priv", explicit=False, baseConstructors=None, - body="") -> None: + def __init__(self, args: list[Argument], inline: bool = False, bodyInHeader: bool = False, + visibility: str = "priv", explicit: bool = False, baseConstructors: list[str] | None = None, + body: str = "") -> None: self.args = args self.inline = False self.bodyInHeader = bodyInHeader @@ -5819,7 +5826,7 @@ class ClassConstructor(ClassItem): return f'{" ".join(decorators)} ' return '' - def getInitializationList(self, cgClass) -> str: + def getInitializationList(self, cgClass: CGClass) -> str: items = [str(c) for c in self.baseConstructors] for m in cgClass.members: if not m.static: @@ -5832,7 +5839,7 @@ class ClassConstructor(ClassItem): return f'\n : {joinedItems}' return '' - def getBody(self, cgClass) -> str: + def getBody(self, cgClass: CGClass) -> str: initializers = [f" parent: {self.baseConstructors[0]}"] joinedInitializers = '\n'.join(initializers) return ( @@ -5848,7 +5855,7 @@ class ClassConstructor(ClassItem): "ret" ) - def declare(self, cgClass) -> str: + def declare(self, cgClass: CGClass) -> str: args = ', '.join([a.declare() for a in self.args]) body = f' {self.getBody(cgClass)}' body = stripTrailingWhitespace(body.replace('\n', '\n ')) @@ -5861,7 +5868,7 @@ class ClassConstructor(ClassItem): pub unsafe fn {self.getDecorators(True)}new({args}) -> Rc<{name}>{body} """ - def define(self, cgClass) -> str: + def define(self, cgClass: CGClass) -> str: if self.bodyInHeader: return '' @@ -5882,17 +5889,17 @@ pub unsafe fn {self.getDecorators(True)}new({args}) -> Rc<{name}>{body} class ClassMember(ClassItem): - def __init__(self, name, type, visibility="priv", static=False, - body=None) -> None: + def __init__(self, name: str | None, type: str, visibility: str = "priv", static: bool = False, + body: str | None = None) -> None: self.type = type self.static = static self.body = body ClassItem.__init__(self, name, visibility) - def declare(self, cgClass) -> str: + def declare(self, cgClass: CGClass) -> str: return f'{self.visibility} {self.name}: {self.type},\n' - def define(self, cgClass) -> str: + def define(self, cgClass: CGClass) -> str: if not self.static: return '' if self.body: @@ -5903,13 +5910,22 @@ class ClassMember(ClassItem): class CGClass(CGThing): - def __init__(self, name, bases=[], members=[], constructors=[], - destructor: ClassItem | None=None, methods=[], - typedefs=[], enums=[], unions=[], templateArgs=[], - templateSpecialization=[], - disallowCopyConstruction=False, indent='', - decorators='', - extradeclarations='') -> None: + def __init__(self, + name: str, + bases: list[ClassBase] = [], + members: list[ClassMember] = [], + constructors: list[ClassConstructor] = [], + destructor: ClassItem | None = None, + methods: list[ClassMethod] = [], + typedefs: list[ClassItem] = [], + enums: list[ClassItem] = [], + unions: list[ClassItem] =[], + templateArgs: list[Argument] | None = [], + templateSpecialization: list[str] = [], + disallowCopyConstruction: bool = False, + indent: str = '', + decorators: str = '', + extradeclarations: str = '') -> None: CGThing.__init__(self) self.name = name self.bases = bases @@ -5929,7 +5945,7 @@ class CGClass(CGThing): self.decorators = decorators self.extradeclarations = extradeclarations - def getNameString(self): + def getNameString(self) -> str: className = self.name if self.templateSpecialization: className = f"{className}<{', '.join([str(a) for a in self.templateSpecialization])}>" @@ -5963,7 +5979,7 @@ class CGClass(CGThing): result += CGIndenter(CGGeneric(self.extradeclarations), len(self.indent)).define() - def declareMembers(cgClass, memberList) -> str: + def declareMembers(cgClass: CGClass, memberList: Iterable[ClassItem]) -> str: result = '' for member in memberList: @@ -5973,11 +5989,11 @@ class CGClass(CGThing): return result if self.disallowCopyConstruction: - class DisallowedCopyConstructor(object): + class DisallowedCopyConstructor(ClassItem): def __init__(self) -> None: self.visibility = "private" - def declare(self, cgClass) -> str: + def declare(self, cgClass: CGClass) -> str: name = cgClass.getNameString() return (f"{name}(const {name}&) MOZ_DELETE;\n" f"void operator=(const {name}) MOZ_DELETE;\n") @@ -6017,9 +6033,10 @@ class CGProxySpecialOperation(CGPerSignatureCall): (don't use this directly, use the derived classes below). """ templateValues: dict[str, Any] | None - def __init__(self, descriptor, operation) -> None: - nativeName = MakeNativeName(descriptor.binaryNameFor(operation, False)) - operation = descriptor.operations[operation] + def __init__(self, descriptor: Descriptor, operationName: str) -> None: + nativeName = MakeNativeName(descriptor.binaryNameFor(operationName, False)) + operation = descriptor.operations[operationName] + assert isinstance(operation, IDLMethod) assert len(operation.signatures()) == 1 signature = operation.signatures()[0] @@ -6067,7 +6084,7 @@ class CGProxyIndexedGetter(CGProxySpecialOperation): Class to generate a call to an indexed getter. If templateValues is not None the returned value will be wrapped with wrapForType using templateValues. """ - def __init__(self, descriptor, templateValues=None) -> None: + def __init__(self, descriptor: Descriptor, templateValues: dict[str, Any] | None = None) -> None: self.templateValues = templateValues CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter') @@ -6076,7 +6093,7 @@ class CGProxyIndexedSetter(CGProxySpecialOperation): """ Class to generate a call to an indexed setter. """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter') @@ -6084,7 +6101,7 @@ class CGProxyNamedOperation(CGProxySpecialOperation): """ Class to generate a call to a named operation. """ - def __init__(self, descriptor, name) -> None: + def __init__(self, descriptor: Descriptor, name: str) -> None: CGProxySpecialOperation.__init__(self, descriptor, name) def define(self) -> str: @@ -6101,7 +6118,7 @@ class CGProxyNamedGetter(CGProxyNamedOperation): Class to generate a call to an named getter. If templateValues is not None the returned value will be wrapped with wrapForType using templateValues. """ - def __init__(self, descriptor, templateValues=None) -> None: + def __init__(self, descriptor: Descriptor, templateValues: dict[str, Any] | None = None) -> None: self.templateValues = templateValues CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter') @@ -6111,7 +6128,7 @@ class CGProxyNamedPresenceChecker(CGProxyNamedGetter): Class to generate a call that checks whether a named property exists. For now, we just delegate to CGProxyNamedGetter """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGProxyNamedGetter.__init__(self, descriptor) @@ -6119,7 +6136,7 @@ class CGProxyNamedSetter(CGProxyNamedOperation): """ Class to generate a call to a named setter. """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter') @@ -6127,7 +6144,7 @@ class CGProxyNamedDeleter(CGProxyNamedOperation): """ Class to generate a call to a named deleter. """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGProxySpecialOperation.__init__(self, descriptor, 'NamedDeleter') def define(self) -> str: @@ -6148,7 +6165,7 @@ class CGProxyNamedDeleter(CGProxyNamedOperation): class CGProxyUnwrap(CGAbstractMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('RawHandleObject', 'obj')] CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", f'*const {descriptor.concreteType}', args, @@ -6164,7 +6181,7 @@ return box_;""") class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawHandleId', 'id'), Argument('RawMutableHandle', 'mut desc'), @@ -6290,7 +6307,7 @@ true""" class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawHandleId', 'id'), Argument('RawHandle', 'desc'), @@ -6350,7 +6367,7 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawHandleId', 'id'), Argument('*mut ObjectOpResult', 'res')] @@ -6384,7 +6401,7 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawMutableHandleIdVector', 'props')] @@ -6454,7 +6471,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: assert (descriptor.operations["IndexedGetter"] and descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") or descriptor.isMaybeCrossOriginObject()) @@ -6513,7 +6530,7 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawHandleId', 'id'), Argument('*mut bool', 'bp')] CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "bool", args, templateArgs=['D: DomTypes']) @@ -6587,7 +6604,7 @@ true""" class CGDOMJSProxyHandler_get(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawHandleValue', 'receiver'), Argument('RawHandleId', 'id'), Argument('RawMutableHandleValue', 'vp')] @@ -6688,7 +6705,7 @@ true""" class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawMutableHandleObject', 'proto')] CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args, templateArgs=["D: DomTypes"]) @@ -6707,7 +6724,7 @@ class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod): class CGDOMJSProxyHandler_className(CGAbstractExternMethod): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', '_proxy')] CGAbstractExternMethod.__init__(self, descriptor, "className", "*const libc::c_char", args, doesNotPanic=True) self.descriptor = descriptor @@ -6757,7 +6774,7 @@ class CGClassTraceHook(CGAbstractClassHook): """ A hook to trace through our native object; used for GC and CC """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut JSTracer', 'trc'), Argument('*mut JSObject', 'obj')] CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void', args, doesNotPanic=True) @@ -6775,7 +6792,7 @@ class CGClassConstructHook(CGAbstractExternMethod): """ JS-visible constructor for our objects """ - def __init__(self, descriptor, constructor=None) -> None: + def __init__(self, descriptor: Descriptor, constructor: IDLConstructor | None = None) -> None: args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')] name = CONSTRUCT_HOOK_NAME if constructor: @@ -6844,7 +6861,7 @@ class CGClassFinalizeHook(CGAbstractClassHook): """ A hook for finalize, used to release our native object. """ - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: args = [Argument('*mut GCContext', '_cx'), Argument('*mut JSObject', 'obj')] CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME, 'void', args) @@ -6854,7 +6871,7 @@ class CGClassFinalizeHook(CGAbstractClassHook): class CGDOMJSProxyHandlerDOMClass(CGThing): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGThing.__init__(self) self.descriptor = descriptor @@ -6872,7 +6889,12 @@ class CGInterfaceTrait(CGThing): def __init__(self, descriptor: Descriptor, descriptorProvider: DescriptorProvider) -> None: CGThing.__init__(self) - def attribute_arguments(attribute_type, argument=None, inRealm=False, canGc=False, retval=False): + def attribute_arguments(attribute_type: IDLType, + argument: IDLType | None = None, + inRealm: bool = False, + canGc: bool = False, + retval: bool = False + ) -> Iterable[tuple[str, str]]: if typeNeedsCx(attribute_type, retval): yield "cx", "SafeJSContext" @@ -6888,7 +6910,7 @@ class CGInterfaceTrait(CGThing): if retval and returnTypeNeedsOutparam(attribute_type): yield "retval", outparamTypeFromReturnType(attribute_type) - def members(): + def members() -> Iterator[tuple[str, Iterable[tuple[str, str]], str, bool]]: for m in descriptor.interface.members: if (m.isMethod() and not m.isMaplikeOrSetlikeOrIterableMethod() @@ -6965,14 +6987,14 @@ class CGInterfaceTrait(CGThing): rettype = return_type(descriptor, rettype, infallible) yield name, arguments, rettype, False - def fmt(arguments, leadingComma=True) -> str: + def fmt(arguments: list[tuple[str, str]], leadingComma: bool = True) -> str: prefix = "" if not leadingComma else ", " return prefix + ", ".join( f"r#{name}: {type_}" for name, type_ in arguments ) - def contains_unsafe_arg(arguments): + def contains_unsafe_arg(arguments: list[tuple[str, str]]) -> bool: if not arguments or len(arguments) == 0: return False return functools.reduce((lambda x, y: x or y[1] == '*mut JSContext'), arguments, False) @@ -6998,7 +7020,7 @@ class CGInterfaceTrait(CGThing): f"{fmt(arguments, leadingComma=not isStatic)}){returnType};\n" )) - def ctorMethod(ctor, baseName: str | None=None): + def ctorMethod(ctor: IDLMethod, baseName: str | None = None) -> Iterator[CGThing]: infallible = 'infallible' in descriptor.getExtendedAttributes(ctor) for (i, (rettype, arguments)) in enumerate(ctor.signatures()): name = (baseName or ctor.identifier.name) + ('_' * i) @@ -7038,7 +7060,7 @@ class CGInterfaceTrait(CGThing): class CGWeakReferenceableTrait(CGThing): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGThing.__init__(self) assert descriptor.weakReferenceable self.code = f"impl WeakReferenceable for {descriptor.interface.identifier.name} {{}}" @@ -7048,10 +7070,10 @@ class CGWeakReferenceableTrait(CGThing): class CGInitStatics(CGThing): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: CGThing.__init__(self) - def internal(method): + def internal(method: IDLMethod) -> str: return descriptor.internalNameFor(method.identifier.name) properties = PropertyArrays(descriptor) @@ -7137,14 +7159,14 @@ class CGInitStatics(CGThing): class CGDescriptor(CGThing): - def __init__(self, descriptor, config, soleDescriptor) -> None: + def __init__(self, descriptor: Descriptor, config: Configuration, soleDescriptor: bool) -> None: CGThing.__init__(self) assert not descriptor.concrete or not descriptor.interface.isCallback() reexports = [] - def reexportedName(name): + def reexportedName(name: str) -> str: if name.startswith(descriptor.name): return name if not soleDescriptor: @@ -7346,7 +7368,7 @@ class CGDescriptor(CGThing): class CGNonNamespacedEnum(CGThing): - def __init__(self, enumName, names, first, comment="", deriving="", repr="") -> None: + def __init__(self, enumName: str, names: list[str], first: int, comment: str = "", deriving: str = "", repr: str = "") -> None: # Account for first value entries = [f"{names[0]} = {first}"] + names[1:] @@ -7380,7 +7402,7 @@ class CGNonNamespacedEnum(CGThing): class CGDictionary(CGThing): - def __init__(self, dictionary, descriptorProvider, config) -> None: + def __init__(self, dictionary: IDLDictionary, descriptorProvider: DescriptorProvider, config: Configuration) -> None: self.dictionary = dictionary derivesList = config.getDictConfig(dictionary.identifier.name).get('derives', []) self.manualImpls = list(filter(lambda t: traitRequiresManualImpl(t, self.dictionary), derivesList)) @@ -7395,7 +7417,7 @@ class CGDictionary(CGThing): self.generic, self.genericSuffix = genericsForType(self.dictionary) - self.memberInfo = [ + self.memberInfo: list[tuple[IDLArgument, JSToNativeConversionInfo]] = [ (member, getJSToNativeConversionInfo(member.type, descriptorProvider, @@ -7428,7 +7450,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS }} """ - def manualImpl(self, t) -> str: + def manualImpl(self, t: str) -> str: if t == "Clone": return self.manualImplClone() raise ValueError(f"Don't know how to impl {t} for dicts.") @@ -7436,6 +7458,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS def struct(self) -> str: d = self.dictionary if d.parent: + assert isinstance(d.parent, IDLDictionary) typeName = f"{self.makeModuleName(d.parent)}::{self.makeClassName(d.parent)}" _, parentSuffix = genericsForType(d.parent) typeName += parentSuffix @@ -7497,6 +7520,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS def impl(self) -> str: d = self.dictionary if d.parent: + assert isinstance(d.parent, IDLDictionary) initParent = ( "{\n" f" match {self.makeModuleName(d.parent)}::{self.makeClassName(d.parent)}::new(cx, val)? {{\n" @@ -7511,20 +7535,20 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS else: initParent = "" - def memberInit(memberInfo) -> CGThing: + def memberInit(memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> CGThing: member, _ = memberInfo name = self.makeMemberName(member.identifier.name) conversion = self.getMemberConversion(memberInfo, member.type) return CGGeneric(f"{name}: {conversion.define()},\n") - def varInsert(varName: str, dictionaryName) -> CGThing: + def varInsert(varName: str, dictionaryName: str) -> CGThing: insertion = ( f"rooted!(in(cx) let mut {varName}_js = UndefinedValue());\n" f"{varName}.to_jsval(cx, {varName}_js.handle_mut());\n" f'set_dictionary_property(cx, obj.handle(), "{dictionaryName}", {varName}_js.handle()).unwrap();') return CGGeneric(insertion) - def memberInsert(memberInfo) -> CGThing: + def memberInsert(memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> CGThing: member, _ = memberInfo name = self.makeMemberName(member.identifier.name) if member.optional and not member.defaultValue: @@ -7605,28 +7629,30 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS return type_needs_tracing(self.dictionary) @staticmethod - def makeDictionaryName(dictionary): + def makeDictionaryName(dictionary: IDLDictionary | IDLWrapperType) -> str: if isinstance(dictionary, IDLWrapperType): return CGDictionary.makeDictionaryName(dictionary.inner) else: + assert isinstance(dictionary, IDLDictionary) return dictionary.identifier.name - def makeClassName(self, dictionary): + def makeClassName(self, dictionary: IDLDictionary | IDLWrapperType) -> str: return self.makeDictionaryName(dictionary) @staticmethod - def makeModuleName(dictionary) -> str: + def makeModuleName(dictionary: IDLDictionary | IDLWrapperType) -> str: return getModuleFromObject(dictionary) - def getMemberType(self, memberInfo): + def getMemberType(self, memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> str: member, info = memberInfo + assert info.declType is not None declType = info.declType if member.optional and not member.defaultValue: declType = CGWrapper(info.declType, pre="Option<", post=">") return declType.define() - def getMemberConversion(self, memberInfo, memberType) -> CGThing: - def indent(s) -> str: + def getMemberConversion(self, memberInfo: tuple[IDLArgument, JSToNativeConversionInfo], memberType: IDLType) -> CGThing: + def indent(s: str) -> str: return CGIndenter(CGGeneric(s), 12).define() member, info = memberInfo @@ -7682,6 +7708,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS ) s = "" if self.dictionary.parent: + assert isinstance(self.dictionary.parent, IDLDictionary) s += parentTemplate % (self.makeModuleName(self.dictionary.parent), self.makeClassName(self.dictionary.parent)) for member, info in self.memberInfo: @@ -7693,8 +7720,9 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS s += fieldTemplate % (self.makeMemberName(member.identifier.name), default) return functionTemplate % CGIndenter(CGGeneric(s), 12).define() - def hasRequiredFields(self, dictionary) -> bool: + def hasRequiredFields(self, dictionary: IDLDictionary) -> bool: if dictionary.parent: + assert isinstance(dictionary.parent, IDLDictionary) if self.hasRequiredFields(dictionary.parent): return True for member in dictionary.members: @@ -7710,9 +7738,10 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS return name @staticmethod - def getDictionaryDependencies(dictionary): + def getDictionaryDependencies(dictionary: IDLDictionary) -> set[IDLDictionary]: deps = set() if dictionary.parent: + assert isinstance(dictionary.parent, IDLDictionary) deps.add(dictionary.parent) for member in dictionary.members: if member.type.isDictionary(): @@ -7721,7 +7750,7 @@ impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericS class CGInitAllStatics(CGAbstractMethod): - def __init__(self, config) -> None: + def __init__(self, config: Configuration) -> None: docs = "Initialize the static data used by the SpiderMonkey DOM bindings to implement JS interfaces." descriptors = (config.getDescriptors(isCallback=False, register=True) + config.getDescriptors(isCallback=True, hasInterfaceObject=True, register=True)) @@ -7740,7 +7769,7 @@ class CGInitAllStatics(CGAbstractMethod): class CGRegisterProxyHandlersMethod(CGAbstractMethod): - def __init__(self, descriptors) -> None: + def __init__(self, descriptors: list[Descriptor]) -> None: docs = "Create the global vtables used by the generated DOM bindings to implement JS proxies." # FIXME: pass in a valid descriptor somehow # pyrefly: ignore # bad-argument-type @@ -7763,7 +7792,7 @@ class CGRegisterProxyHandlersMethod(CGAbstractMethod): class CGRegisterProxyHandlers(CGThing): - def __init__(self, config) -> None: + def __init__(self, config: Configuration) -> None: descriptors = config.getDescriptors(proxy=True) body = "".join( f" pub(crate) static {desc.name}: std::sync::atomic::AtomicPtr =\n" @@ -7787,7 +7816,7 @@ class CGStructuredCloneMarker(CGThing): """ Generate a type assertion for inheritance """ - def __init__(self, descriptor, marker) -> None: + def __init__(self, descriptor: Descriptor, marker: str) -> None: CGThing.__init__(self) self.descriptor = descriptor self.marker = marker @@ -7812,7 +7841,7 @@ class CGConcreteBindingRoot(CGThing): the generic bindings with type specialization applied. """ root: CGThing | None - def __init__(self, config, prefix, webIDLFile) -> None: + def __init__(self, config: Configuration, prefix: str, webIDLFile: str) -> None: descriptors = config.getDescriptors(webIDLFile=webIDLFile, hasInterfaceObject=True) # We also want descriptors that have an interface prototype object @@ -7954,7 +7983,7 @@ class CGBindingRoot(CGThing): declare or define to generate header or cpp code (respectively). """ root: CGThing | None - def __init__(self, config, prefix, webIDLFile) -> None: + def __init__(self, config: Configuration, prefix: str, webIDLFile: str) -> None: descriptors = config.getDescriptors(webIDLFile=webIDLFile, hasInterfaceObject=True) # We also want descriptors that have an interface prototype object @@ -8011,9 +8040,13 @@ class CGBindingRoot(CGThing): cgthings.extend([CGDescriptor(x, config, len(descriptors) == 1) for x in descriptors]) # Do codegen for all the callback interfaces. - cgthings.extend(CGList([CGCallbackInterface(x), - CGCallbackFunctionImpl(x.interface)], "\n") - for x in callbackDescriptors) + cgthings.extend(CGList( + [ + CGCallbackInterface(x), + CGCallbackFunctionImpl(assert_type(x.interface, IDLInterface)) + ], + "\n" + ) for x in callbackDescriptors) # And make sure we have the right number of newlines at the end curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n") @@ -8110,7 +8143,15 @@ def type_needs_auto_root(t: IDLType) -> bool: return False -def argument_type(descriptorProvider: DescriptorProvider, ty: IDLType, optional: bool = False, defaultValue=None, variadic: bool = False) -> str: +DefaultValueType = IDLValue | IDLNullValue | IDLUndefinedValue | IDLDefaultDictionaryValue | IDLEmptySequenceValue + + +def argument_type(descriptorProvider: DescriptorProvider, + ty: IDLType, + optional: bool = False, + defaultValue: DefaultValueType | None = None, + variadic: bool = False + ) -> str: info = getJSToNativeConversionInfo( ty, descriptorProvider, isArgument=True, isAutoRooted=type_needs_auto_root(ty)) @@ -8299,7 +8340,7 @@ class CGCallback(CGClass): visibility='pub'), method] - def deps(self): + def deps(self) -> set[str]: return self._deps @@ -8313,7 +8354,7 @@ def callbackSetterName(attr: IDLAttribute, descriptor: Descriptor) -> str: class CGCallbackFunction(CGCallback): - def __init__(self, callback, descriptorProvider) -> None: + def __init__(self, callback: IDLCallback, descriptorProvider: DescriptorProvider) -> None: CGCallback.__init__(self, callback, descriptorProvider, "CallbackFunction", methods=[CallCallback(callback, descriptorProvider)]) @@ -8323,7 +8364,7 @@ class CGCallbackFunction(CGCallback): class CGCallbackFunctionImpl(CGGeneric): - def __init__(self, callback) -> None: + def __init__(self, callback: IDLCallback | IDLInterface) -> None: type = f"{callback.identifier.name}" impl = (f""" impl CallbackContainer for {type} {{ @@ -8346,7 +8387,7 @@ impl ToJSValConvertible for {type} {{ class CGCallbackInterface(CGCallback): - def __init__(self, descriptor) -> None: + def __init__(self, descriptor: Descriptor) -> None: iface = descriptor.interface attrs = [m for m in iface.members if m.isAttr() and not m.isStatic()] assert not attrs @@ -8521,7 +8562,7 @@ class CallbackMember(CGNativeMember): ) return conversion - def getArgs(self, returnType, argList) -> list[Argument]: + def getArgs(self, returnType: IDLType, argList: list[IDLArgument]) -> list[Argument]: args = CGNativeMember.getArgs(self, returnType, argList) if not self.needThisHandling: # Since we don't need this handling, we're the actual method that @@ -8551,7 +8592,7 @@ class CallbackMember(CGNativeMember): return CGGeneric(f"let mut argc = {self.argCountStr};") @staticmethod - def ensureASCIIName(idlObject) -> None: + def ensureASCIIName(idlObject: IDLInterfaceMember) -> None: type = "attribute" if idlObject.isAttr() else "operation" if re.match("[^\x20-\x7E]", idlObject.identifier.name): raise SyntaxError(f'Callback {type} name "{idlObject.identifier.name}" contains non-ASCII ' @@ -8661,7 +8702,7 @@ class CallbackOperation(CallbackOperationBase): """ Codegen actual WebIDL operations on callback interfaces. """ - def __init__(self, method, signature, descriptor) -> None: + def __init__(self, method: IDLMethod, signature: tuple[IDLType, list[IDLArgument | FakeArgument]], descriptor: Descriptor) -> None: self.ensureASCIIName(method) jsName = method.identifier.name CallbackOperationBase.__init__(self, signature, @@ -8677,7 +8718,7 @@ class CGMaplikeOrSetlikeMethodGenerator(CGGeneric): CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of using CGCallGenerator. """ - def __init__(self, descriptor, likeable, methodName) -> None: + def __init__(self, descriptor: Descriptor, likeable: IDLMaplikeOrSetlikeOrIterableBase, methodName: str) -> None: trait: str if likeable.isSetlike(): trait = "Setlike" @@ -8748,7 +8789,7 @@ class CGIterableMethodGenerator(CGGeneric): CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of using CGCallGenerator. """ - def __init__(self, descriptor, iterable, methodName) -> None: + def __init__(self, descriptor: Descriptor, iterable: IDLMaplikeOrSetlikeOrIterableBase, methodName: str) -> None: if methodName == "forEach": CGGeneric.__init__(self, fill( """ @@ -8829,7 +8870,7 @@ class GlobalGenRoots(): """ @staticmethod - def Globals(config) -> CGThing: + def Globals(config: Configuration) -> CGThing: global_descriptors = config.getDescriptors(isGlobal=True) flags = [("EMPTY", 0)] flags.extend( @@ -8848,7 +8889,7 @@ class GlobalGenRoots(): ]) @staticmethod - def InterfaceObjectMap(config) -> CGThing: + def InterfaceObjectMap(config: Configuration) -> CGThing: mods = [ "crate::dom::bindings::codegen", "script_bindings::interfaces::Interface", @@ -8863,8 +8904,8 @@ class GlobalGenRoots(): ]) @staticmethod - def InterfaceObjectMapData(config) -> CGThing: - pairs = [] + def InterfaceObjectMapData(config: Configuration) -> CGThing: + pairs: list[tuple[str, str, str]] = [] for d in config.getDescriptors(hasInterfaceObject=True, isInline=False): binding_mod = toBindingModuleFileFromDescriptor(d) binding_ns = toBindingNamespace(d.name) @@ -8875,7 +8916,7 @@ class GlobalGenRoots(): pairs.append((ctor.identifier.name, binding_mod, binding_ns)) pairs.sort(key=operator.itemgetter(0)) - def bindingPath(pair) -> str: + def bindingPath(pair: tuple[str, str, str]) -> str: return f'codegen::Bindings::{pair[1]}::{pair[2]}' mappings = [ @@ -8889,7 +8930,7 @@ class GlobalGenRoots(): post="\n}\n") @staticmethod - def PrototypeList(config) -> CGThing: + def PrototypeList(config: Configuration) -> CGThing: # Prototype ID enum. interfaces = config.getDescriptors(isCallback=False, isNamespace=False) protos = [d.name for d in interfaces] @@ -8917,7 +8958,7 @@ class GlobalGenRoots(): ]) @staticmethod - def RegisterBindings(config) -> CGThing: + def RegisterBindings(config: Configuration) -> CGThing: # TODO - Generate the methods we want code = CGList([ CGRegisterProxyHandlers(config), @@ -8930,7 +8971,7 @@ class GlobalGenRoots(): ], config=config) @staticmethod - def InterfaceTypes(config) -> CGThing: + def InterfaceTypes(config: Configuration) -> CGThing: descriptors = sorted([MakeNativeName(d.name) for d in config.getDescriptors(register=True, isCallback=False, @@ -8941,9 +8982,9 @@ class GlobalGenRoots(): return curr @staticmethod - def Bindings(config) -> CGThing: + def Bindings(config: Configuration) -> CGThing: - def leafModule(d) -> str: + def leafModule(d: IDLObject) -> str: return getModuleFromObject(d).split('::')[-1] descriptors = config.getDescriptors(register=True, isIteratorInterface=False) @@ -8958,7 +8999,7 @@ class GlobalGenRoots(): return curr @staticmethod - def ConcreteInheritTypes(config) -> CGThing: + def ConcreteInheritTypes(config: Configuration) -> CGThing: descriptors = config.getDescriptors(register=True, isCallback=False) imports = [CGGeneric("use crate::dom::types::*;\n"), CGGeneric("use script_bindings::codegen::InheritTypes::*;\n"), @@ -8991,6 +9032,7 @@ class GlobalGenRoots(): allprotos.append(CGGeneric("\n")) if downcast: + assert descriptor.interface.parent is not None hierarchy[descriptor.interface.parent.identifier.name].append(name) typeIdCode = [] @@ -9017,7 +9059,7 @@ impl {base} {{ return curr @staticmethod - def InheritTypes(config) -> CGThing: + def InheritTypes(config: Configuration) -> CGThing: descriptors = config.getDescriptors(register=True, isCallback=False) topTypes = [] hierarchy = defaultdict(list) @@ -9030,6 +9072,7 @@ impl {base} {{ topTypes.append(name) if downcast: + assert descriptor.interface.parent is not None hierarchy[descriptor.interface.parent.identifier.name].append(name) typeIdCode: list = [] @@ -9054,7 +9097,7 @@ impl Clone for TopTypeId { """)) - def type_id_variant(name): + def type_id_variant(name: str) -> str: # If `name` is present in the hierarchy keys', that means some other interfaces # derive from it and this enum variant should have an argument with its own # TypeId enum. @@ -9075,7 +9118,7 @@ impl Clone for TopTypeId { return curr @staticmethod - def ConcreteUnionTypes(config) -> CGThing: + def ConcreteUnionTypes(config: Configuration) -> CGThing: unions = set() cgthings = [] allTypes = getAllTypes( @@ -9095,7 +9138,7 @@ impl Clone for TopTypeId { return curr @staticmethod - def UnionTypes(config) -> CGThing: + def UnionTypes(config: Configuration) -> CGThing: curr = UnionTypes(config.getDescriptors(), config.getDictionaries(), @@ -9110,7 +9153,7 @@ impl Clone for TopTypeId { return curr @staticmethod - def DomTypes(config) -> CGThing: + def DomTypes(config: Configuration) -> CGThing: curr = DomTypes(config.getDescriptors(), config.getDescriptorProvider(), config.getDictionaries(), @@ -9125,7 +9168,7 @@ impl Clone for TopTypeId { return curr @staticmethod - def DomTypeHolder(config) -> CGThing: + def DomTypeHolder(config: Configuration) -> CGThing: curr = DomTypeHolder(config.getDescriptors(), config.getDescriptorProvider(), config.getDictionaries(), @@ -9140,7 +9183,7 @@ impl Clone for TopTypeId { return curr @staticmethod - def SupportedDomApis(config) -> CGThing: + def SupportedDomApis(config: Configuration) -> CGThing: descriptors = config.getDescriptors(isExposedConditionally=False) base_path = os.path.dirname(__file__) diff --git a/components/script_bindings/codegen/configuration.py b/components/script_bindings/codegen/configuration.py index d15a23e220b..b10a037ed2b 100644 --- a/components/script_bindings/codegen/configuration.py +++ b/components/script_bindings/codegen/configuration.py @@ -111,7 +111,7 @@ class Configuration: def getInterface(self, ifname: str) -> IDLInterfaceOrNamespace: return self.interfaces[ifname] - def getDescriptors(self, **filters: IDLInterfaceOrNamespace) -> list[Descriptor]: + def getDescriptors(self, **filters: Any) -> list[Descriptor]: """Gets the descriptors that match the given filters.""" curr = self.descriptors for key, val in filters.items(): diff --git a/pyproject.toml b/pyproject.toml index df7b240724e..05bb458631f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,6 @@ ignore = [ [tool.ruff.lint.per-file-ignores] "etc/**" = ["ANN"] -"components/script_bindings/codegen/codegen.py" = ["ANN"] "**/test.py" = ["ANN"] "**/*_tests.py" = ["ANN"] "**/tests/**/*.py" = ["ANN"]