diff options
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
77 files changed, 9079 insertions, 4712 deletions
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py index e317087837d..9618ec3531f 100644 --- a/components/script/dom/bindings/codegen/parser/WebIDL.py +++ b/components/script/dom/bindings/codegen/parser/WebIDL.py @@ -4,16 +4,17 @@ """ A WebIDL parser. """ - -from ply import lex, yacc -import re -import os -import traceback +import copy import math +import os +import re import string -from collections import defaultdict, OrderedDict +import traceback +from collections import OrderedDict, defaultdict from itertools import chain +from ply import lex, yacc + # Machinery @@ -22,14 +23,14 @@ def parseInt(literal): sign = 0 base = 0 - if string[0] == '-': + if string[0] == "-": sign = -1 string = string[1:] else: sign = 1 - if string[0] == '0' and len(string) > 1: - if string[1] == 'x' or string[1] == 'X': + if string[0] == "0" and len(string) > 1: + if string[1] == "x" or string[1] == "X": base = 16 string = string[2:] else: @@ -45,19 +46,22 @@ def parseInt(literal): def enum(*names, **kw): class Foo(object): attrs = OrderedDict() + def __init__(self, names): for v, k in enumerate(names): self.attrs[k] = v + def __getattr__(self, attr): if attr in self.attrs: return self.attrs[attr] raise AttributeError + def __setattr__(self, name, value): # this makes it read-only raise NotImplementedError if "base" not in kw: return Foo(names) - return Foo(chain(list(kw["base"].attrs.keys()), names)) + return Foo(chain(kw["base"].attrs.keys(), names)) class WebIDLError(Exception): @@ -67,10 +71,12 @@ class WebIDLError(Exception): self.warning = warning def __str__(self): - return "%s: %s%s%s" % (self.warning and 'warning' or 'error', - self.message, - ", " if len(self.locations) != 0 else "", - "\n".join(self.locations)) + return "%s: %s%s%s" % ( + self.warning and "warning" or "error", + self.message, + ", " if len(self.locations) != 0 else "", + "\n".join(self.locations), + ) class Location(object): @@ -82,8 +88,7 @@ class Location(object): self._file = filename if filename else "<unknown>" def __eq__(self, other): - return (self._lexpos == other._lexpos and - self._file == other._file) + return self._lexpos == other._lexpos and self._file == other._file def filename(self): return self._file @@ -92,8 +97,8 @@ class Location(object): if self._line: return - startofline = self._lexdata.rfind('\n', 0, self._lexpos) + 1 - endofline = self._lexdata.find('\n', self._lexpos, self._lexpos + 80) + startofline = self._lexdata.rfind("\n", 0, self._lexpos) + 1 + endofline = self._lexdata.find("\n", self._lexpos, self._lexpos + 80) if endofline != -1: self._line = self._lexdata[startofline:endofline] else: @@ -101,7 +106,7 @@ class Location(object): self._colno = self._lexpos - startofline # Our line number seems to point to the start of self._lexdata - self._lineno += self._lexdata.count('\n', 0, startofline) + self._lineno += self._lexdata.count("\n", 0, startofline) def get(self): self.resolve() @@ -112,8 +117,13 @@ class Location(object): def __str__(self): self.resolve() - return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno, - self._line, self._pointerline()) + return "%s line %s:%s\n%s\n%s" % ( + self._file, + self._lineno, + self._colno, + self._line, + self._pointerline(), + ) class BuiltinLocation(object): @@ -121,14 +131,10 @@ class BuiltinLocation(object): self.msg = text + "\n" def __eq__(self, other): - return (isinstance(other, BuiltinLocation) and - self.msg == other.msg) - - def __hash__(self): - return hash(self.msg) + return isinstance(other, BuiltinLocation) and self.msg == other.msg def filename(self): - return '<builtin>' + return "<builtin>" def resolve(self): pass @@ -194,13 +200,13 @@ class IDLObject(object): assert False # Override me! def getDeps(self, visited=None): - """ Return a set of files that this object depends on. If any of - these files are changed the parser needs to be rerun to regenerate - a new IDLObject. + """Return a set of files that this object depends on. If any of + these files are changed the parser needs to be rerun to regenerate + a new IDLObject. - The visited argument is a set of all the objects already visited. - We must test to see if we are in it, and if so, do nothing. This - prevents infinite recursion.""" + The visited argument is a set of all the objects already visited. + We must test to see if we are in it, and if so, do nothing. This + prevents infinite recursion.""" # NB: We can't use visited=set() above because the default value is # evaluated when the def statement is evaluated, not when the function @@ -256,9 +262,9 @@ class IDLScope(IDLObject): def ensureUnique(self, identifier, object): """ - Ensure that there is at most one 'identifier' in scope ('self'). - Note that object can be None. This occurs if we end up here for an - interface type we haven't seen yet. + Ensure that there is at most one 'identifier' in scope ('self'). + Note that object can be None. This occurs if we end up here for an + interface type we haven't seen yet. """ assert isinstance(identifier, IDLUnresolvedIdentifier) assert not object or isinstance(object, IDLObjectWithIdentifier) @@ -271,9 +277,9 @@ class IDLScope(IDLObject): # ensureUnique twice with the same object is not allowed assert id(object) != id(self._dict[identifier.name]) - replacement = self.resolveIdentifierConflict(self, identifier, - self._dict[identifier.name], - object) + replacement = self.resolveIdentifierConflict( + self, identifier, self._dict[identifier.name], object + ) self._dict[identifier.name] = replacement return @@ -282,44 +288,53 @@ class IDLScope(IDLObject): self._dict[identifier.name] = object def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject): - if (isinstance(originalObject, IDLExternalInterface) and - isinstance(newObject, IDLExternalInterface) and - originalObject.identifier.name == newObject.identifier.name): + if ( + isinstance(originalObject, IDLExternalInterface) + and isinstance(newObject, IDLExternalInterface) + and originalObject.identifier.name == newObject.identifier.name + ): return originalObject - if (isinstance(originalObject, IDLExternalInterface) or - isinstance(newObject, IDLExternalInterface)): + if isinstance(originalObject, IDLExternalInterface) or isinstance( + newObject, IDLExternalInterface + ): raise WebIDLError( "Name collision between " "interface declarations for identifier '%s' at '%s' and '%s'" - % (identifier.name, - originalObject.location, newObject.location), []) + % (identifier.name, originalObject.location, newObject.location), + [], + ) - if (isinstance(originalObject, IDLDictionary) or - isinstance(newObject, IDLDictionary)): + if isinstance(originalObject, IDLDictionary) or isinstance( + newObject, IDLDictionary + ): raise WebIDLError( "Name collision between dictionary declarations for " "identifier '%s'.\n%s\n%s" - % (identifier.name, - originalObject.location, newObject.location), []) + % (identifier.name, originalObject.location, newObject.location), + [], + ) # We do the merging of overloads here as opposed to in IDLInterface - # because we need to merge overloads of NamedConstructors and we need to + # because we need to merge overloads of LegacyFactoryFunctions and we need to # detect conflicts in those across interfaces. See also the comment in - # IDLInterface.addExtendedAttributes for "NamedConstructor". - if (isinstance(originalObject, IDLMethod) and - isinstance(newObject, IDLMethod)): + # IDLInterface.addExtendedAttributes for "LegacyFactoryFunction". + if isinstance(originalObject, IDLMethod) and isinstance(newObject, IDLMethod): return originalObject.addOverload(newObject) # Default to throwing, derived classes can override. - conflictdesc = "\n\t%s at %s\n\t%s at %s" % (originalObject, - originalObject.location, - newObject, - newObject.location) + conflictdesc = "\n\t%s at %s\n\t%s at %s" % ( + originalObject, + originalObject.location, + newObject, + newObject.location, + ) raise WebIDLError( "Multiple unresolvable definitions of identifier '%s' in scope '%s'%s" - % (identifier.name, str(self), conflictdesc), []) + % (identifier.name, str(self), conflictdesc), + [], + ) def _lookupIdentifier(self, identifier): return self._dict[identifier.name] @@ -362,8 +377,9 @@ class IDLIdentifier(IDLObject): class IDLUnresolvedIdentifier(IDLObject): - def __init__(self, location, name, allowDoubleUnderscore=False, - allowForbidden=False): + def __init__( + self, location, name, allowDoubleUnderscore=False, allowForbidden=False + ): IDLObject.__init__(self, location) assert len(name) > 0 @@ -371,15 +387,14 @@ class IDLUnresolvedIdentifier(IDLObject): if name == "__noSuchMethod__": raise WebIDLError("__noSuchMethod__ is deprecated", [location]) - if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore: - raise WebIDLError("Identifiers beginning with __ are reserved", - [location]) - if name[0] == '_' and not allowDoubleUnderscore: + if name[:2] == "__" and not allowDoubleUnderscore: + raise WebIDLError("Identifiers beginning with __ are reserved", [location]) + if name[0] == "_" and not allowDoubleUnderscore: name = name[1:] - if (name in ["constructor", "toString"] and - not allowForbidden): - raise WebIDLError("Cannot use reserved identifier '%s'" % (name), - [location]) + if name in ["constructor", "toString"] and not allowForbidden: + raise WebIDLError( + "Cannot use reserved identifier '%s'" % (name), [location] + ) self.name = name @@ -439,14 +454,15 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier): try: scope._lookupIdentifier(self.identifier) except: - raise WebIDLError("Unresolved type '%s'." % self.identifier, - [self.location]) + raise WebIDLError( + "Unresolved type '%s'." % self.identifier, [self.location] + ) obj = self.identifier.resolve(scope, None) return scope.lookupIdentifier(obj) -class IDLExposureMixins(): +class IDLExposureMixins: def __init__(self, location): # _exposureGlobalNames are the global names listed in our [Exposed] # extended attribute. exposureSet is the exposure set as defined in the @@ -460,11 +476,15 @@ class IDLExposureMixins(): assert scope.parentScope is None self._globalScope = scope - # Verify that our [Exposed] value, if any, makes sense. - for globalName in self._exposureGlobalNames: - if globalName not in scope.globalNames: - raise WebIDLError("Unknown [Exposed] value %s" % globalName, - [self._location]) + if "*" in self._exposureGlobalNames: + self._exposureGlobalNames = scope.globalNames + else: + # Verify that our [Exposed] value, if any, makes sense. + for globalName in self._exposureGlobalNames: + if globalName not in scope.globalNames: + raise WebIDLError( + "Unknown [Exposed] value %s" % globalName, [self._location] + ) # Verify that we are exposed _somwhere_ if we have some place to be # exposed. We don't want to assert that we're definitely exposed @@ -473,16 +493,20 @@ class IDLExposureMixins(): # and add global interfaces and [Exposed] annotations to all those # tests. if len(scope.globalNames) != 0: - if (len(self._exposureGlobalNames) == 0): - raise WebIDLError(("'%s' is not exposed anywhere even though we have " - "globals to be exposed to") % self, - [self.location]) + if len(self._exposureGlobalNames) == 0 and not self.isPseudoInterface(): + raise WebIDLError( + ( + "'%s' is not exposed anywhere even though we have " + "globals to be exposed to" + ) + % self, + [self.location], + ) - globalNameSetToExposureSet(scope, self._exposureGlobalNames, - self.exposureSet) + globalNameSetToExposureSet(scope, self._exposureGlobalNames, self.exposureSet) def isExposedInWindow(self): - return 'Window' in self.exposureSet + return "Window" in self.exposureSet def isExposedInAnyWorker(self): return len(self.getWorkerExposureSet()) > 0 @@ -505,6 +529,9 @@ class IDLExposureMixins(): workerScopes = self.parentScope.globalNameMapping["Worker"] return len(workerScopes.difference(self.exposureSet)) > 0 + def isExposedInShadowRealms(self): + return "ShadowRealmGlobalScope" in self.exposureSet + def getWorkerExposureSet(self): workerScopes = self._globalScope.globalNameMapping["Worker"] return workerScopes.intersection(self.exposureSet) @@ -535,6 +562,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier): def isIteratorInterface(self): return False + def isAsyncIteratorInterface(self): + return False + def isExternal(self): return True @@ -543,9 +573,11 @@ class IDLExternalInterface(IDLObjectWithIdentifier): def addExtendedAttributes(self, attrs): if len(attrs) != 0: - raise WebIDLError("There are no extended attributes that are " - "allowed on external interfaces", - [attrs[0].location, self.location]) + raise WebIDLError( + "There are no extended attributes that are " + "allowed on external interfaces", + [attrs[0].location, self.location], + ) def resolve(self, parentScope): pass @@ -610,49 +642,68 @@ class IDLPartialInterfaceOrNamespace(IDLObject): for attr in attrs: identifier = attr.identifier() - if identifier == "NamedConstructor": + if identifier == "LegacyFactoryFunction": self.propagatedExtendedAttrs.append(attr) elif identifier == "SecureContext": self._haveSecureContextExtendedAttribute = True # This gets propagated to all our members. for member in self.members: if member.getExtendedAttribute("SecureContext"): - raise WebIDLError("[SecureContext] specified on both a " - "partial interface member and on the " - "partial interface itself", - [member.location, attr.location]) + raise WebIDLError( + "[SecureContext] specified on both a " + "partial interface member and on the " + "partial interface itself", + [member.location, attr.location], + ) member.addExtendedAttributes([attr]) elif identifier == "Exposed": # This just gets propagated to all our members. for member in self.members: if len(member._exposureGlobalNames) != 0: - raise WebIDLError("[Exposed] specified on both a " - "partial interface member and on the " - "partial interface itself", - [member.location, attr.location]) + raise WebIDLError( + "[Exposed] specified on both a " + "partial interface member and on the " + "partial interface itself", + [member.location, attr.location], + ) member.addExtendedAttributes([attr]) else: - raise WebIDLError("Unknown extended attribute %s on partial " - "interface" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on partial " + "interface" % identifier, + [attr.location], + ) def finish(self, scope): if self._finished: return self._finished = True - if (not self._haveSecureContextExtendedAttribute and - self._nonPartialInterfaceOrNamespace.getExtendedAttribute("SecureContext")): + if ( + not self._haveSecureContextExtendedAttribute + and self._nonPartialInterfaceOrNamespace.getExtendedAttribute( + "SecureContext" + ) + ): # This gets propagated to all our members. for member in self.members: if member.getExtendedAttribute("SecureContext"): - raise WebIDLError("[SecureContext] specified on both a " - "partial interface member and on the " - "non-partial interface", - [member.location, - self._nonPartialInterfaceOrNamespace.location]) + raise WebIDLError( + "[SecureContext] specified on both a " + "partial interface member and on the " + "non-partial interface", + [ + member.location, + self._nonPartialInterfaceOrNamespace.location, + ], + ) member.addExtendedAttributes( - [IDLExtendedAttribute(self._nonPartialInterfaceOrNamespace.location, - ("SecureContext",))]) + [ + IDLExtendedAttribute( + self._nonPartialInterfaceOrNamespace.location, + ("SecureContext",), + ) + ] + ) # Need to make sure our non-partial interface or namespace gets # finished so it can report cases when we only have partial # interfaces/namespaces. @@ -675,6 +726,7 @@ def globalNameSetToExposureSet(globalScope, nameSet, exposureSet): for name in nameSet: exposureSet.update(globalScope.globalNameMapping[name]) + class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMixins): def __init__(self, location, parentScope, name): assert isinstance(parentScope, IDLScope) @@ -691,8 +743,10 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix def finish(self, scope): if not self._isKnownNonPartial: - raise WebIDLError("%s does not have a non-partial declaration" % - str(self), [self.location]) + raise WebIDLError( + "%s does not have a non-partial declaration" % str(self), + [self.location], + ) IDLExposureMixins.finish(self, scope) @@ -707,8 +761,9 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix assert isinstance(originalObject, IDLInterfaceMember) assert isinstance(newObject, IDLInterfaceMember) - retval = IDLScope.resolveIdentifierConflict(self, scope, identifier, - originalObject, newObject) + retval = IDLScope.resolveIdentifierConflict( + self, scope, identifier, originalObject, newObject + ) # Might be a ctor, which isn't in self.members if newObject in self.members: @@ -728,9 +783,10 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix def setNonPartial(self, location, members): if self._isKnownNonPartial: - raise WebIDLError("Two non-partial definitions for the " - "same %s" % self.typeName(), - [location, self.location]) + raise WebIDLError( + "Two non-partial definitions for the " "same %s" % self.typeName(), + [location, self.location], + ) self._isKnownNonPartial = True # Now make it look like we were parsed at this new location, since # that's the place where the interface is "really" defined @@ -775,9 +831,11 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix # sets, make sure they aren't exposed in places where we are not. for member in self.members: if not member.exposureSet.issubset(self.exposureSet): - raise WebIDLError("Interface or interface mixin member has " - "larger exposure set than its container", - [member.location, self.location]) + raise WebIDLError( + "Interface or interface mixin member has " + "larger exposure set than its container", + [member.location, self.location], + ) def isExternal(self): return False @@ -788,7 +846,9 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace): self.actualExposureGlobalNames = set() assert isKnownNonPartial or len(members) == 0 - IDLInterfaceOrInterfaceMixinOrNamespace.__init__(self, location, parentScope, name) + IDLInterfaceOrInterfaceMixinOrNamespace.__init__( + self, location, parentScope, name + ) if isKnownNonPartial: self.setNonPartial(location, members) @@ -824,26 +884,33 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace): if member.isAttr(): if member.inherit: - raise WebIDLError("Interface mixin member cannot include " - "an inherited attribute", - [member.location, self.location]) + raise WebIDLError( + "Interface mixin member cannot include " + "an inherited attribute", + [member.location, self.location], + ) if member.isStatic(): - raise WebIDLError("Interface mixin member cannot include " - "a static member", - [member.location, self.location]) + raise WebIDLError( + "Interface mixin member cannot include " "a static member", + [member.location, self.location], + ) if member.isMethod(): if member.isStatic(): - raise WebIDLError("Interface mixin member cannot include " - "a static operation", - [member.location, self.location]) - if (member.isGetter() or - member.isSetter() or - member.isDeleter() or - member.isLegacycaller()): - raise WebIDLError("Interface mixin member cannot include a " - "special operation", - [member.location, self.location]) + raise WebIDLError( + "Interface mixin member cannot include " "a static operation", + [member.location, self.location], + ) + if ( + member.isGetter() + or member.isSetter() + or member.isDeleter() + or member.isLegacycaller() + ): + raise WebIDLError( + "Interface mixin member cannot include a " "special operation", + [member.location, self.location], + ) def addExtendedAttributes(self, attrs): for attr in attrs: @@ -851,22 +918,26 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace): if identifier == "SecureContext": if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) # This gets propagated to all our members. for member in self.members: if member.getExtendedAttribute("SecureContext"): - raise WebIDLError("[SecureContext] specified on both " - "an interface mixin member and on" - "the interface mixin itself", - [member.location, attr.location]) + raise WebIDLError( + "[SecureContext] specified on both " + "an interface mixin member and on" + "the interface mixin itself", + [member.location, attr.location], + ) member.addExtendedAttributes([attr]) elif identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, - self._exposureGlobalNames) + convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) else: - raise WebIDLError("Unknown extended attribute %s on interface" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on interface" % identifier, + [attr.location], + ) attrlist = attr.listValue() self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True @@ -876,8 +947,7 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace): class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): - def __init__(self, location, parentScope, name, parent, members, - isKnownNonPartial, toStringTag): + def __init__(self, location, parentScope, name, parent, members, isKnownNonPartial): assert isKnownNonPartial or not parent assert isKnownNonPartial or len(members) == 0 @@ -887,7 +957,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): # namedConstructors needs deterministic ordering because bindings code # outputs the constructs in the order that namedConstructors enumerates # them. - self.namedConstructors = list() + self.legacyFactoryFunctions = list() self.legacyWindowAliases = [] self.includedMixins = set() # self.interfacesBasedOnSelf is the set of interfaces that inherit from @@ -896,6 +966,9 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): self.interfacesBasedOnSelf = set([self]) self._hasChildInterfaces = False self._isOnGlobalProtoChain = False + # Pseudo interfaces aren't exposed anywhere, and so shouldn't issue warnings + self._isPseudo = False + # Tracking of the number of reserved slots we need for our # members and those of ancestor interfaces. self.totalMembersInSlots = 0 @@ -904,33 +977,49 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): # If this is an iterator interface, we need to know what iterable # interface we're iterating for in order to get its nativeType. self.iterableInterface = None + self.asyncIterableInterface = None # True if we have cross-origin members. self.hasCrossOriginMembers = False # True if some descendant (including ourselves) has cross-origin members self.hasDescendantWithCrossOriginMembers = False - self.toStringTag = toStringTag - - IDLInterfaceOrInterfaceMixinOrNamespace.__init__(self, location, parentScope, name) + IDLInterfaceOrInterfaceMixinOrNamespace.__init__( + self, location, parentScope, name + ) if isKnownNonPartial: self.setNonPartial(location, parent, members) def ctor(self): - identifier = IDLUnresolvedIdentifier(self.location, "constructor", - allowForbidden=True) + identifier = IDLUnresolvedIdentifier( + self.location, "constructor", allowForbidden=True + ) try: return self._lookupIdentifier(identifier) except: return None def isIterable(self): - return (self.maplikeOrSetlikeOrIterable and - self.maplikeOrSetlikeOrIterable.isIterable()) + return ( + self.maplikeOrSetlikeOrIterable + and self.maplikeOrSetlikeOrIterable.isIterable() + ) + + def isAsyncIterable(self): + return ( + self.maplikeOrSetlikeOrIterable + and self.maplikeOrSetlikeOrIterable.isAsyncIterable() + ) def isIteratorInterface(self): return self.iterableInterface is not None + def isAsyncIteratorInterface(self): + return self.asyncIterableInterface is not None + + def getClassName(self): + return self.identifier.name + def finish(self, scope): if self._finished: return @@ -941,48 +1030,71 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): if len(self.legacyWindowAliases) > 0: if not self.hasInterfaceObject(): - raise WebIDLError("Interface %s unexpectedly has [LegacyWindowAlias] " - "and [NoInterfaceObject] together" % self.identifier.name, - [self.location]) + raise WebIDLError( + "Interface %s unexpectedly has [LegacyWindowAlias] " + "and [LegacyNoInterfaceObject] together" % self.identifier.name, + [self.location], + ) if not self.isExposedInWindow(): - raise WebIDLError("Interface %s has [LegacyWindowAlias] " - "but not exposed in Window" % self.identifier.name, - [self.location]) + raise WebIDLError( + "Interface %s has [LegacyWindowAlias] " + "but not exposed in Window" % self.identifier.name, + [self.location], + ) # Generate maplike/setlike interface members. Since generated members # need to be treated like regular interface members, do this before # things like exposure setting. for member in self.members: if member.isMaplikeOrSetlikeOrIterable(): + if self.isJSImplemented(): + raise WebIDLError( + "%s declaration used on " + "interface that is implemented in JS" + % (member.maplikeOrSetlikeOrIterableType), + [member.location], + ) + if member.valueType.isObservableArray() or ( + member.hasKeyType() and member.keyType.isObservableArray() + ): + raise WebIDLError( + "%s declaration uses ObservableArray as value or key type" + % (member.maplikeOrSetlikeOrIterableType), + [member.location], + ) # Check that we only have one interface declaration (currently # there can only be one maplike/setlike declaration per # interface) if self.maplikeOrSetlikeOrIterable: - raise WebIDLError("%s declaration used on " - "interface that already has %s " - "declaration" % - (member.maplikeOrSetlikeOrIterableType, - self.maplikeOrSetlikeOrIterable.maplikeOrSetlikeOrIterableType), - [self.maplikeOrSetlikeOrIterable.location, - member.location]) + raise WebIDLError( + "%s declaration used on " + "interface that already has %s " + "declaration" + % ( + member.maplikeOrSetlikeOrIterableType, + self.maplikeOrSetlikeOrIterable.maplikeOrSetlikeOrIterableType, + ), + [self.maplikeOrSetlikeOrIterable.location, member.location], + ) self.maplikeOrSetlikeOrIterable = member # If we've got a maplike or setlike declaration, we'll be building all of # our required methods in Codegen. Generate members now. - self.maplikeOrSetlikeOrIterable.expand(self.members, self.isJSImplemented()) + self.maplikeOrSetlikeOrIterable.expand(self.members) assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder) parent = self.parent.finish(scope) if self.parent else None if parent and isinstance(parent, IDLExternalInterface): - raise WebIDLError("%s inherits from %s which does not have " - "a definition" % - (self.identifier.name, - self.parent.identifier.name), - [self.location]) + raise WebIDLError( + "%s inherits from %s which does not have " + "a definition" % (self.identifier.name, self.parent.identifier.name), + [self.location], + ) if parent and not isinstance(parent, IDLInterface): - raise WebIDLError("%s inherits from %s which is not an interface " % - (self.identifier.name, - self.parent.identifier.name), - [self.location, parent.location]) + raise WebIDLError( + "%s inherits from %s which is not an interface " + % (self.identifier.name, self.parent.identifier.name), + [self.location, parent.location], + ) self.parent = parent @@ -993,9 +1105,10 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): for m in self.members: if m.isAttr() or m.isMethod(): if m.isStatic(): - raise WebIDLError("Don't mark things explicitly static " - "in namespaces", - [self.location, m.location]) + raise WebIDLError( + "Don't mark things explicitly static " "in namespaces", + [self.location, m.location], + ) # Just mark all our methods/attributes as static. The other # option is to duplicate the relevant InterfaceMembers # production bits but modified to produce static stuff to @@ -1013,55 +1126,63 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): # Note: This is not a self.parent.isOnGlobalProtoChain() check # because ancestors of a [Global] interface can have other # descendants. - raise WebIDLError("[Global] interface has another interface " - "inheriting from it", - [self.location, self.parent.location]) + raise WebIDLError( + "[Global] interface has another interface " "inheriting from it", + [self.location, self.parent.location], + ) # Make sure that we're not exposed in places where our parent is not if not self.exposureSet.issubset(self.parent.exposureSet): - raise WebIDLError("Interface %s is exposed in globals where its " - "parent interface %s is not exposed." % - (self.identifier.name, - self.parent.identifier.name), - [self.location, self.parent.location]) + raise WebIDLError( + "Interface %s is exposed in globals where its " + "parent interface %s is not exposed." + % (self.identifier.name, self.parent.identifier.name), + [self.location, self.parent.location], + ) # Callbacks must not inherit from non-callbacks. # XXXbz Can non-callbacks inherit from callbacks? Spec issue pending. if self.isCallback(): if not self.parent.isCallback(): - raise WebIDLError("Callback interface %s inheriting from " - "non-callback interface %s" % - (self.identifier.name, - self.parent.identifier.name), - [self.location, self.parent.location]) + raise WebIDLError( + "Callback interface %s inheriting from " + "non-callback interface %s" + % (self.identifier.name, self.parent.identifier.name), + [self.location, self.parent.location], + ) elif self.parent.isCallback(): - raise WebIDLError("Non-callback interface %s inheriting from " - "callback interface %s" % - (self.identifier.name, - self.parent.identifier.name), - [self.location, self.parent.location]) + raise WebIDLError( + "Non-callback interface %s inheriting from " + "callback interface %s" + % (self.identifier.name, self.parent.identifier.name), + [self.location, self.parent.location], + ) # Interfaces which have interface objects can't inherit - # from [NoInterfaceObject] interfaces. - if (self.parent.getExtendedAttribute("NoInterfaceObject") and - not self.getExtendedAttribute("NoInterfaceObject")): - raise WebIDLError("Interface %s does not have " - "[NoInterfaceObject] but inherits from " - "interface %s which does" % - (self.identifier.name, - self.parent.identifier.name), - [self.location, self.parent.location]) + # from [LegacyNoInterfaceObject] interfaces. + if self.parent.getExtendedAttribute( + "LegacyNoInterfaceObject" + ) and not self.getExtendedAttribute("LegacyNoInterfaceObject"): + raise WebIDLError( + "Interface %s does not have " + "[LegacyNoInterfaceObject] but inherits from " + "interface %s which does" + % (self.identifier.name, self.parent.identifier.name), + [self.location, self.parent.location], + ) # Interfaces that are not [SecureContext] can't inherit # from [SecureContext] interfaces. - if (self.parent.getExtendedAttribute("SecureContext") and - not self.getExtendedAttribute("SecureContext")): - raise WebIDLError("Interface %s does not have " - "[SecureContext] but inherits from " - "interface %s which does" % - (self.identifier.name, - self.parent.identifier.name), - [self.location, self.parent.location]) + if self.parent.getExtendedAttribute( + "SecureContext" + ) and not self.getExtendedAttribute("SecureContext"): + raise WebIDLError( + "Interface %s does not have " + "[SecureContext] but inherits from " + "interface %s which does" + % (self.identifier.name, self.parent.identifier.name), + [self.location, self.parent.location], + ) for mixin in self.includedMixins: mixin.finish(scope) @@ -1070,7 +1191,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): if cycleInGraph: raise WebIDLError( "Interface %s has itself as ancestor" % self.identifier.name, - [self.location, cycleInGraph.location]) + [self.location, cycleInGraph.location], + ) self.finishMembers(scope) @@ -1078,25 +1200,28 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): if ctor is not None: if not self.hasInterfaceObject(): raise WebIDLError( - "Can't have both a constructor and [NoInterfaceObject]", - [self.location, ctor.location]) + "Can't have both a constructor and [LegacyNoInterfaceObject]", + [self.location, ctor.location], + ) if self.globalNames: raise WebIDLError( "Can't have both a constructor and [Global]", - [self.location, ctor.location]) + [self.location, ctor.location], + ) - assert(ctor._exposureGlobalNames == self._exposureGlobalNames) + assert ctor._exposureGlobalNames == self._exposureGlobalNames ctor._exposureGlobalNames.update(self._exposureGlobalNames) # Remove the constructor operation from our member list so # it doesn't get in the way later. self.members.remove(ctor) - for ctor in self.namedConstructors: + for ctor in self.legacyFactoryFunctions: if self.globalNames: raise WebIDLError( - "Can't have both a named constructor and [Global]", - [self.location, ctor.location]) + "Can't have both a legacy factory function and [Global]", + [self.location, ctor.location], + ) assert len(ctor._exposureGlobalNames) == 0 ctor._exposureGlobalNames.update(self._exposureGlobalNames) ctor.finish(scope) @@ -1106,67 +1231,84 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): # admixed. self.originalMembers = list(self.members) - for mixin in sorted(self.includedMixins, - key=lambda x: x.identifier.name): + for mixin in sorted(self.includedMixins, key=lambda x: x.identifier.name): for mixinMember in mixin.members: for member in self.members: if mixinMember.identifier.name == member.identifier.name: raise WebIDLError( - "Multiple definitions of %s on %s coming from 'includes' statements" % - (member.identifier.name, self), - [mixinMember.location, member.location]) + "Multiple definitions of %s on %s coming from 'includes' statements" + % (member.identifier.name, self), + [mixinMember.location, member.location], + ) self.members.extend(mixin.members) for ancestor in self.getInheritedInterfaces(): ancestor.interfacesBasedOnSelf.add(self) - if (ancestor.maplikeOrSetlikeOrIterable is not None and - self.maplikeOrSetlikeOrIterable is not None): - raise WebIDLError("Cannot have maplike/setlike on %s that " - "inherits %s, which is already " - "maplike/setlike" % - (self.identifier.name, - ancestor.identifier.name), - [self.maplikeOrSetlikeOrIterable.location, - ancestor.maplikeOrSetlikeOrIterable.location]) - - # Deal with interfaces marked [Unforgeable], now that we have our full + if ( + ancestor.maplikeOrSetlikeOrIterable is not None + and self.maplikeOrSetlikeOrIterable is not None + ): + raise WebIDLError( + "Cannot have maplike/setlike on %s that " + "inherits %s, which is already " + "maplike/setlike" + % (self.identifier.name, ancestor.identifier.name), + [ + self.maplikeOrSetlikeOrIterable.location, + ancestor.maplikeOrSetlikeOrIterable.location, + ], + ) + + # Deal with interfaces marked [LegacyUnforgeable], now that we have our full # member list, except unforgeables pulled in from parents. We want to # do this before we set "originatingInterface" on our unforgeable # members. - if self.getExtendedAttribute("Unforgeable"): + if self.getExtendedAttribute("LegacyUnforgeable"): # Check that the interface already has all the things the # spec would otherwise require us to synthesize and is # missing the ones we plan to synthesize. if not any(m.isMethod() and m.isStringifier() for m in self.members): - raise WebIDLError("Unforgeable interface %s does not have a " - "stringifier" % self.identifier.name, - [self.location]) + raise WebIDLError( + "LegacyUnforgeable interface %s does not have a " + "stringifier" % self.identifier.name, + [self.location], + ) for m in self.members: if m.identifier.name == "toJSON": - raise WebIDLError("Unforgeable interface %s has a " - "toJSON so we won't be able to add " - "one ourselves" % self.identifier.name, - [self.location, m.location]) + raise WebIDLError( + "LegacyUnforgeable interface %s has a " + "toJSON so we won't be able to add " + "one ourselves" % self.identifier.name, + [self.location, m.location], + ) if m.identifier.name == "valueOf" and not m.isStatic(): - raise WebIDLError("Unforgeable interface %s has a valueOf " - "member so we won't be able to add one " - "ourselves" % self.identifier.name, - [self.location, m.location]) + raise WebIDLError( + "LegacyUnforgeable interface %s has a valueOf " + "member so we won't be able to add one " + "ourselves" % self.identifier.name, + [self.location, m.location], + ) for member in self.members: - if ((member.isAttr() or member.isMethod()) and - member.isUnforgeable() and - not hasattr(member, "originatingInterface")): + if ( + (member.isAttr() or member.isMethod()) + and member.isLegacyUnforgeable() + and not hasattr(member, "originatingInterface") + ): member.originatingInterface = self for member in self.members: - if ((member.isMethod() and - member.getExtendedAttribute("CrossOriginCallable")) or - (member.isAttr() and - (member.getExtendedAttribute("CrossOriginReadable") or - member.getExtendedAttribute("CrossOriginWritable")))): + if ( + member.isMethod() and member.getExtendedAttribute("CrossOriginCallable") + ) or ( + member.isAttr() + and ( + member.getExtendedAttribute("CrossOriginReadable") + or member.getExtendedAttribute("CrossOriginWritable") + ) + ): self.hasCrossOriginMembers = True break @@ -1180,16 +1322,21 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): # members from our parent. Also, maplike/setlike declarations get a # slot to hold their backing object. for member in self.members: - if ((member.isAttr() and - (member.getExtendedAttribute("StoreInSlot") or - member.getExtendedAttribute("Cached"))) or - member.isMaplikeOrSetlike()): + if ( + member.isAttr() + and ( + member.getExtendedAttribute("StoreInSlot") + or member.getExtendedAttribute("Cached") + or member.type.isObservableArray() + ) + ) or member.isMaplikeOrSetlike(): if self.isJSImplemented() and not member.isMaplikeOrSetlike(): - raise WebIDLError("Interface %s is JS-implemented and we " - "don't support [Cached] or [StoreInSlot] " - "on JS-implemented interfaces" % - self.identifier.name, - [self.location, member.location]) + raise WebIDLError( + "Interface %s is JS-implemented and we " + "don't support [Cached] or [StoreInSlot] or ObservableArray " + "on JS-implemented interfaces" % self.identifier.name, + [self.location, member.location], + ) if member.slotIndices is None: member.slotIndices = dict() member.slotIndices[self.identifier.name] = self.totalMembersInSlots @@ -1198,27 +1345,33 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): self._ownMembersInSlots += 1 if self.parent: - # Make sure we don't shadow any of the [Unforgeable] attributes on our + # Make sure we don't shadow any of the [LegacyUnforgeable] attributes on our # ancestor interfaces. We don't have to worry about mixins here, because # those have already been imported into the relevant .members lists. And # we don't have to worry about anything other than our parent, because it # has already imported its ancestors' unforgeable attributes into its # member list. - for unforgeableMember in (member for member in self.parent.members if - (member.isAttr() or member.isMethod()) and - member.isUnforgeable()): - shadows = [m for m in self.members if - (m.isAttr() or m.isMethod()) and - not m.isStatic() and - m.identifier.name == unforgeableMember.identifier.name] + for unforgeableMember in ( + member + for member in self.parent.members + if (member.isAttr() or member.isMethod()) + and member.isLegacyUnforgeable() + ): + shadows = [ + m + for m in self.members + if (m.isAttr() or m.isMethod()) + and not m.isStatic() + and m.identifier.name == unforgeableMember.identifier.name + ] if len(shadows) != 0: - locs = [unforgeableMember.location] + [s.location for s - in shadows] - raise WebIDLError("Interface %s shadows [Unforgeable] " - "members of %s" % - (self.identifier.name, - ancestor.identifier.name), - locs) + locs = [unforgeableMember.location] + [s.location for s in shadows] + raise WebIDLError( + "Interface %s shadows [LegacyUnforgeable] " + "members of %s" + % (self.identifier.name, ancestor.identifier.name), + locs, + ) # And now just stick it in our members, since we won't be # inheriting this down the proto chain. If we really cared we # could try to do something where we set up the unforgeable @@ -1234,8 +1387,9 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): testInterface = self isAncestor = False while testInterface: - self.maplikeOrSetlikeOrIterable.checkCollisions(testInterface.members, - isAncestor) + self.maplikeOrSetlikeOrIterable.checkCollisions( + testInterface.members, isAncestor + ) isAncestor = True testInterface = testInterface.parent @@ -1265,7 +1419,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): else: continue - if (memberType != "stringifiers" and memberType != "legacycallers"): + if memberType != "stringifiers" and memberType != "legacycallers": if member.isNamed(): memberType = "named " + memberType else: @@ -1273,10 +1427,14 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): memberType = "indexed " + memberType if memberType in specialMembersSeen: - raise WebIDLError("Multiple " + memberType + " on %s" % (self), - [self.location, - specialMembersSeen[memberType].location, - member.location]) + raise WebIDLError( + "Multiple " + memberType + " on %s" % (self), + [ + self.location, + specialMembersSeen[memberType].location, + member.location, + ], + ) specialMembersSeen[memberType] = member @@ -1286,7 +1444,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): raise WebIDLError( "Interface with [LegacyUnenumerableNamedProperties] does " "not have a named getter", - [self.location]) + [self.location], + ) ancestor = self.parent while ancestor: if ancestor.getExtendedAttribute("LegacyUnenumerableNamedProperties"): @@ -1294,7 +1453,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): "Interface with [LegacyUnenumerableNamedProperties] " "inherits from another interface with " "[LegacyUnenumerableNamedProperties]", - [self.location, ancestor.location]) + [self.location, ancestor.location], + ) ancestor = ancestor.parent if self._isOnGlobalProtoChain: @@ -1302,56 +1462,63 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): for memberType in ["setter", "deleter"]: memberId = "named " + memberType + "s" if memberId in specialMembersSeen: - raise WebIDLError("Interface with [Global] has a named %s" % - memberType, - [self.location, - specialMembersSeen[memberId].location]) - # Make sure we're not [OverrideBuiltins] - if self.getExtendedAttribute("OverrideBuiltins"): - raise WebIDLError("Interface with [Global] also has " - "[OverrideBuiltins]", - [self.location]) + raise WebIDLError( + "Interface with [Global] has a named %s" % memberType, + [self.location, specialMembersSeen[memberId].location], + ) + # Make sure we're not [LegacyOverrideBuiltIns] + if self.getExtendedAttribute("LegacyOverrideBuiltIns"): + raise WebIDLError( + "Interface with [Global] also has " "[LegacyOverrideBuiltIns]", + [self.location], + ) # Mark all of our ancestors as being on the global's proto chain too parent = self.parent while parent: - # Must not inherit from an interface with [OverrideBuiltins] - if parent.getExtendedAttribute("OverrideBuiltins"): - raise WebIDLError("Interface with [Global] inherits from " - "interface with [OverrideBuiltins]", - [self.location, parent.location]) + # Must not inherit from an interface with [LegacyOverrideBuiltIns] + if parent.getExtendedAttribute("LegacyOverrideBuiltIns"): + raise WebIDLError( + "Interface with [Global] inherits from " + "interface with [LegacyOverrideBuiltIns]", + [self.location, parent.location], + ) parent._isOnGlobalProtoChain = True parent = parent.parent def validate(self): - def checkDuplicateNames(member, name, attributeName): for m in self.members: if m.identifier.name == name: - raise WebIDLError("[%s=%s] has same name as interface member" % - (attributeName, name), - [member.location, m.location]) + raise WebIDLError( + "[%s=%s] has same name as interface member" + % (attributeName, name), + [member.location, m.location], + ) if m.isMethod() and m != member and name in m.aliases: - raise WebIDLError("conflicting [%s=%s] definitions" % - (attributeName, name), - [member.location, m.location]) + raise WebIDLError( + "conflicting [%s=%s] definitions" % (attributeName, name), + [member.location, m.location], + ) if m.isAttr() and m != member and name in m.bindingAliases: - raise WebIDLError("conflicting [%s=%s] definitions" % - (attributeName, name), - [member.location, m.location]) + raise WebIDLError( + "conflicting [%s=%s] definitions" % (attributeName, name), + [member.location, m.location], + ) # We also don't support inheriting from unforgeable interfaces. - if self.getExtendedAttribute("Unforgeable") and self.hasChildInterfaces(): - locations = ([self.location] + - list(i.location for i in - self.interfacesBasedOnSelf if i.parent == self)) - raise WebIDLError("%s is an unforgeable ancestor interface" % - self.identifier.name, - locations) + if self.getExtendedAttribute("LegacyUnforgeable") and self.hasChildInterfaces(): + locations = [self.location] + list( + i.location for i in self.interfacesBasedOnSelf if i.parent == self + ) + raise WebIDLError( + "%s is an unforgeable ancestor interface" % self.identifier.name, + locations, + ) ctor = self.ctor() if ctor is not None: ctor.validate() - for namedCtor in self.namedConstructors: + for namedCtor in self.legacyFactoryFunctions: namedCtor.validate() indexedGetter = None @@ -1360,50 +1527,57 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): member.validate() if self.isCallback() and member.getExtendedAttribute("Replaceable"): - raise WebIDLError("[Replaceable] used on an attribute on " - "interface %s which is a callback interface" % - self.identifier.name, - [self.location, member.location]) + raise WebIDLError( + "[Replaceable] used on an attribute on " + "interface %s which is a callback interface" % self.identifier.name, + [self.location, member.location], + ) # Check that PutForwards refers to another attribute and that no # cycles exist in forwarded assignments. Also check for a # integer-typed "length" attribute. if member.isAttr(): - if (member.identifier.name == "length" and - member.type.isInteger()): + if member.identifier.name == "length" and member.type.isInteger(): hasLengthAttribute = True iface = self attr = member putForwards = attr.getExtendedAttribute("PutForwards") if putForwards and self.isCallback(): - raise WebIDLError("[PutForwards] used on an attribute " - "on interface %s which is a callback " - "interface" % self.identifier.name, - [self.location, member.location]) + raise WebIDLError( + "[PutForwards] used on an attribute " + "on interface %s which is a callback " + "interface" % self.identifier.name, + [self.location, member.location], + ) while putForwards is not None: forwardIface = attr.type.unroll().inner fowardAttr = None for forwardedMember in forwardIface.members: - if (not forwardedMember.isAttr() or - forwardedMember.identifier.name != putForwards[0]): + if ( + not forwardedMember.isAttr() + or forwardedMember.identifier.name != putForwards[0] + ): continue if forwardedMember == member: - raise WebIDLError("Cycle detected in forwarded " - "assignments for attribute %s on " - "%s" % - (member.identifier.name, self), - [member.location]) + raise WebIDLError( + "Cycle detected in forwarded " + "assignments for attribute %s on " + "%s" % (member.identifier.name, self), + [member.location], + ) fowardAttr = forwardedMember break if fowardAttr is None: - raise WebIDLError("Attribute %s on %s forwards to " - "missing attribute %s" % - (attr.identifier.name, iface, putForwards), - [attr.location]) + raise WebIDLError( + "Attribute %s on %s forwards to " + "missing attribute %s" + % (attr.identifier.name, iface, putForwards), + [attr.location], + ) iface = forwardIface attr = fowardAttr @@ -1417,29 +1591,41 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): for alias in member.aliases: if self.isOnGlobalProtoChain(): - raise WebIDLError("[Alias] must not be used on a " - "[Global] interface operation", - [member.location]) - if (member.getExtendedAttribute("Exposed") or - member.getExtendedAttribute("ChromeOnly") or - member.getExtendedAttribute("Pref") or - member.getExtendedAttribute("Func") or - member.getExtendedAttribute("SecureContext")): - raise WebIDLError("[Alias] must not be used on a " - "conditionally exposed operation", - [member.location]) + raise WebIDLError( + "[Alias] must not be used on a " + "[Global] interface operation", + [member.location], + ) + if ( + member.getExtendedAttribute("Exposed") + or member.getExtendedAttribute("ChromeOnly") + or member.getExtendedAttribute("Pref") + or member.getExtendedAttribute("Func") + or member.getExtendedAttribute("Trial") + or member.getExtendedAttribute("SecureContext") + ): + raise WebIDLError( + "[Alias] must not be used on a " + "conditionally exposed operation", + [member.location], + ) if member.isStatic(): - raise WebIDLError("[Alias] must not be used on a " - "static operation", - [member.location]) + raise WebIDLError( + "[Alias] must not be used on a " "static operation", + [member.location], + ) if member.isIdentifierLess(): - raise WebIDLError("[Alias] must not be used on an " - "identifierless operation", - [member.location]) - if member.isUnforgeable(): - raise WebIDLError("[Alias] must not be used on an " - "[Unforgeable] operation", - [member.location]) + raise WebIDLError( + "[Alias] must not be used on an " + "identifierless operation", + [member.location], + ) + if member.isLegacyUnforgeable(): + raise WebIDLError( + "[Alias] must not be used on an " + "[LegacyUnforgeable] operation", + [member.location], + ) checkDuplicateNames(member, alias, "Alias") @@ -1449,16 +1635,18 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): for bindingAlias in member.bindingAliases: checkDuplicateNames(member, bindingAlias, "BindingAlias") - # Conditional exposure makes no sense for interfaces with no # interface object. # And SecureContext makes sense for interfaces with no interface object, # since it is also propagated to interface members. - if (self.isExposedConditionally(exclusions=["SecureContext"]) and - not self.hasInterfaceObject()): - raise WebIDLError("Interface with no interface object is " - "exposed conditionally", - [self.location]) + if ( + self.isExposedConditionally(exclusions=["SecureContext"]) + and not self.hasInterfaceObject() + ): + raise WebIDLError( + "Interface with no interface object is " "exposed conditionally", + [self.location], + ) # Value iterators are only allowed on interfaces with indexed getters, # and pair iterators are only allowed on interfaces without indexed @@ -1467,32 +1655,38 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): iterableDecl = self.maplikeOrSetlikeOrIterable if iterableDecl.isValueIterator(): if not indexedGetter: - raise WebIDLError("Interface with value iterator does not " - "support indexed properties", - [self.location, iterableDecl.location]) + raise WebIDLError( + "Interface with value iterator does not " + "support indexed properties", + [self.location, iterableDecl.location], + ) if iterableDecl.valueType != indexedGetter.signatures()[0][0]: - raise WebIDLError("Iterable type does not match indexed " - "getter type", - [iterableDecl.location, - indexedGetter.location]) + raise WebIDLError( + "Iterable type does not match indexed " "getter type", + [iterableDecl.location, indexedGetter.location], + ) if not hasLengthAttribute: - raise WebIDLError('Interface with value iterator does not ' - 'have an integer-typed "length" attribute', - [self.location, iterableDecl.location]) + raise WebIDLError( + "Interface with value iterator does not " + 'have an integer-typed "length" attribute', + [self.location, iterableDecl.location], + ) else: assert iterableDecl.isPairIterator() if indexedGetter: - raise WebIDLError("Interface with pair iterator supports " - "indexed properties", - [self.location, iterableDecl.location, - indexedGetter.location]) + raise WebIDLError( + "Interface with pair iterator supports " "indexed properties", + [self.location, iterableDecl.location, indexedGetter.location], + ) if indexedGetter and not hasLengthAttribute: - raise WebIDLError('Interface with an indexed getter does not have ' - 'an integer-typed "length" attribute', - [self.location, indexedGetter.location]) + raise WebIDLError( + "Interface with an indexed getter does not have " + 'an integer-typed "length" attribute', + [self.location, indexedGetter.location], + ) def setCallback(self, value): self._callback = value @@ -1505,15 +1699,25 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): return ( # JS-implemented things should never need the # this-handling weirdness of single-operation interfaces. - not self.isJSImplemented() and + not self.isJSImplemented() + and # Not inheriting from another interface - not self.parent and + not self.parent + and # No attributes of any kinds - not any(m.isAttr() for m in self.members) and + not any(m.isAttr() for m in self.members) + and # There is at least one regular operation, and all regular # operations have the same identifier - len(set(m.identifier.name for m in self.members if - m.isMethod() and not m.isStatic())) == 1) + len( + set( + m.identifier.name + for m in self.members + if m.isMethod() and not m.isStatic() + ) + ) + == 1 + ) def inheritanceDepth(self): depth = 0 @@ -1529,14 +1733,18 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): def hasInterfaceObject(self): if self.isCallback(): return self.hasConstants() - return not hasattr(self, "_noInterfaceObject") + return not hasattr(self, "_noInterfaceObject") and not self.isPseudoInterface() def hasInterfacePrototypeObject(self): - return (not self.isCallback() and not self.isNamespace() - and self.getUserData('hasConcreteDescendant', False)) + return ( + not self.isCallback() + and not self.isNamespace() + and self.getUserData("hasConcreteDescendant", False) + and not self.isPseudoInterface() + ) def addIncludedMixin(self, includedMixin): - assert(isinstance(includedMixin, IDLInterfaceMixin)) + assert isinstance(includedMixin, IDLInterfaceMixin) self.includedMixins.add(includedMixin) def getInheritedInterfaces(self): @@ -1545,7 +1753,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): (not including this interface itself). The list is in order from most derived to least derived. """ - assert(self._finished) + assert self._finished if not self.parent: return [] parentInterfaces = self.parent.getInheritedInterfaces() @@ -1596,6 +1804,9 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): def isOnGlobalProtoChain(self): return self._isOnGlobalProtoChain + def isPseudoInterface(self): + return self._isPseudo + def _getDependentObjects(self): deps = set(self.members) deps.update(self.includedMixins) @@ -1606,18 +1817,35 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): def hasMembersInSlots(self): return self._ownMembersInSlots != 0 - conditionExtendedAttributes = [ "Pref", "ChromeOnly", "Func", - "SecureContext" ] + conditionExtendedAttributes = [ + "Pref", + "ChromeOnly", + "Func", + "Trial", + "SecureContext", + ] + def isExposedConditionally(self, exclusions=[]): - return any(((not a in exclusions) and self.getExtendedAttribute(a)) for a in self.conditionExtendedAttributes) + return any( + ((not a in exclusions) and self.getExtendedAttribute(a)) + for a in self.conditionExtendedAttributes + ) + class IDLInterface(IDLInterfaceOrNamespace): - def __init__(self, location, parentScope, name, parent, members, - isKnownNonPartial, classNameOverride=None, - toStringTag=None): - IDLInterfaceOrNamespace.__init__(self, location, parentScope, name, - parent, members, isKnownNonPartial, - toStringTag) + def __init__( + self, + location, + parentScope, + name, + parent, + members, + isKnownNonPartial, + classNameOverride=None, + ): + IDLInterfaceOrNamespace.__init__( + self, location, parentScope, name, parent, members, isKnownNonPartial + ) self.classNameOverride = classNameOverride def __str__(self): @@ -1629,7 +1857,7 @@ class IDLInterface(IDLInterfaceOrNamespace): def getClassName(self): if self.classNameOverride: return self.classNameOverride - return self.identifier.name + return IDLInterfaceOrNamespace.getClassName(self) def addExtendedAttributes(self, attrs): for attr in attrs: @@ -1637,22 +1865,29 @@ class IDLInterface(IDLInterfaceOrNamespace): # Special cased attrs if identifier == "TreatNonCallableAsNull": - raise WebIDLError("TreatNonCallableAsNull cannot be specified on interfaces", - [attr.location, self.location]) - if identifier == "TreatNonObjectAsNull": - raise WebIDLError("TreatNonObjectAsNull cannot be specified on interfaces", - [attr.location, self.location]) - elif identifier == "NoInterfaceObject": + raise WebIDLError( + "TreatNonCallableAsNull cannot be specified on interfaces", + [attr.location, self.location], + ) + if identifier == "LegacyTreatNonObjectAsNull": + raise WebIDLError( + "LegacyTreatNonObjectAsNull cannot be specified on interfaces", + [attr.location, self.location], + ) + elif identifier == "LegacyNoInterfaceObject": if not attr.noArguments(): - raise WebIDLError("[NoInterfaceObject] must take no arguments", - [attr.location]) + raise WebIDLError( + "[LegacyNoInterfaceObject] must take no arguments", + [attr.location], + ) self._noInterfaceObject = True - elif identifier == "NamedConstructor": + elif identifier == "LegacyFactoryFunction": if not attr.hasValue(): - raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list", - [attr.location]) - + raise WebIDLError( + "LegacyFactoryFunction must either take an identifier or take a named argument list", + [attr.location], + ) args = attr.args() if attr.hasArgs() else [] @@ -1664,37 +1899,43 @@ class IDLInterface(IDLInterfaceOrNamespace): # Named constructors are always assumed to be able to # throw (since there's no way to indicate otherwise). method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("Throws",))]) + [IDLExtendedAttribute(self.location, ("Throws",))] + ) - # We need to detect conflicts for NamedConstructors across + # We need to detect conflicts for LegacyFactoryFunctions across # interfaces. We first call resolve on the parentScope, - # which will merge all NamedConstructors with the same + # which will merge all LegacyFactoryFunctions with the same # identifier accross interfaces as overloads. method.resolve(self.parentScope) # Then we look up the identifier on the parentScope. If the # result is the same as the method we're adding then it # hasn't been added as an overload and it's the first time - # we've encountered a NamedConstructor with that identifier. + # we've encountered a LegacyFactoryFunction with that identifier. # If the result is not the same as the method we're adding # then it has been added as an overload and we need to check # whether the result is actually one of our existing - # NamedConstructors. + # LegacyFactoryFunctions. newMethod = self.parentScope.lookupIdentifier(method.identifier) if newMethod == method: - self.namedConstructors.append(method) - elif newMethod not in self.namedConstructors: - raise WebIDLError("NamedConstructor conflicts with a " - "NamedConstructor of a different interface", - [method.location, newMethod.location]) - elif (identifier == "ExceptionClass"): + self.legacyFactoryFunctions.append(method) + elif newMethod not in self.legacyFactoryFunctions: + raise WebIDLError( + "LegacyFactoryFunction conflicts with a " + "LegacyFactoryFunction of a different interface", + [method.location, newMethod.location], + ) + elif identifier == "ExceptionClass": if not attr.noArguments(): - raise WebIDLError("[ExceptionClass] must take no arguments", - [attr.location]) + raise WebIDLError( + "[ExceptionClass] must take no arguments", [attr.location] + ) if self.parent: - raise WebIDLError("[ExceptionClass] must not be specified on " - "an interface with inherited interfaces", - [attr.location, self.location]) + raise WebIDLError( + "[ExceptionClass] must not be specified on " + "an interface with inherited interfaces", + [attr.location, self.location], + ) elif identifier == "Global": if attr.hasValue(): self.globalNames = [attr.value()] @@ -1702,8 +1943,9 @@ class IDLInterface(IDLInterfaceOrNamespace): self.globalNames = attr.args() else: self.globalNames = [self.identifier.name] - self.parentScope.addIfaceGlobalNames(self.identifier.name, - self.globalNames) + self.parentScope.addIfaceGlobalNames( + self.identifier.name, self.globalNames + ) self._isOnGlobalProtoChain = True elif identifier == "LegacyWindowAlias": if attr.hasValue(): @@ -1711,60 +1953,74 @@ class IDLInterface(IDLInterfaceOrNamespace): elif attr.hasArgs(): self.legacyWindowAliases = attr.args() else: - raise WebIDLError("[%s] must either take an identifier " - "or take an identifier list" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must either take an identifier " + "or take an identifier list" % identifier, + [attr.location], + ) for alias in self.legacyWindowAliases: unresolved = IDLUnresolvedIdentifier(attr.location, alias) IDLObjectWithIdentifier(attr.location, self.parentScope, unresolved) elif identifier == "SecureContext": if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) # This gets propagated to all our members. for member in self.members: if member.getExtendedAttribute("SecureContext"): - raise WebIDLError("[SecureContext] specified on both " - "an interface member and on the " - "interface itself", - [member.location, attr.location]) + raise WebIDLError( + "[SecureContext] specified on both " + "an interface member and on the " + "interface itself", + [member.location, attr.location], + ) member.addExtendedAttributes([attr]) - elif (identifier == "NeedResolve" or - identifier == "OverrideBuiltins" or - identifier == "ChromeOnly" or - identifier == "Unforgeable" or - identifier == "LegacyEventInit" or - identifier == "ProbablyShortLivingWrapper" or - identifier == "LegacyUnenumerableNamedProperties" or - identifier == "RunConstructorInCallerCompartment" or - identifier == "WantsEventListenerHooks" or - identifier == "Serializable" or - identifier == "Abstract" or - identifier == "Inline"): + elif ( + identifier == "NeedResolve" + or identifier == "LegacyOverrideBuiltIns" + or identifier == "ChromeOnly" + or identifier == "LegacyUnforgeable" + or identifier == "LegacyEventInit" + or identifier == "ProbablyShortLivingWrapper" + or identifier == "LegacyUnenumerableNamedProperties" + or identifier == "RunConstructorInCallerCompartment" + or identifier == "WantsEventListenerHooks" + or identifier == "Serializable" + or identifier == "Abstract" + or identifier == "Inline" + ): # Known extended attributes that do not take values if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) elif identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, - self._exposureGlobalNames) - elif (identifier == "Pref" or - identifier == "JSImplementation" or - identifier == "HeaderFile" or - identifier == "Func" or - identifier == "Deprecated"): + convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) + elif ( + identifier == "Pref" + or identifier == "JSImplementation" + or identifier == "HeaderFile" + or identifier == "Func" + or identifier == "Trial" + or identifier == "Deprecated" + ): # Known extended attributes that take a string value if not attr.hasValue(): - raise WebIDLError("[%s] must have a value" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must have a value" % identifier, [attr.location] + ) elif identifier == "InstrumentedProps": # Known extended attributes that take a list if not attr.hasArgs(): - raise WebIDLError("[%s] must have arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must have arguments" % identifier, [attr.location] + ) else: - raise WebIDLError("Unknown extended attribute %s on interface" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on interface" % identifier, + [attr.location], + ) attrlist = attr.listValue() self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True @@ -1777,7 +2033,8 @@ class IDLInterface(IDLInterfaceOrNamespace): "interface. Per spec, that means the object should not be " "serializable, so chances are someone made a mistake here " "somewhere.", - [self.location, self.parent.location]) + [self.location, self.parent.location], + ) def isSerializable(self): return self.getExtendedAttribute("Serializable") @@ -1796,9 +2053,9 @@ class IDLInterface(IDLInterfaceOrNamespace): class IDLNamespace(IDLInterfaceOrNamespace): def __init__(self, location, parentScope, name, members, isKnownNonPartial): - IDLInterfaceOrNamespace.__init__(self, location, parentScope, name, - None, members, isKnownNonPartial, - toStringTag=None) + IDLInterfaceOrNamespace.__init__( + self, location, parentScope, name, None, members, isKnownNonPartial + ) def __str__(self): return "Namespace '%s'" % self.identifier.name @@ -1815,30 +2072,35 @@ class IDLNamespace(IDLInterfaceOrNamespace): identifier = attr.identifier() if identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, - self._exposureGlobalNames) + convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) elif identifier == "ClassString": # Takes a string value to override the default "Object" if # desired. if not attr.hasValue(): - raise WebIDLError("[%s] must have a value" % identifier, - [attr.location]) - elif (identifier == "ProtoObjectHack" or - identifier == "ChromeOnly"): + raise WebIDLError( + "[%s] must have a value" % identifier, [attr.location] + ) + elif identifier == "ProtoObjectHack" or identifier == "ChromeOnly": if not attr.noArguments(): - raise WebIDLError("[%s] must not have arguments" % identifier, - [attr.location]) - elif (identifier == "Pref" or - identifier == "HeaderFile" or - identifier == "Func"): + raise WebIDLError( + "[%s] must not have arguments" % identifier, [attr.location] + ) + elif ( + identifier == "Pref" + or identifier == "HeaderFile" + or identifier == "Func" + or identifier == "Trial" + ): # Known extended attributes that take a string value if not attr.hasValue(): - raise WebIDLError("[%s] must have a value" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must have a value" % identifier, [attr.location] + ) else: - raise WebIDLError("Unknown extended attribute %s on namespace" % - identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on namespace" % identifier, + [attr.location], + ) attrlist = attr.listValue() self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True @@ -1874,8 +2136,9 @@ class IDLDictionary(IDLObjectWithScope): Returns true if this dictionary can be empty (that is, it has no required members and neither do any of its ancestors). """ - return (all(member.optional for member in self.members) and - (not self.parent or self.parent.canBeEmpty())) + return all(member.optional for member in self.members) and ( + not self.parent or self.parent.canBeEmpty() + ) def finish(self, scope): if self._finished: @@ -1888,9 +2151,11 @@ class IDLDictionary(IDLObjectWithScope): oldParent = self.parent self.parent = self.parent.finish(scope) if not isinstance(self.parent, IDLDictionary): - raise WebIDLError("Dictionary %s has parent that is not a dictionary" % - self.identifier.name, - [oldParent.location, self.parent.location]) + raise WebIDLError( + "Dictionary %s has parent that is not a dictionary" + % self.identifier.name, + [oldParent.location, self.parent.location], + ) # Make sure the parent resolves all its members before we start # looking at them. @@ -1907,16 +2172,19 @@ class IDLDictionary(IDLObjectWithScope): member.complete(scope) assert member.type.isComplete() - # Members of a dictionary are sorted in lexicographic order - self.members.sort(key=lambda x: x.identifier.name) + # Members of a dictionary are sorted in lexicographic order, + # unless the dictionary opts out. + if not self.getExtendedAttribute("Unsorted"): + self.members.sort(key=lambda x: x.identifier.name) inheritedMembers = [] ancestor = self.parent while ancestor: if ancestor == self: - raise WebIDLError("Dictionary %s has itself as an ancestor" % - self.identifier.name, - [self.identifier.location]) + raise WebIDLError( + "Dictionary %s has itself as an ancestor" % self.identifier.name, + [self.identifier.location], + ) inheritedMembers.extend(ancestor.members) ancestor = ancestor.parent @@ -1924,9 +2192,11 @@ class IDLDictionary(IDLObjectWithScope): for inheritedMember in inheritedMembers: for member in self.members: if member.identifier.name == inheritedMember.identifier.name: - raise WebIDLError("Dictionary %s has two members with name %s" % - (self.identifier.name, member.identifier.name), - [member.location, inheritedMember.location]) + raise WebIDLError( + "Dictionary %s has two members with name %s" + % (self.identifier.name, member.identifier.name), + [member.location, inheritedMember.location], + ) def validate(self): def typeContainsDictionary(memberType, dictionary): @@ -1944,17 +2214,20 @@ class IDLDictionary(IDLObjectWithScope): None, if the boolean value in the first element is False. """ - if (memberType.nullable() or - memberType.isSequence() or - memberType.isRecord()): + if ( + memberType.nullable() + or memberType.isSequence() + or memberType.isRecord() + ): return typeContainsDictionary(memberType.inner, dictionary) if memberType.isDictionary(): if memberType.inner == dictionary: return (True, [memberType.location]) - (contains, locations) = dictionaryContainsDictionary(memberType.inner, - dictionary) + (contains, locations) = dictionaryContainsDictionary( + memberType.inner, dictionary + ) if contains: return (True, [memberType.location] + locations) @@ -1976,7 +2249,9 @@ class IDLDictionary(IDLObjectWithScope): if dictMember.parent == dictionary: return (True, [dictMember.location]) else: - (contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary) + (contains, locations) = dictionaryContainsDictionary( + dictMember.parent, dictionary + ) if contains: return (True, [dictMember.location] + locations) @@ -1984,14 +2259,33 @@ class IDLDictionary(IDLObjectWithScope): for member in self.members: if member.type.isDictionary() and member.type.nullable(): - raise WebIDLError("Dictionary %s has member with nullable " - "dictionary type" % self.identifier.name, - [member.location]) + raise WebIDLError( + "Dictionary %s has member with nullable " + "dictionary type" % self.identifier.name, + [member.location], + ) (contains, locations) = typeContainsDictionary(member.type, self) if contains: - raise WebIDLError("Dictionary %s has member with itself as type." % - self.identifier.name, - [member.location] + locations) + raise WebIDLError( + "Dictionary %s has member with itself as type." + % self.identifier.name, + [member.location] + locations, + ) + + if member.type.isUndefined(): + raise WebIDLError( + "Dictionary %s has member with undefined as its type." + % self.identifier.name, + [member.location], + ) + elif member.type.isUnion(): + for unionMember in member.type.unroll().flatMemberTypes: + if unionMember.isUndefined(): + raise WebIDLError( + "Dictionary %s has member with a union containing " + "undefined as a type." % self.identifier.name, + [unionMember.location], + ) def getExtendedAttribute(self, name): return self._extendedAttrDict.get(name, None) @@ -2000,31 +2294,40 @@ class IDLDictionary(IDLObjectWithScope): for attr in attrs: identifier = attr.identifier() - if (identifier == "GenerateInitFromJSON" or - identifier == "GenerateInit"): + if identifier == "GenerateInitFromJSON" or identifier == "GenerateInit": if not attr.noArguments(): - raise WebIDLError("[%s] must not have arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must not have arguments" % identifier, [attr.location] + ) self.needsConversionFromJS = True - elif (identifier == "GenerateConversionToJS" or - identifier == "GenerateToJSON"): + elif ( + identifier == "GenerateConversionToJS" or identifier == "GenerateToJSON" + ): if not attr.noArguments(): - raise WebIDLError("[%s] must not have arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must not have arguments" % identifier, [attr.location] + ) # ToJSON methods require to-JS conversion, because we # implement ToJSON by converting to a JS object and # then using JSON.stringify. self.needsConversionToJS = True + elif identifier == "Unsorted": + if not attr.noArguments(): + raise WebIDLError( + "[Unsorted] must take no arguments", [attr.location] + ) else: - raise WebIDLError("[%s] extended attribute not allowed on " - "dictionaries" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] extended attribute not allowed on " + "dictionaries" % identifier, + [attr.location], + ) self._extendedAttrDict[identifier] = True def _getDependentObjects(self): deps = set(self.members) - if (self.parent): + if self.parent: deps.add(self.parent) return deps @@ -2039,8 +2342,9 @@ class IDLEnum(IDLObjectWithIdentifier): assert isinstance(name, IDLUnresolvedIdentifier) if len(values) != len(set(values)): - raise WebIDLError("Enum %s has multiple identical strings" % name.name, - [location]) + raise WebIDLError( + "Enum %s has multiple identical strings" % name.name, [location] + ) IDLObjectWithIdentifier.__init__(self, location, parentScope, name) self._values = values @@ -2059,9 +2363,10 @@ class IDLEnum(IDLObjectWithIdentifier): def addExtendedAttributes(self, attrs): if len(attrs) != 0: - raise WebIDLError("There are no extended attributes that are " - "allowed on enums", - [attrs[0].location, self.location]) + raise WebIDLError( + "There are no extended attributes that are " "allowed on enums", + [attrs[0].location, self.location], + ) def _getDependentObjects(self): return set() @@ -2070,56 +2375,72 @@ class IDLEnum(IDLObjectWithIdentifier): class IDLType(IDLObject): Tags = enum( # The integer types - 'int8', - 'uint8', - 'int16', - 'uint16', - 'int32', - 'uint32', - 'int64', - 'uint64', + "int8", + "uint8", + "int16", + "uint16", + "int32", + "uint32", + "int64", + "uint64", # Additional primitive types - 'bool', - 'unrestricted_float', - 'float', - 'unrestricted_double', + "bool", + "unrestricted_float", + "float", + "unrestricted_double", # "double" last primitive type to match IDLBuiltinType - 'double', + "double", # Other types - 'any', - 'domstring', - 'bytestring', - 'usvstring', - 'utf8string', - 'jsstring', - 'object', - 'undefined', + "any", + "undefined", + "domstring", + "bytestring", + "usvstring", + "utf8string", + "jsstring", + "object", # Funny stuff - 'interface', - 'dictionary', - 'enum', - 'callback', - 'union', - 'sequence', - 'record', - 'promise', - ) + "interface", + "dictionary", + "enum", + "callback", + "union", + "sequence", + "record", + "promise", + "observablearray", + ) def __init__(self, location, name): IDLObject.__init__(self, location) self.name = name self.builtin = False - self.treatNullAsEmpty = False + self.legacyNullToEmptyString = False self._clamp = False self._enforceRange = False self._allowShared = False self._extendedAttrDict = {} + def __hash__(self): + return ( + hash(self.builtin) + + hash(self.name) + + hash(self._clamp) + + hash(self._enforceRange) + + hash(self.legacyNullToEmptyString) + + hash(self._allowShared) + ) + def __eq__(self, other): - return (other and self.builtin == other.builtin and self.name == other.name and - self._clamp == other.hasClamp() and self._enforceRange == other.hasEnforceRange() and - self.treatNullAsEmpty == other.treatNullAsEmpty and - self._allowShared == other.hasAllowShared()) + return ( + other + and self.builtin == other.builtin + and self.name == other.name + and self._clamp == other.hasClamp() + and self._enforceRange == other.hasEnforceRange() + and self.legacyNullToEmptyString == other.legacyNullToEmptyString + and self._allowShared == other.hasAllowShared() + ) def __ne__(self, other): return not self == other @@ -2169,7 +2490,7 @@ class IDLType(IDLObject): return False def isUndefined(self): - return self.name == "Undefined" + return False def isSequence(self): return False @@ -2177,9 +2498,6 @@ class IDLType(IDLObject): def isRecord(self): return False - def isReadableStream(self): - return False - def isArrayBuffer(self): return False @@ -2199,23 +2517,16 @@ class IDLType(IDLObject): return False def isGeckoInterface(self): - """ Returns a boolean indicating whether this type is an 'interface' - type that is implemented in Gecko. At the moment, this returns - true for all interface types that are not types from the TypedArray - spec.""" + """Returns a boolean indicating whether this type is an 'interface' + type that is implemented in Gecko. At the moment, this returns + true for all interface types that are not types from the TypedArray + spec.""" return self.isInterface() and not self.isSpiderMonkeyInterface() def isSpiderMonkeyInterface(self): - """ Returns a boolean indicating whether this type is an 'interface' - type that is implemented in SpiderMonkey. """ - return self.isInterface() and (self.isBufferSource() or - self.isReadableStream()) - - def isDictionary(self): - return False - - def isInterface(self): - return False + """Returns a boolean indicating whether this type is an 'interface' + type that is implemented in SpiderMonkey.""" + return self.isInterface() and self.isBufferSource() def isAny(self): return self.tag() == IDLType.Tags.any @@ -2242,6 +2553,12 @@ class IDLType(IDLObject): def isJSONType(self): return False + def isObservableArray(self): + return False + + def isDictionaryLike(self): + return self.isDictionary() or self.isRecord() or self.isCallbackInterface() + def hasClamp(self): return self._clamp @@ -2264,8 +2581,10 @@ class IDLType(IDLObject): def withExtendedAttributes(self, attrs): if len(attrs) > 0: - raise WebIDLError("Extended attributes on types only supported for builtins", - [attrs[0].location, self.location]) + raise WebIDLError( + "Extended attributes on types only supported for builtins", + [attrs[0].location, self.location], + ) return self def getExtendedAttribute(self, name): @@ -2278,8 +2597,10 @@ class IDLType(IDLObject): return self def isDistinguishableFrom(self, other): - raise TypeError("Can't tell whether a generic type is or is not " - "distinguishable from other things") + raise TypeError( + "Can't tell whether a generic type is or is not " + "distinguishable from other things" + ) def isExposedInAllOf(self, exposureSet): return True @@ -2287,7 +2608,7 @@ class IDLType(IDLObject): class IDLUnresolvedType(IDLType): """ - Unresolved types are interface types + Unresolved types are interface types """ def __init__(self, location, name, attrs=[]): @@ -2302,19 +2623,17 @@ class IDLUnresolvedType(IDLType): try: obj = scope._lookupIdentifier(self.name) except: - raise WebIDLError("Unresolved type '%s'." % self.name, - [self.location]) + raise WebIDLError("Unresolved type '%s'." % self.name, [self.location]) assert obj - if obj.isType(): - print(obj) assert not obj.isType() if obj.isTypedef(): assert self.name.name == obj.identifier.name - typedefType = IDLTypedefType(self.location, obj.innerType, - obj.identifier) + typedefType = IDLTypedefType(self.location, obj.innerType, obj.identifier) assert not typedefType.isComplete() - return typedefType.complete(scope).withExtendedAttributes(self.extraTypeAttributes) + return typedefType.complete(scope).withExtendedAttributes( + self.extraTypeAttributes + ) elif obj.isCallback() and not obj.isInterface(): assert self.name.name == obj.identifier.name return IDLCallbackType(obj.location, obj) @@ -2326,8 +2645,10 @@ class IDLUnresolvedType(IDLType): return IDLUnresolvedType(self.location, self.name, attrs) def isDistinguishableFrom(self, other): - raise TypeError("Can't tell whether an unresolved type is or is not " - "distinguishable from other things") + raise TypeError( + "Can't tell whether an unresolved type is or is not " + "distinguishable from other things" + ) class IDLParametrizedType(IDLType): @@ -2355,17 +2676,16 @@ class IDLParametrizedType(IDLType): class IDLNullableType(IDLParametrizedType): def __init__(self, location, innerType): - assert not innerType.isUndefined() assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any] IDLParametrizedType.__init__(self, location, None, innerType) - def __eq__(self, other): - return isinstance(other, IDLNullableType) and self.inner == other.inner - def __hash__(self): return hash(self.inner) + def __eq__(self, other): + return isinstance(other, IDLNullableType) and self.inner == other.inner + def __str__(self): return self.inner.__str__() + "OrNull" @@ -2415,7 +2735,7 @@ class IDLNullableType(IDLParametrizedType): return self.inner.isInteger() def isUndefined(self): - return False + return self.inner.isUndefined() def isSequence(self): return self.inner.isSequence() @@ -2423,9 +2743,6 @@ class IDLNullableType(IDLParametrizedType): def isRecord(self): return self.inner.isRecord() - def isReadableStream(self): - return self.inner.isReadableStream() - def isArrayBuffer(self): return self.inner.isArrayBuffer() @@ -2461,6 +2778,9 @@ class IDLNullableType(IDLParametrizedType): def isJSONType(self): return self.inner.isJSONType() + def isObservableArray(self): + return self.inner.isObservableArray() + def hasClamp(self): return self.inner.hasClamp() @@ -2482,27 +2802,41 @@ class IDLNullableType(IDLParametrizedType): assert self.inner.isComplete() if self.inner.nullable(): - raise WebIDLError("The inner type of a nullable type must not be " - "a nullable type", - [self.location, self.inner.location]) + raise WebIDLError( + "The inner type of a nullable type must not be a nullable type", + [self.location, self.inner.location], + ) if self.inner.isUnion(): if self.inner.hasNullableType: - raise WebIDLError("The inner type of a nullable type must not " - "be a union type that itself has a nullable " - "type as a member type", [self.location]) + raise WebIDLError( + "The inner type of a nullable type must not " + "be a union type that itself has a nullable " + "type as a member type", + [self.location], + ) if self.inner.isDOMString(): - if self.inner.treatNullAsEmpty: - raise WebIDLError("[TreatNullAs] not allowed on a nullable DOMString", - [self.location, self.inner.location]) + if self.inner.legacyNullToEmptyString: + raise WebIDLError( + "[LegacyNullToEmptyString] not allowed on a nullable DOMString", + [self.location, self.inner.location], + ) + if self.inner.isObservableArray(): + raise WebIDLError( + "The inner type of a nullable type must not be an ObservableArray type", + [self.location, self.inner.location], + ) self.name = self.inner.name + "OrNull" return self def isDistinguishableFrom(self, other): - if (other.nullable() or - other.isDictionary() or - (other.isUnion() and - (other.hasNullableType or other.hasDictionaryType()))): + if ( + other.nullable() + or other.isDictionary() + or ( + other.isUnion() and (other.hasNullableType or other.hasDictionaryType()) + ) + ): # Can't tell which type null should become return False return self.inner.isDistinguishableFrom(other) @@ -2525,57 +2859,21 @@ class IDLSequenceType(IDLParametrizedType): if self.inner.isComplete(): self.name = self.inner.name + "Sequence" - def __eq__(self, other): - return isinstance(other, IDLSequenceType) and self.inner == other.inner - def __hash__(self): return hash(self.inner) + def __eq__(self, other): + return isinstance(other, IDLSequenceType) and self.inner == other.inner + def __str__(self): return self.inner.__str__() + "Sequence" def prettyName(self): return "sequence<%s>" % self.inner.prettyName() - def nullable(self): - return False - - def isPrimitive(self): - return False - - def isString(self): - return False - - def isByteString(self): - return False - - def isDOMString(self): - return False - - def isUSVString(self): - return False - - def isUTF8String(self): - return False - - def isJSString(self): - return False - - def isUndefined(self): - return False - def isSequence(self): return True - def isDictionary(self): - return False - - def isInterface(self): - return False - - def isEnum(self): - return False - def isJSONType(self): return self.inner.isJSONType() @@ -2583,6 +2881,12 @@ class IDLSequenceType(IDLParametrizedType): return IDLType.Tags.sequence def complete(self, scope): + if self.inner.isObservableArray(): + raise WebIDLError( + "The inner type of a sequence type must not be an ObservableArray type", + [self.location, self.inner.location], + ) + self.inner = self.inner.complete(scope) self.name = self.inner.name + "Sequence" return self @@ -2593,9 +2897,16 @@ class IDLSequenceType(IDLParametrizedType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) - return (other.isPrimitive() or other.isString() or other.isEnum() or - other.isInterface() or other.isDictionary() or - other.isCallback() or other.isRecord()) + return ( + other.isUndefined() + or other.isPrimitive() + or other.isString() + or other.isEnum() + or other.isInterface() + or other.isDictionary() + or other.isCallback() + or other.isRecord() + ) class IDLRecordType(IDLParametrizedType): @@ -2612,6 +2923,9 @@ class IDLRecordType(IDLParametrizedType): if self.inner.isComplete(): self.name = self.keyType.name + self.inner.name + "Record" + def __hash__(self): + return hash(self.inner) + def __eq__(self, other): return isinstance(other, IDLRecordType) and self.inner == other.inner @@ -2631,6 +2945,12 @@ class IDLRecordType(IDLParametrizedType): return IDLType.Tags.record def complete(self, scope): + if self.inner.isObservableArray(): + raise WebIDLError( + "The value type of a record type must not be an ObservableArray type", + [self.location, self.inner.location], + ) + self.inner = self.inner.complete(scope) self.name = self.keyType.name + self.inner.name + "Record" return self @@ -2647,13 +2967,84 @@ class IDLRecordType(IDLParametrizedType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) - return (other.isPrimitive() or other.isString() or other.isEnum() or - other.isNonCallbackInterface() or other.isSequence()) + return ( + other.isPrimitive() + or other.isString() + or other.isEnum() + or other.isNonCallbackInterface() + or other.isSequence() + ) def isExposedInAllOf(self, exposureSet): return self.inner.unroll().isExposedInAllOf(exposureSet) +class IDLObservableArrayType(IDLParametrizedType): + def __init__(self, location, innerType): + assert not innerType.isUndefined() + IDLParametrizedType.__init__(self, location, None, innerType) + + def __hash__(self): + return hash(self.inner) + + def __eq__(self, other): + return isinstance(other, IDLObservableArrayType) and self.inner == other.inner + + def __str__(self): + return self.inner.__str__() + "ObservableArray" + + def prettyName(self): + return "ObservableArray<%s>" % self.inner.prettyName() + + def isJSONType(self): + return self.inner.isJSONType() + + def isObservableArray(self): + return True + + def isComplete(self): + return self.name is not None + + def tag(self): + return IDLType.Tags.observablearray + + def complete(self, scope): + if not self.inner.isComplete(): + self.inner = self.inner.complete(scope) + assert self.inner.isComplete() + + if self.inner.isDictionary(): + raise WebIDLError( + "The inner type of an ObservableArray type must not " + "be a dictionary type", + [self.location, self.inner.location], + ) + if self.inner.isSequence(): + raise WebIDLError( + "The inner type of an ObservableArray type must not " + "be a sequence type", + [self.location, self.inner.location], + ) + if self.inner.isRecord(): + raise WebIDLError( + "The inner type of an ObservableArray type must not be a record type", + [self.location, self.inner.location], + ) + if self.inner.isObservableArray(): + raise WebIDLError( + "The inner type of an ObservableArray type must not " + "be an ObservableArray type", + [self.location, self.inner.location], + ) + + self.name = self.inner.name + "ObservableArray" + return self + + def isDistinguishableFrom(self, other): + # ObservableArrays are not distinguishable from anything. + return False + + class IDLUnionType(IDLType): def __init__(self, location, memberTypes): IDLType.__init__(self, location, "") @@ -2673,9 +3064,6 @@ class IDLUnionType(IDLType): def prettyName(self): return "(" + " or ".join(m.prettyName() for m in self.memberTypes) + ")" - def isUndefined(self): - return False - def isUnion(self): return True @@ -2727,36 +3115,46 @@ class IDLUnionType(IDLType): while i < len(self.flatMemberTypes): if self.flatMemberTypes[i].nullable(): if self.hasNullableType: - raise WebIDLError("Can't have more than one nullable types in a union", - [nullableType.location, self.flatMemberTypes[i].location]) + raise WebIDLError( + "Can't have more than one nullable types in a union", + [nullableType.location, self.flatMemberTypes[i].location], + ) if self.hasDictionaryType(): - raise WebIDLError("Can't have a nullable type and a " - "dictionary type in a union", - [self._dictionaryType.location, - self.flatMemberTypes[i].location]) + raise WebIDLError( + "Can't have a nullable type and a " + "dictionary type in a union", + [ + self._dictionaryType.location, + self.flatMemberTypes[i].location, + ], + ) self.hasNullableType = True nullableType = self.flatMemberTypes[i] self.flatMemberTypes[i] = self.flatMemberTypes[i].inner continue if self.flatMemberTypes[i].isDictionary(): if self.hasNullableType: - raise WebIDLError("Can't have a nullable type and a " - "dictionary type in a union", - [nullableType.location, - self.flatMemberTypes[i].location]) + raise WebIDLError( + "Can't have a nullable type and a " + "dictionary type in a union", + [nullableType.location, self.flatMemberTypes[i].location], + ) self._dictionaryType = self.flatMemberTypes[i] + self.flatMemberTypes[i].inner.needsConversionFromJS = True elif self.flatMemberTypes[i].isUnion(): - self.flatMemberTypes[i:i + 1] = self.flatMemberTypes[i].memberTypes + self.flatMemberTypes[i : i + 1] = self.flatMemberTypes[i].memberTypes continue i += 1 for (i, t) in enumerate(self.flatMemberTypes[:-1]): - for u in self.flatMemberTypes[i + 1:]: + for u in self.flatMemberTypes[i + 1 :]: if not t.isDistinguishableFrom(u): - raise WebIDLError("Flat member types of a union should be " - "distinguishable, " + str(t) + " is not " - "distinguishable from " + str(u), - [self.location, t.location, u.location]) + raise WebIDLError( + "Flat member types of a union should be " + "distinguishable, " + str(t) + " is not " + "distinguishable from " + str(u), + [self.location, t.location, u.location], + ) return self @@ -2778,8 +3176,10 @@ class IDLUnionType(IDLType): def isExposedInAllOf(self, exposureSet): # We could have different member types in different globals. Just make sure that each thing in exposureSet has one of our member types exposed in it. for globalName in exposureSet: - if not any(t.unroll().isExposedInAllOf(set([globalName])) for t - in self.flatMemberTypes): + if not any( + t.unroll().isExposedInAllOf(set([globalName])) + for t in self.flatMemberTypes + ): return False return True @@ -2787,8 +3187,9 @@ class IDLUnionType(IDLType): return self._dictionaryType is not None def hasPossiblyEmptyDictionaryType(self): - return (self._dictionaryType is not None and - self._dictionaryType.inner.canBeEmpty()) + return ( + self._dictionaryType is not None and self._dictionaryType.inner.canBeEmpty() + ) def _getDependentObjects(self): return set(self.memberTypes) @@ -2800,6 +3201,9 @@ class IDLTypedefType(IDLType): self.inner = innerType self.builtin = False + def __hash__(self): + return hash(self.inner) + def __eq__(self, other): return isinstance(other, IDLTypedefType) and self.inner == other.inner @@ -2848,9 +3252,6 @@ class IDLTypedefType(IDLType): def isRecord(self): return self.inner.isRecord() - def isReadableStream(self): - return self.inner.isReadableStream() - def isDictionary(self): return self.inner.isDictionary() @@ -2896,7 +3297,9 @@ class IDLTypedefType(IDLType): return self.inner._getDependentObjects() def withExtendedAttributes(self, attrs): - return IDLTypedefType(self.location, self.inner.withExtendedAttributes(attrs), self.name) + return IDLTypedefType( + self.location, self.inner.withExtendedAttributes(attrs), self.name + ) class IDLTypedef(IDLObjectWithIdentifier): @@ -2922,9 +3325,10 @@ class IDLTypedef(IDLObjectWithIdentifier): def addExtendedAttributes(self, attrs): if len(attrs) != 0: - raise WebIDLError("There are no extended attributes that are " - "allowed on typedefs", - [attrs[0].location, self.location]) + raise WebIDLError( + "There are no extended attributes that are " "allowed on typedefs", + [attrs[0].location, self.location], + ) def _getDependentObjects(self): return self.innerType._getDependentObjects() @@ -2937,53 +3341,26 @@ class IDLWrapperType(IDLType): self._identifier = inner.identifier self.builtin = False - def __eq__(self, other): - return (isinstance(other, IDLWrapperType) and - self._identifier == other._identifier and - self.builtin == other.builtin) - def __hash__(self): - return hash((self._identifier, self.builtin)) + return hash(self._identifier) + hash(self.builtin) + + def __eq__(self, other): + return ( + isinstance(other, IDLWrapperType) + and self._identifier == other._identifier + and self.builtin == other.builtin + ) def __str__(self): return str(self.name) + " (Wrapper)" - def nullable(self): - return False - - def isPrimitive(self): - return False - - def isString(self): - return False - - def isByteString(self): - return False - - def isDOMString(self): - return False - - def isUSVString(self): - return False - - def isUTF8String(self): - return False - - def isJSString(self): - return False - - def isUndefined(self): - return False - - def isSequence(self): - return False - def isDictionary(self): return isinstance(self.inner, IDLDictionary) def isInterface(self): - return (isinstance(self.inner, IDLInterface) or - isinstance(self.inner, IDLExternalInterface)) + return isinstance(self.inner, IDLInterface) or isinstance( + self.inner, IDLExternalInterface + ) def isCallbackInterface(self): return self.isInterface() and self.inner.isCallback() @@ -3014,8 +3391,11 @@ class IDLWrapperType(IDLType): dictionary = dictionary.parent return True else: - raise WebIDLError("IDLWrapperType wraps type %s that we don't know if " - "is serializable" % type(self.inner), [self.location]) + raise WebIDLError( + "IDLWrapperType wraps type %s that we don't know if " + "is serializable" % type(self.inner), + [self.location], + ) def resolveType(self, parentScope): assert isinstance(parentScope, IDLScope) @@ -3042,13 +3422,24 @@ class IDLWrapperType(IDLType): return other.isDistinguishableFrom(self) assert self.isInterface() or self.isEnum() or self.isDictionary() if self.isEnum(): - return (other.isPrimitive() or other.isInterface() or other.isObject() or - other.isCallback() or other.isDictionary() or - other.isSequence() or other.isRecord()) - if self.isDictionary() and other.nullable(): + return ( + other.isUndefined() + or other.isPrimitive() + or other.isInterface() + or other.isObject() + or other.isCallback() + or other.isDictionary() + or other.isSequence() + or other.isRecord() + ) + if self.isDictionary() and (other.nullable() or other.isUndefined()): return False - if (other.isPrimitive() or other.isString() or other.isEnum() or - other.isSequence()): + if ( + other.isPrimitive() + or other.isString() + or other.isEnum() + or other.isSequence() + ): return True if self.isDictionary(): return other.isNonCallbackInterface() @@ -3061,12 +3452,16 @@ class IDLWrapperType(IDLType): assert self.isGeckoInterface() and other.isGeckoInterface() if self.inner.isExternal() or other.unroll().inner.isExternal(): return self != other - return (len(self.inner.interfacesBasedOnSelf & - other.unroll().inner.interfacesBasedOnSelf) == 0 and - (self.isNonCallbackInterface() or - other.isNonCallbackInterface())) - if (other.isDictionary() or other.isCallback() or - other.isRecord()): + return len( + self.inner.interfacesBasedOnSelf + & other.unroll().inner.interfacesBasedOnSelf + ) == 0 and (self.isNonCallbackInterface() or other.isNonCallbackInterface()) + if ( + other.isUndefined() + or other.isDictionary() + or other.isCallback() + or other.isRecord() + ): return self.isNonCallbackInterface() # Not much else |other| can be @@ -3113,9 +3508,14 @@ class IDLPromiseType(IDLParametrizedType): def __init__(self, location, innerType): IDLParametrizedType.__init__(self, location, "Promise", innerType) + def __hash__(self): + return hash(self.promiseInnerType()) + def __eq__(self, other): - return (isinstance(other, IDLPromiseType) and - self.promiseInnerType() == other.promiseInnerType()) + return ( + isinstance(other, IDLPromiseType) + and self.promiseInnerType() == other.promiseInnerType() + ) def __str__(self): return self.inner.__str__() + "Promise" @@ -3133,6 +3533,12 @@ class IDLPromiseType(IDLParametrizedType): return IDLType.Tags.promise def complete(self, scope): + if self.inner.isObservableArray(): + raise WebIDLError( + "The inner type of a promise type must not be an ObservableArray type", + [self.location, self.inner.location], + ) + self.inner = self.promiseInnerType().complete(scope) return self @@ -3155,44 +3561,43 @@ class IDLBuiltinType(IDLType): Types = enum( # The integer types - 'byte', - 'octet', - 'short', - 'unsigned_short', - 'long', - 'unsigned_long', - 'long_long', - 'unsigned_long_long', + "byte", + "octet", + "short", + "unsigned_short", + "long", + "unsigned_long", + "long_long", + "unsigned_long_long", # Additional primitive types - 'boolean', - 'unrestricted_float', - 'float', - 'unrestricted_double', + "boolean", + "unrestricted_float", + "float", + "unrestricted_double", # IMPORTANT: "double" must be the last primitive type listed - 'double', + "double", # Other types - 'any', - 'domstring', - 'bytestring', - 'usvstring', - 'utf8string', - 'jsstring', - 'object', - 'undefined', + "any", + "undefined", + "domstring", + "bytestring", + "usvstring", + "utf8string", + "jsstring", + "object", # Funny stuff - 'ArrayBuffer', - 'ArrayBufferView', - 'Int8Array', - 'Uint8Array', - 'Uint8ClampedArray', - 'Int16Array', - 'Uint16Array', - 'Int32Array', - 'Uint32Array', - 'Float32Array', - 'Float64Array', - 'ReadableStream', - ) + "ArrayBuffer", + "ArrayBufferView", + "Int8Array", + "Uint8Array", + "Uint8ClampedArray", + "Int16Array", + "Uint16Array", + "Int32Array", + "Uint32Array", + "Float32Array", + "Float64Array", + ) TagLookup = { Types.byte: IDLType.Tags.int8, @@ -3209,13 +3614,13 @@ class IDLBuiltinType(IDLType): Types.unrestricted_double: IDLType.Tags.unrestricted_double, Types.double: IDLType.Tags.double, Types.any: IDLType.Tags.any, + Types.undefined: IDLType.Tags.undefined, Types.domstring: IDLType.Tags.domstring, Types.bytestring: IDLType.Tags.bytestring, Types.usvstring: IDLType.Tags.usvstring, Types.utf8string: IDLType.Tags.utf8string, Types.jsstring: IDLType.Tags.jsstring, Types.object: IDLType.Tags.object, - Types.undefined: IDLType.Tags.undefined, Types.ArrayBuffer: IDLType.Tags.interface, Types.ArrayBufferView: IDLType.Tags.interface, Types.Int8Array: IDLType.Tags.interface, @@ -3227,7 +3632,6 @@ class IDLBuiltinType(IDLType): Types.Uint32Array: IDLType.Tags.interface, Types.Float32Array: IDLType.Tags.interface, Types.Float64Array: IDLType.Tags.interface, - Types.ReadableStream: IDLType.Tags.interface, } PrettyNames = { @@ -3245,13 +3649,13 @@ class IDLBuiltinType(IDLType): Types.unrestricted_double: "unrestricted double", Types.double: "double", Types.any: "any", + Types.undefined: "undefined", Types.domstring: "DOMString", Types.bytestring: "ByteString", Types.usvstring: "USVString", - Types.utf8string: "USVString", # That's what it is in spec terms - Types.jsstring: "USVString", # Again, that's what it is in spec terms + Types.utf8string: "USVString", # That's what it is in spec terms + Types.jsstring: "USVString", # Again, that's what it is in spec terms Types.object: "object", - Types.undefined: "undefined", Types.ArrayBuffer: "ArrayBuffer", Types.ArrayBufferView: "ArrayBufferView", Types.Int8Array: "Int8Array", @@ -3263,15 +3667,23 @@ class IDLBuiltinType(IDLType): Types.Uint32Array: "Uint32Array", Types.Float32Array: "Float32Array", Types.Float64Array: "Float64Array", - Types.ReadableStream: "ReadableStream", } - def __init__(self, location, name, type, clamp=False, enforceRange=False, treatNullAsEmpty=False, - allowShared=False, attrLocation=[]): - """ - The mutually exclusive clamp/enforceRange/treatNullAsEmpty/allowShared arguments are used + def __init__( + self, + location, + name, + type, + clamp=False, + enforceRange=False, + legacyNullToEmptyString=False, + allowShared=False, + attrLocation=[], + ): + """ + The mutually exclusive clamp/enforceRange/legacyNullToEmptyString/allowShared arguments are used to create instances of this type with the appropriate attributes attached. Use .clamped(), - .rangeEnforced(), .withTreatNullAs() and .withAllowShared(). + .rangeEnforced(), .withLegacyNullToEmptyString() and .withAllowShared(). attrLocation is an array of source locations of these attributes for error reporting. """ @@ -3280,8 +3692,8 @@ class IDLBuiltinType(IDLType): self._typeTag = type self._clamped = None self._rangeEnforced = None - self._withTreatNullAs = None - self._withAllowShared = None; + self._withLegacyNullToEmptyString = None + self._withAllowShared = None if self.isInteger(): if clamp: self._clamp = True @@ -3292,20 +3704,27 @@ class IDLBuiltinType(IDLType): self.name = "RangeEnforced" + self.name self._extendedAttrDict["EnforceRange"] = True elif clamp or enforceRange: - raise WebIDLError("Non-integer types cannot be [Clamp] or [EnforceRange]", attrLocation) + raise WebIDLError( + "Non-integer types cannot be [Clamp] or [EnforceRange]", attrLocation + ) if self.isDOMString() or self.isUTF8String(): - if treatNullAsEmpty: - self.treatNullAsEmpty = True + if legacyNullToEmptyString: + self.legacyNullToEmptyString = True self.name = "NullIsEmpty" + self.name - self._extendedAttrDict["TreatNullAs"] = ["EmptyString"] - elif treatNullAsEmpty: - raise WebIDLError("Non-string types cannot be [TreatNullAs]", attrLocation) + self._extendedAttrDict["LegacyNullToEmptyString"] = True + elif legacyNullToEmptyString: + raise WebIDLError( + "Non-string types cannot be [LegacyNullToEmptyString]", attrLocation + ) if self.isBufferSource(): if allowShared: self._allowShared = True self._extendedAttrDict["AllowShared"] = True elif allowShared: - raise WebIDLError("Types that are not buffer source types cannot be [AllowShared]", attrLocation) + raise WebIDLError( + "Types that are not buffer source types cannot be [AllowShared]", + attrLocation, + ) def __str__(self): if self._allowShared: @@ -3313,41 +3732,51 @@ class IDLBuiltinType(IDLType): return "MaybeShared" + str(self.name) return str(self.name) - def __eq__(self, other): - return other and self.location == other.location and self.name == other.name and self._typeTag == other._typeTag - - def __hash__(self): - return hash((self.location, self.name, self._typeTag)) - def prettyName(self): return IDLBuiltinType.PrettyNames[self._typeTag] def clamped(self, attrLocation): if not self._clamped: - self._clamped = IDLBuiltinType(self.location, self.name, - self._typeTag, clamp=True, - attrLocation=attrLocation) + self._clamped = IDLBuiltinType( + self.location, + self.name, + self._typeTag, + clamp=True, + attrLocation=attrLocation, + ) return self._clamped def rangeEnforced(self, attrLocation): if not self._rangeEnforced: - self._rangeEnforced = IDLBuiltinType(self.location, self.name, - self._typeTag, enforceRange=True, - attrLocation=attrLocation) + self._rangeEnforced = IDLBuiltinType( + self.location, + self.name, + self._typeTag, + enforceRange=True, + attrLocation=attrLocation, + ) return self._rangeEnforced - def withTreatNullAs(self, attrLocation): - if not self._withTreatNullAs: - self._withTreatNullAs = IDLBuiltinType(self.location, self.name, - self._typeTag, treatNullAsEmpty=True, - attrLocation=attrLocation) - return self._withTreatNullAs + def withLegacyNullToEmptyString(self, attrLocation): + if not self._withLegacyNullToEmptyString: + self._withLegacyNullToEmptyString = IDLBuiltinType( + self.location, + self.name, + self._typeTag, + legacyNullToEmptyString=True, + attrLocation=attrLocation, + ) + return self._withLegacyNullToEmptyString def withAllowShared(self, attrLocation): if not self._withAllowShared: - self._withAllowShared = IDLBuiltinType(self.location, self.name, - self._typeTag, allowShared=True, - attrLocation=attrLocation) + self._withAllowShared = IDLBuiltinType( + self.location, + self.name, + self._typeTag, + allowShared=True, + attrLocation=attrLocation, + ) return self._withAllowShared def isPrimitive(self): @@ -3356,15 +3785,20 @@ class IDLBuiltinType(IDLType): def isBoolean(self): return self._typeTag == IDLBuiltinType.Types.boolean + def isUndefined(self): + return self._typeTag == IDLBuiltinType.Types.undefined + def isNumeric(self): return self.isPrimitive() and not self.isBoolean() def isString(self): - return (self._typeTag == IDLBuiltinType.Types.domstring or - self._typeTag == IDLBuiltinType.Types.bytestring or - self._typeTag == IDLBuiltinType.Types.usvstring or - self._typeTag == IDLBuiltinType.Types.utf8string or - self._typeTag == IDLBuiltinType.Types.jsstring) + return ( + self._typeTag == IDLBuiltinType.Types.domstring + or self._typeTag == IDLBuiltinType.Types.bytestring + or self._typeTag == IDLBuiltinType.Types.usvstring + or self._typeTag == IDLBuiltinType.Types.utf8string + or self._typeTag == IDLBuiltinType.Types.jsstring + ) def isByteString(self): return self._typeTag == IDLBuiltinType.Types.bytestring @@ -3391,35 +3825,35 @@ class IDLBuiltinType(IDLType): return self._typeTag == IDLBuiltinType.Types.ArrayBufferView def isTypedArray(self): - return (self._typeTag >= IDLBuiltinType.Types.Int8Array and - self._typeTag <= IDLBuiltinType.Types.Float64Array) - - def isReadableStream(self): - return self._typeTag == IDLBuiltinType.Types.ReadableStream + return ( + self._typeTag >= IDLBuiltinType.Types.Int8Array + and self._typeTag <= IDLBuiltinType.Types.Float64Array + ) def isInterface(self): # TypedArray things are interface types per the TypedArray spec, # but we handle them as builtins because SpiderMonkey implements # all of it internally. - return (self.isArrayBuffer() or - self.isArrayBufferView() or - self.isTypedArray() or - self.isReadableStream()) + return self.isArrayBuffer() or self.isArrayBufferView() or self.isTypedArray() def isNonCallbackInterface(self): # All the interfaces we can be are non-callback return self.isInterface() def isFloat(self): - return (self._typeTag == IDLBuiltinType.Types.float or - self._typeTag == IDLBuiltinType.Types.double or - self._typeTag == IDLBuiltinType.Types.unrestricted_float or - self._typeTag == IDLBuiltinType.Types.unrestricted_double) + return ( + self._typeTag == IDLBuiltinType.Types.float + or self._typeTag == IDLBuiltinType.Types.double + or self._typeTag == IDLBuiltinType.Types.unrestricted_float + or self._typeTag == IDLBuiltinType.Types.unrestricted_double + ) def isUnrestricted(self): assert self.isFloat() - return (self._typeTag == IDLBuiltinType.Types.unrestricted_float or - self._typeTag == IDLBuiltinType.Types.unrestricted_double) + return ( + self._typeTag == IDLBuiltinType.Types.unrestricted_float + or self._typeTag == IDLBuiltinType.Types.unrestricted_double + ) def isJSONType(self): return self.isPrimitive() or self.isString() or self.isObject() @@ -3436,48 +3870,84 @@ class IDLBuiltinType(IDLType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) - if self.isBoolean(): - return (other.isNumeric() or other.isString() or other.isEnum() or - other.isInterface() or other.isObject() or - other.isCallback() or other.isDictionary() or - other.isSequence() or other.isRecord()) - if self.isNumeric(): - return (other.isBoolean() or other.isString() or other.isEnum() or - other.isInterface() or other.isObject() or - other.isCallback() or other.isDictionary() or - other.isSequence() or other.isRecord()) + if self.isUndefined(): + return not (other.isUndefined() or other.isDictionaryLike()) + if self.isPrimitive(): + if ( + other.isUndefined() + or other.isString() + or other.isEnum() + or other.isInterface() + or other.isObject() + or other.isCallback() + or other.isDictionary() + or other.isSequence() + or other.isRecord() + ): + return True + if self.isBoolean(): + return other.isNumeric() + assert self.isNumeric() + return other.isBoolean() if self.isString(): - return (other.isPrimitive() or other.isInterface() or - other.isObject() or - other.isCallback() or other.isDictionary() or - other.isSequence() or other.isRecord()) + return ( + other.isUndefined() + or other.isPrimitive() + or other.isInterface() + or other.isObject() + or other.isCallback() + or other.isDictionary() + or other.isSequence() + or other.isRecord() + ) if self.isAny(): # Can't tell "any" apart from anything return False if self.isObject(): - return other.isPrimitive() or other.isString() or other.isEnum() - if self.isUndefined(): - return not other.isUndefined() + return ( + other.isUndefined() + or other.isPrimitive() + or other.isString() + or other.isEnum() + ) # Not much else we could be! assert self.isSpiderMonkeyInterface() # Like interfaces, but we know we're not a callback - return (other.isPrimitive() or other.isString() or other.isEnum() or - other.isCallback() or other.isDictionary() or - other.isSequence() or other.isRecord() or - (other.isInterface() and ( - # ArrayBuffer is distinguishable from everything - # that's not an ArrayBuffer or a callback interface - (self.isArrayBuffer() and not other.isArrayBuffer()) or - (self.isReadableStream() and not other.isReadableStream()) or - # ArrayBufferView is distinguishable from everything - # that's not an ArrayBufferView or typed array. - (self.isArrayBufferView() and not other.isArrayBufferView() and - not other.isTypedArray()) or - # Typed arrays are distinguishable from everything - # except ArrayBufferView and the same type of typed - # array - (self.isTypedArray() and not other.isArrayBufferView() and not - (other.isTypedArray() and other.name == self.name))))) + return ( + other.isUndefined() + or other.isPrimitive() + or other.isString() + or other.isEnum() + or other.isCallback() + or other.isDictionary() + or other.isSequence() + or other.isRecord() + or ( + other.isInterface() + and ( + # ArrayBuffer is distinguishable from everything + # that's not an ArrayBuffer or a callback interface + (self.isArrayBuffer() and not other.isArrayBuffer()) + or + # ArrayBufferView is distinguishable from everything + # that's not an ArrayBufferView or typed array. + ( + self.isArrayBufferView() + and not other.isArrayBufferView() + and not other.isTypedArray() + ) + or + # Typed arrays are distinguishable from everything + # except ArrayBufferView and the same type of typed + # array + ( + self.isTypedArray() + and not other.isArrayBufferView() + and not (other.isTypedArray() and other.name == self.name) + ) + ) + ) + ) def _getDependentObjects(self): return set() @@ -3488,177 +3958,213 @@ class IDLBuiltinType(IDLType): identifier = attribute.identifier() if identifier == "Clamp": if not attribute.noArguments(): - raise WebIDLError("[Clamp] must take no arguments", - [attribute.location]) + raise WebIDLError( + "[Clamp] must take no arguments", [attribute.location] + ) if ret.hasEnforceRange() or self._enforceRange: - raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive", - [self.location, attribute.location]) + raise WebIDLError( + "[EnforceRange] and [Clamp] are mutually exclusive", + [self.location, attribute.location], + ) ret = self.clamped([self.location, attribute.location]) elif identifier == "EnforceRange": if not attribute.noArguments(): - raise WebIDLError("[EnforceRange] must take no arguments", - [attribute.location]) + raise WebIDLError( + "[EnforceRange] must take no arguments", [attribute.location] + ) if ret.hasClamp() or self._clamp: - raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive", - [self.location, attribute.location]) + raise WebIDLError( + "[EnforceRange] and [Clamp] are mutually exclusive", + [self.location, attribute.location], + ) ret = self.rangeEnforced([self.location, attribute.location]) - elif identifier == "TreatNullAs": + elif identifier == "LegacyNullToEmptyString": if not (self.isDOMString() or self.isUTF8String()): - raise WebIDLError("[TreatNullAs] only allowed on DOMStrings and UTF8Strings", - [self.location, attribute.location]) + raise WebIDLError( + "[LegacyNullToEmptyString] only allowed on DOMStrings and UTF8Strings", + [self.location, attribute.location], + ) assert not self.nullable() - if not attribute.hasValue(): - raise WebIDLError("[TreatNullAs] must take an identifier argument", - [attribute.location]) - value = attribute.value() - if value != 'EmptyString': - raise WebIDLError("[TreatNullAs] must take the identifier " - "'EmptyString', not '%s'" % value, - [attribute.location]) - ret = self.withTreatNullAs([self.location, attribute.location]) + if attribute.hasValue(): + raise WebIDLError( + "[LegacyNullToEmptyString] must take no identifier argument", + [attribute.location], + ) + ret = self.withLegacyNullToEmptyString( + [self.location, attribute.location] + ) elif identifier == "AllowShared": if not attribute.noArguments(): - raise WebIDLError("[AllowShared] must take no arguments", - [attribute.location]) + raise WebIDLError( + "[AllowShared] must take no arguments", [attribute.location] + ) if not self.isBufferSource(): - raise WebIDLError("[AllowShared] only allowed on buffer source types", - [self.location, attribute.location]) + raise WebIDLError( + "[AllowShared] only allowed on buffer source types", + [self.location, attribute.location], + ) ret = self.withAllowShared([self.location, attribute.location]) else: - raise WebIDLError("Unhandled extended attribute on type", - [self.location, attribute.location]) + raise WebIDLError( + "Unhandled extended attribute on type", + [self.location, attribute.location], + ) return ret + BuiltinTypes = { - IDLBuiltinType.Types.byte: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte", - IDLBuiltinType.Types.byte), - IDLBuiltinType.Types.octet: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet", - IDLBuiltinType.Types.octet), - IDLBuiltinType.Types.short: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Short", - IDLBuiltinType.Types.short), - IDLBuiltinType.Types.unsigned_short: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedShort", - IDLBuiltinType.Types.unsigned_short), - IDLBuiltinType.Types.long: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Long", - IDLBuiltinType.Types.long), - IDLBuiltinType.Types.unsigned_long: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLong", - IDLBuiltinType.Types.unsigned_long), - IDLBuiltinType.Types.long_long: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "LongLong", - IDLBuiltinType.Types.long_long), - IDLBuiltinType.Types.unsigned_long_long: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLongLong", - IDLBuiltinType.Types.unsigned_long_long), - IDLBuiltinType.Types.boolean: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Boolean", - IDLBuiltinType.Types.boolean), - IDLBuiltinType.Types.float: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float", - IDLBuiltinType.Types.float), - IDLBuiltinType.Types.unrestricted_float: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedFloat", - IDLBuiltinType.Types.unrestricted_float), - IDLBuiltinType.Types.double: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Double", - IDLBuiltinType.Types.double), - IDLBuiltinType.Types.unrestricted_double: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedDouble", - IDLBuiltinType.Types.unrestricted_double), - IDLBuiltinType.Types.any: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Any", - IDLBuiltinType.Types.any), - IDLBuiltinType.Types.domstring: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "String", - IDLBuiltinType.Types.domstring), - IDLBuiltinType.Types.bytestring: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString", - IDLBuiltinType.Types.bytestring), - IDLBuiltinType.Types.usvstring: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "USVString", - IDLBuiltinType.Types.usvstring), - IDLBuiltinType.Types.utf8string: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "UTF8String", - IDLBuiltinType.Types.utf8string), - IDLBuiltinType.Types.jsstring: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "JSString", - IDLBuiltinType.Types.jsstring), - IDLBuiltinType.Types.object: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object", - IDLBuiltinType.Types.object), - IDLBuiltinType.Types.undefined: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Undefined", - IDLBuiltinType.Types.undefined), - IDLBuiltinType.Types.ArrayBuffer: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBuffer", - IDLBuiltinType.Types.ArrayBuffer), - IDLBuiltinType.Types.ArrayBufferView: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView", - IDLBuiltinType.Types.ArrayBufferView), - IDLBuiltinType.Types.Int8Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array", - IDLBuiltinType.Types.Int8Array), - IDLBuiltinType.Types.Uint8Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8Array", - IDLBuiltinType.Types.Uint8Array), - IDLBuiltinType.Types.Uint8ClampedArray: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8ClampedArray", - IDLBuiltinType.Types.Uint8ClampedArray), - IDLBuiltinType.Types.Int16Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int16Array", - IDLBuiltinType.Types.Int16Array), - IDLBuiltinType.Types.Uint16Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint16Array", - IDLBuiltinType.Types.Uint16Array), - IDLBuiltinType.Types.Int32Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int32Array", - IDLBuiltinType.Types.Int32Array), - IDLBuiltinType.Types.Uint32Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint32Array", - IDLBuiltinType.Types.Uint32Array), - IDLBuiltinType.Types.Float32Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float32Array", - IDLBuiltinType.Types.Float32Array), - IDLBuiltinType.Types.Float64Array: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array", - IDLBuiltinType.Types.Float64Array), - IDLBuiltinType.Types.ReadableStream: - IDLBuiltinType(BuiltinLocation("<builtin type>"), "ReadableStream", - IDLBuiltinType.Types.ReadableStream), + IDLBuiltinType.Types.byte: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Byte", IDLBuiltinType.Types.byte + ), + IDLBuiltinType.Types.octet: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Octet", IDLBuiltinType.Types.octet + ), + IDLBuiltinType.Types.short: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Short", IDLBuiltinType.Types.short + ), + IDLBuiltinType.Types.unsigned_short: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "UnsignedShort", + IDLBuiltinType.Types.unsigned_short, + ), + IDLBuiltinType.Types.long: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Long", IDLBuiltinType.Types.long + ), + IDLBuiltinType.Types.unsigned_long: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "UnsignedLong", + IDLBuiltinType.Types.unsigned_long, + ), + IDLBuiltinType.Types.long_long: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "LongLong", IDLBuiltinType.Types.long_long + ), + IDLBuiltinType.Types.unsigned_long_long: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "UnsignedLongLong", + IDLBuiltinType.Types.unsigned_long_long, + ), + IDLBuiltinType.Types.undefined: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Undefined", IDLBuiltinType.Types.undefined + ), + IDLBuiltinType.Types.boolean: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Boolean", IDLBuiltinType.Types.boolean + ), + IDLBuiltinType.Types.float: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Float", IDLBuiltinType.Types.float + ), + IDLBuiltinType.Types.unrestricted_float: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "UnrestrictedFloat", + IDLBuiltinType.Types.unrestricted_float, + ), + IDLBuiltinType.Types.double: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Double", IDLBuiltinType.Types.double + ), + IDLBuiltinType.Types.unrestricted_double: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "UnrestrictedDouble", + IDLBuiltinType.Types.unrestricted_double, + ), + IDLBuiltinType.Types.any: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Any", IDLBuiltinType.Types.any + ), + IDLBuiltinType.Types.domstring: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "String", IDLBuiltinType.Types.domstring + ), + IDLBuiltinType.Types.bytestring: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "ByteString", IDLBuiltinType.Types.bytestring + ), + IDLBuiltinType.Types.usvstring: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "USVString", IDLBuiltinType.Types.usvstring + ), + IDLBuiltinType.Types.utf8string: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "UTF8String", IDLBuiltinType.Types.utf8string + ), + IDLBuiltinType.Types.jsstring: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "JSString", IDLBuiltinType.Types.jsstring + ), + IDLBuiltinType.Types.object: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Object", IDLBuiltinType.Types.object + ), + IDLBuiltinType.Types.ArrayBuffer: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "ArrayBuffer", + IDLBuiltinType.Types.ArrayBuffer, + ), + IDLBuiltinType.Types.ArrayBufferView: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "ArrayBufferView", + IDLBuiltinType.Types.ArrayBufferView, + ), + IDLBuiltinType.Types.Int8Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Int8Array", IDLBuiltinType.Types.Int8Array + ), + IDLBuiltinType.Types.Uint8Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Uint8Array", IDLBuiltinType.Types.Uint8Array + ), + IDLBuiltinType.Types.Uint8ClampedArray: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "Uint8ClampedArray", + IDLBuiltinType.Types.Uint8ClampedArray, + ), + IDLBuiltinType.Types.Int16Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Int16Array", IDLBuiltinType.Types.Int16Array + ), + IDLBuiltinType.Types.Uint16Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "Uint16Array", + IDLBuiltinType.Types.Uint16Array, + ), + IDLBuiltinType.Types.Int32Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), "Int32Array", IDLBuiltinType.Types.Int32Array + ), + IDLBuiltinType.Types.Uint32Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "Uint32Array", + IDLBuiltinType.Types.Uint32Array, + ), + IDLBuiltinType.Types.Float32Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "Float32Array", + IDLBuiltinType.Types.Float32Array, + ), + IDLBuiltinType.Types.Float64Array: IDLBuiltinType( + BuiltinLocation("<builtin type>"), + "Float64Array", + IDLBuiltinType.Types.Float64Array, + ), } integerTypeSizes = { IDLBuiltinType.Types.byte: (-128, 127), - IDLBuiltinType.Types.octet: (0, 255), + IDLBuiltinType.Types.octet: (0, 255), IDLBuiltinType.Types.short: (-32768, 32767), IDLBuiltinType.Types.unsigned_short: (0, 65535), IDLBuiltinType.Types.long: (-2147483648, 2147483647), IDLBuiltinType.Types.unsigned_long: (0, 4294967295), IDLBuiltinType.Types.long_long: (-9223372036854775808, 9223372036854775807), - IDLBuiltinType.Types.unsigned_long_long: (0, 18446744073709551615) + IDLBuiltinType.Types.unsigned_long_long: (0, 18446744073709551615), } def matchIntegerValueToType(value): - for type, extremes in list(integerTypeSizes.items()): + for type, extremes in integerTypeSizes.items(): (min, max) = extremes if value <= max and value >= min: return BuiltinTypes[type] return None + class NoCoercionFoundError(WebIDLError): """ A class we use to indicate generic coercion failures because none of the types worked out in IDLValue.coerceToType. """ + class IDLValue(IDLObject): def __init__(self, location, type, value): IDLObject.__init__(self, location) @@ -3693,8 +4199,9 @@ class IDLValue(IDLObject): # non-WebIDLErrors here, because those can just happen if # "type" is not something that can have a default value at # all. - if (isinstance(e, WebIDLError) and - not isinstance(e, NoCoercionFoundError)): + if isinstance(e, WebIDLError) and not isinstance( + e, NoCoercionFoundError + ): raise e # If the type allows null, rerun this matching on the inner type, except @@ -3713,29 +4220,41 @@ class IDLValue(IDLObject): # Promote return IDLValue(self.location, type, self.value) else: - raise WebIDLError("Value %s is out of range for type %s." % - (self.value, type), [location]) + raise WebIDLError( + "Value %s is out of range for type %s." % (self.value, type), + [location], + ) elif self.type.isInteger() and type.isFloat(): # Convert an integer literal into float - if -2**24 <= self.value <= 2**24: + if -(2 ** 24) <= self.value <= 2 ** 24: return IDLValue(self.location, type, float(self.value)) else: - raise WebIDLError("Converting value %s to %s will lose precision." % - (self.value, type), [location]) + raise WebIDLError( + "Converting value %s to %s will lose precision." + % (self.value, type), + [location], + ) elif self.type.isString() and type.isEnum(): # Just keep our string, but make sure it's a valid value for this enum enum = type.unroll().inner - if self.value not in list(enum.values()): - raise WebIDLError("'%s' is not a valid default value for enum %s" - % (self.value, enum.identifier.name), - [location, enum.location]) + if self.value not in enum.values(): + raise WebIDLError( + "'%s' is not a valid default value for enum %s" + % (self.value, enum.identifier.name), + [location, enum.location], + ) return self elif self.type.isFloat() and type.isFloat(): - if (not type.isUnrestricted() and - (self.value == float("inf") or self.value == float("-inf") or - math.isnan(self.value))): - raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted" - % self.value, [location]) + if not type.isUnrestricted() and ( + self.value == float("inf") + or self.value == float("-inf") + or math.isnan(self.value) + ): + raise WebIDLError( + "Trying to convert unrestricted value %s to non-unrestricted" + % self.value, + [location], + ) return IDLValue(self.location, type, self.value) elif self.type.isString() and type.isUSVString(): # Allow USVStrings to use default value just like @@ -3744,27 +4263,35 @@ class IDLValue(IDLObject): # extra normalization step. assert self.type.isDOMString() return self - elif self.type.isDOMString() and type.treatNullAsEmpty: - # TreatNullAsEmpty is a different type for resolution reasons, - # however once you have a value it doesn't matter - return self - elif self.type.isString() and (type.isByteString() or type.isJSString() or type.isUTF8String()): + elif self.type.isString() and ( + type.isByteString() or type.isJSString() or type.isUTF8String() + ): # Allow ByteStrings, UTF8String, and JSStrings to use a default # value like DOMString. # No coercion is required as Codegen.py will handle the # extra steps. We want to make sure that our string contains # only valid characters, so we check that here. - valid_ascii_lit = " " + string.ascii_letters + string.digits + string.punctuation + valid_ascii_lit = ( + " " + string.ascii_letters + string.digits + string.punctuation + ) for idx, c in enumerate(self.value): if c not in valid_ascii_lit: - raise WebIDLError("Coercing this string literal %s to a ByteString is not supported yet. " - "Coercion failed due to an unsupported byte %d at index %d." - % (self.value.__repr__(), ord(c), idx), [location]) + raise WebIDLError( + "Coercing this string literal %s to a ByteString is not supported yet. " + "Coercion failed due to an unsupported byte %d at index %d." + % (self.value.__repr__(), ord(c), idx), + [location], + ) return IDLValue(self.location, type, self.value) + elif self.type.isDOMString() and type.legacyNullToEmptyString: + # LegacyNullToEmptyString is a different type for resolution reasons, + # however once you have a value it doesn't matter + return self - raise NoCoercionFoundError("Cannot coerce type %s to type %s." % - (self.type, type), [location]) + raise NoCoercionFoundError( + "Cannot coerce type %s to type %s." % (self.type, type), [location] + ) def _getDependentObjects(self): return set() @@ -3777,11 +4304,12 @@ class IDLNullValue(IDLObject): self.value = None def coerceToType(self, type, location): - if (not isinstance(type, IDLNullableType) and - not (type.isUnion() and type.hasNullableType) and - not type.isAny()): - raise WebIDLError("Cannot coerce null value to type %s." % type, - [location]) + if ( + not isinstance(type, IDLNullableType) + and not (type.isUnion() and type.hasNullableType) + and not type.isAny() + ): + raise WebIDLError("Cannot coerce null value to type %s." % type, [location]) nullValue = IDLNullValue(self.location) if type.isUnion() and not type.nullable() and type.hasDictionaryType(): @@ -3816,8 +4344,9 @@ class IDLEmptySequenceValue(IDLObject): pass if not type.isSequence(): - raise WebIDLError("Cannot coerce empty sequence value to type %s." % type, - [location]) + raise WebIDLError( + "Cannot coerce empty sequence value to type %s." % type, [location] + ) emptySequenceValue = IDLEmptySequenceValue(self.location) emptySequenceValue.type = type @@ -3845,8 +4374,9 @@ class IDLDefaultDictionaryValue(IDLObject): pass if not type.isDictionary(): - raise WebIDLError("Cannot coerce default dictionary value to type %s." % type, - [location]) + raise WebIDLError( + "Cannot coerce default dictionary value to type %s." % type, [location] + ) defaultDictionaryValue = IDLDefaultDictionaryValue(self.location) defaultDictionaryValue.type = type @@ -3864,8 +4394,9 @@ class IDLUndefinedValue(IDLObject): def coerceToType(self, type, location): if not type.isAny(): - raise WebIDLError("Cannot coerce undefined value to type %s." % type, - [location]) + raise WebIDLError( + "Cannot coerce undefined value to type %s." % type, [location] + ) undefinedValue = IDLUndefinedValue(self.location) undefinedValue.type = type @@ -3878,17 +4409,10 @@ class IDLUndefinedValue(IDLObject): class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): Tags = enum( - 'Const', - 'Attr', - 'Method', - 'MaplikeOrSetlike', - 'Iterable' + "Const", "Attr", "Method", "MaplikeOrSetlike", "AsyncIterable", "Iterable" ) - Special = enum( - 'Static', - 'Stringifier' - ) + Special = enum("Static", "Stringifier") AffectsValues = ("Nothing", "Everything") DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything") @@ -3912,8 +4436,11 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): return self.tag == IDLInterfaceMember.Tags.Const def isMaplikeOrSetlikeOrIterable(self): - return (self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike or - self.tag == IDLInterfaceMember.Tags.Iterable) + return ( + self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike + or self.tag == IDLInterfaceMember.Tags.AsyncIterable + or self.tag == IDLInterfaceMember.Tags.Iterable + ) def isMaplikeOrSetlike(self): return self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike @@ -3922,7 +4449,9 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): for attr in attrs: self.handleExtendedAttribute(attr) attrlist = attr.listValue() - self._extendedAttrDict[attr.identifier()] = attrlist if len(attrlist) else True + self._extendedAttrDict[attr.identifier()] = ( + attrlist if len(attrlist) else True + ) def handleExtendedAttribute(self, attr): pass @@ -3936,66 +4465,84 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): def validate(self): if self.isAttr() or self.isMethod(): if self.affects == "Everything" and self.dependsOn != "Everything": - raise WebIDLError("Interface member is flagged as affecting " - "everything but not depending on everything. " - "That seems rather unlikely.", - [self.location]) + raise WebIDLError( + "Interface member is flagged as affecting " + "everything but not depending on everything. " + "That seems rather unlikely.", + [self.location], + ) if self.getExtendedAttribute("NewObject"): if self.dependsOn == "Nothing" or self.dependsOn == "DOMState": - raise WebIDLError("A [NewObject] method is not idempotent, " - "so it has to depend on something other than DOM state.", - [self.location]) - if (self.getExtendedAttribute("Cached") or - self.getExtendedAttribute("StoreInSlot")): - raise WebIDLError("A [NewObject] attribute shouldnt be " - "[Cached] or [StoreInSlot], since the point " - "of those is to keep returning the same " - "thing across multiple calls, which is not " - "what [NewObject] does.", - [self.location]) + raise WebIDLError( + "A [NewObject] method is not idempotent, " + "so it has to depend on something other than DOM state.", + [self.location], + ) + if self.getExtendedAttribute("Cached") or self.getExtendedAttribute( + "StoreInSlot" + ): + raise WebIDLError( + "A [NewObject] attribute shouldnt be " + "[Cached] or [StoreInSlot], since the point " + "of those is to keep returning the same " + "thing across multiple calls, which is not " + "what [NewObject] does.", + [self.location], + ) def _setDependsOn(self, dependsOn): if self.dependsOn != "Everything": - raise WebIDLError("Trying to specify multiple different DependsOn, " - "Pure, or Constant extended attributes for " - "attribute", [self.location]) + raise WebIDLError( + "Trying to specify multiple different DependsOn, " + "Pure, or Constant extended attributes for " + "attribute", + [self.location], + ) if dependsOn not in IDLInterfaceMember.DependsOnValues: - raise WebIDLError("Invalid [DependsOn=%s] on attribute" % dependsOn, - [self.location]) + raise WebIDLError( + "Invalid [DependsOn=%s] on attribute" % dependsOn, [self.location] + ) self.dependsOn = dependsOn def _setAffects(self, affects): if self.affects != "Everything": - raise WebIDLError("Trying to specify multiple different Affects, " - "Pure, or Constant extended attributes for " - "attribute", [self.location]) + raise WebIDLError( + "Trying to specify multiple different Affects, " + "Pure, or Constant extended attributes for " + "attribute", + [self.location], + ) if affects not in IDLInterfaceMember.AffectsValues: - raise WebIDLError("Invalid [Affects=%s] on attribute" % dependsOn, - [self.location]) + raise WebIDLError( + "Invalid [Affects=%s] on attribute" % dependsOn, [self.location] + ) self.affects = affects def _addAlias(self, alias): if alias in self.aliases: - raise WebIDLError("Duplicate [Alias=%s] on attribute" % alias, - [self.location]) + raise WebIDLError( + "Duplicate [Alias=%s] on attribute" % alias, [self.location] + ) self.aliases.append(alias) def _addBindingAlias(self, bindingAlias): if bindingAlias in self.bindingAliases: - raise WebIDLError("Duplicate [BindingAlias=%s] on attribute" % bindingAlias, - [self.location]) + raise WebIDLError( + "Duplicate [BindingAlias=%s] on attribute" % bindingAlias, + [self.location], + ) self.bindingAliases.append(bindingAlias) -class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): +class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind): IDLInterfaceMember.__init__(self, location, identifier, ifaceKind) if keyType is not None: assert isinstance(keyType, IDLType) else: assert valueType is not None - assert ifaceType in ['maplike', 'setlike', 'iterable'] + assert ifaceType in ["maplike", "setlike", "iterable", "asynciterable"] if valueType is not None: assert isinstance(valueType, IDLType) self.keyType = keyType @@ -4013,6 +4560,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): def isIterable(self): return self.maplikeOrSetlikeOrIterableType == "iterable" + def isAsyncIterable(self): + return self.maplikeOrSetlikeOrIterableType == "asynciterable" + def hasKeyType(self): return self.keyType is not None @@ -4022,28 +4572,42 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): def checkCollisions(self, members, isAncestor): for member in members: # Check that there are no disallowed members - if (member.identifier.name in self.disallowedMemberNames and - not ((member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod()) or - (member.isAttr() and member.isMaplikeOrSetlikeAttr()))): - raise WebIDLError("Member '%s' conflicts " - "with reserved %s name." % - (member.identifier.name, - self.maplikeOrSetlikeOrIterableType), - [self.location, member.location]) + if member.identifier.name in self.disallowedMemberNames and not ( + (member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod()) + or (member.isAttr() and member.isMaplikeOrSetlikeAttr()) + ): + raise WebIDLError( + "Member '%s' conflicts " + "with reserved %s name." + % (member.identifier.name, self.maplikeOrSetlikeOrIterableType), + [self.location, member.location], + ) # Check that there are no disallowed non-method members. # Ancestor members are always disallowed here; own members # are disallowed only if they're non-methods. - if ((isAncestor or member.isAttr() or member.isConst()) and - member.identifier.name in self.disallowedNonMethodNames): - raise WebIDLError("Member '%s' conflicts " - "with reserved %s method." % - (member.identifier.name, - self.maplikeOrSetlikeOrIterableType), - [self.location, member.location]) - - def addMethod(self, name, members, allowExistingOperations, returnType, args=[], - chromeOnly=False, isPure=False, affectsNothing=False, newObject=False, - isIteratorAlias=False): + if ( + isAncestor or member.isAttr() or member.isConst() + ) and member.identifier.name in self.disallowedNonMethodNames: + raise WebIDLError( + "Member '%s' conflicts " + "with reserved %s method." + % (member.identifier.name, self.maplikeOrSetlikeOrIterableType), + [self.location, member.location], + ) + + def addMethod( + self, + name, + members, + allowExistingOperations, + returnType, + args=[], + chromeOnly=False, + isPure=False, + affectsNothing=False, + newObject=False, + isIteratorAlias=False, + ): """ Create an IDLMethod based on the parameters passed in. @@ -4082,35 +4646,47 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): for m in members: if m.identifier.name == name and m.isMethod() and not m.isStatic(): return - method = IDLMethod(self.location, - IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly), - returnType, args, maplikeOrSetlikeOrIterable=self) + method = IDLMethod( + self.location, + IDLUnresolvedIdentifier( + self.location, name, allowDoubleUnderscore=chromeOnly + ), + returnType, + args, + maplikeOrSetlikeOrIterable=self, + ) # We need to be able to throw from declaration methods - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("Throws",))]) + method.addExtendedAttributes([IDLExtendedAttribute(self.location, ("Throws",))]) if chromeOnly: method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("ChromeOnly",))]) + [IDLExtendedAttribute(self.location, ("ChromeOnly",))] + ) if isPure: method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("Pure",))]) + [IDLExtendedAttribute(self.location, ("Pure",))] + ) # Following attributes are used for keys/values/entries. Can't mark # them pure, since they return a new object each time they are run. if affectsNothing: method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("DependsOn", "Everything")), - IDLExtendedAttribute(self.location, ("Affects", "Nothing"))]) + [ + IDLExtendedAttribute(self.location, ("DependsOn", "Everything")), + IDLExtendedAttribute(self.location, ("Affects", "Nothing")), + ] + ) if newObject: method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("NewObject",))]) + [IDLExtendedAttribute(self.location, ("NewObject",))] + ) if isIteratorAlias: - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))]) - # Methods generated for iterables should be enumerable, but the ones for - # maplike/setlike should not be. - if not self.isIterable(): - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("NonEnumerable",))]) + if not self.isAsyncIterable(): + method.addExtendedAttributes( + [IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))] + ) + else: + method.addExtendedAttributes( + [IDLExtendedAttribute(self.location, ("Alias", "@@asyncIterator"))] + ) members.append(method) def resolve(self, parentScope): @@ -4151,30 +4727,47 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember): return deps def getForEachArguments(self): - return [IDLArgument(self.location, - IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), - "callback"), - BuiltinTypes[IDLBuiltinType.Types.object]), - IDLArgument(self.location, - IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), - "thisArg"), - BuiltinTypes[IDLBuiltinType.Types.any], - optional=True)] + return [ + IDLArgument( + self.location, + IDLUnresolvedIdentifier( + BuiltinLocation("<auto-generated-identifier>"), "callback" + ), + BuiltinTypes[IDLBuiltinType.Types.object], + ), + IDLArgument( + self.location, + IDLUnresolvedIdentifier( + BuiltinLocation("<auto-generated-identifier>"), "thisArg" + ), + BuiltinTypes[IDLBuiltinType.Types.any], + optional=True, + ), + ] + # Iterable adds ES6 iterator style functions and traits # (keys/values/entries/@@iterator) to an interface. class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase): - - def __init__(self, location, identifier, keyType, valueType=None, scope=None): - IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, - "iterable", keyType, valueType, - IDLInterfaceMember.Tags.Iterable) + def __init__(self, location, identifier, keyType, valueType, scope): + IDLMaplikeOrSetlikeOrIterableBase.__init__( + self, + location, + identifier, + "iterable", + keyType, + valueType, + IDLInterfaceMember.Tags.Iterable, + ) self.iteratorType = None def __str__(self): - return "declared iterable with key '%s' and value '%s'" % (self.keyType, self.valueType) + return "declared iterable with key '%s' and value '%s'" % ( + self.keyType, + self.valueType, + ) - def expand(self, members, isJSImplemented): + def expand(self, members): """ In order to take advantage of all of the method machinery in Codegen, we generate our functions as if they were part of the interface @@ -4186,20 +4779,125 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase): return # object entries() - self.addMethod("entries", members, False, self.iteratorType, - affectsNothing=True, newObject=True, - isIteratorAlias=True) + self.addMethod( + "entries", + members, + False, + self.iteratorType, + affectsNothing=True, + newObject=True, + isIteratorAlias=True, + ) # object keys() - self.addMethod("keys", members, False, self.iteratorType, - affectsNothing=True, newObject=True) + self.addMethod( + "keys", + members, + False, + self.iteratorType, + affectsNothing=True, + newObject=True, + ) # object values() - self.addMethod("values", members, False, self.iteratorType, - affectsNothing=True, newObject=True) + self.addMethod( + "values", + members, + False, + self.iteratorType, + affectsNothing=True, + newObject=True, + ) # undefined forEach(callback(valueType, keyType), optional any thisArg) - self.addMethod("forEach", members, False, - BuiltinTypes[IDLBuiltinType.Types.undefined], - self.getForEachArguments()) + self.addMethod( + "forEach", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.undefined], + self.getForEachArguments(), + ) + + def isValueIterator(self): + return not self.isPairIterator() + + def isPairIterator(self): + return self.hasKeyType() + + +class IDLAsyncIterable(IDLMaplikeOrSetlikeOrIterableBase): + def __init__(self, location, identifier, keyType, valueType, argList, scope): + for arg in argList: + if not arg.optional: + raise WebIDLError( + "The arguments of the asynchronously iterable declaration on " + "%s must all be optional arguments." % identifier, + [arg.location], + ) + + IDLMaplikeOrSetlikeOrIterableBase.__init__( + self, + location, + identifier, + "asynciterable", + keyType, + valueType, + IDLInterfaceMember.Tags.AsyncIterable, + ) + self.iteratorType = None + self.argList = argList + + def __str__(self): + return "declared async iterable with key '%s' and value '%s'" % ( + self.keyType, + self.valueType, + ) + + def expand(self, members): + """ + In order to take advantage of all of the method machinery in Codegen, + we generate our functions as if they were part of the interface + specification during parsing. + """ + # object values() + self.addMethod( + "values", + members, + False, + self.iteratorType, + self.argList, + affectsNothing=True, + newObject=True, + isIteratorAlias=(not self.isPairIterator()), + ) + + # We only need to add entries/keys here if we're a pair iterator. + if not self.isPairIterator(): + return + + # Methods can't share their IDLArguments, so we need to make copies here. + def copyArgList(argList): + return map(copy.copy, argList) + + # object entries() + self.addMethod( + "entries", + members, + False, + self.iteratorType, + copyArgList(self.argList), + affectsNothing=True, + newObject=True, + isIteratorAlias=True, + ) + # object keys() + self.addMethod( + "keys", + members, + False, + self.iteratorType, + copyArgList(self.argList), + affectsNothing=True, + newObject=True, + ) def isValueIterator(self): return not self.isPairIterator() @@ -4207,98 +4905,137 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase): def isPairIterator(self): return self.hasKeyType() + # MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface. class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase): - - def __init__(self, location, identifier, maplikeOrSetlikeType, - readonly, keyType, valueType): - IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, maplikeOrSetlikeType, - keyType, valueType, IDLInterfaceMember.Tags.MaplikeOrSetlike) + def __init__( + self, location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType + ): + IDLMaplikeOrSetlikeOrIterableBase.__init__( + self, + location, + identifier, + maplikeOrSetlikeType, + keyType, + valueType, + IDLInterfaceMember.Tags.MaplikeOrSetlike, + ) self.readonly = readonly self.slotIndices = None # When generating JSAPI access code, we need to know the backing object # type prefix to create the correct function. Generate here for reuse. if self.isMaplike(): - self.prefix = 'Map' + self.prefix = "Map" elif self.isSetlike(): - self.prefix = 'Set' + self.prefix = "Set" def __str__(self): - return "declared '%s' with key '%s'" % (self.maplikeOrSetlikeOrIterableType, self.keyType) + return "declared '%s' with key '%s'" % ( + self.maplikeOrSetlikeOrIterableType, + self.keyType, + ) - def expand(self, members, isJSImplemented): + def expand(self, members): """ In order to take advantage of all of the method machinery in Codegen, we generate our functions as if they were part of the interface specification during parsing. """ # Both maplike and setlike have a size attribute - sizeAttr = IDLAttribute(self.location, - IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"), - BuiltinTypes[IDLBuiltinType.Types.unsigned_long], - True, - maplikeOrSetlike=self) - # This should be non-enumerable. - sizeAttr.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("NonEnumerable",))]) - members.append(sizeAttr) + members.append( + IDLAttribute( + self.location, + IDLUnresolvedIdentifier( + BuiltinLocation("<auto-generated-identifier>"), "size" + ), + BuiltinTypes[IDLBuiltinType.Types.unsigned_long], + True, + maplikeOrSetlike=self, + ) + ) self.reserved_ro_names = ["size"] self.disallowedMemberNames.append("size") # object entries() - self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object], - affectsNothing=True, isIteratorAlias=self.isMaplike()) + self.addMethod( + "entries", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.object], + affectsNothing=True, + isIteratorAlias=self.isMaplike(), + ) # object keys() - self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object], - affectsNothing=True) + self.addMethod( + "keys", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.object], + affectsNothing=True, + ) # object values() - self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object], - affectsNothing=True, isIteratorAlias=self.isSetlike()) + self.addMethod( + "values", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.object], + affectsNothing=True, + isIteratorAlias=self.isSetlike(), + ) # undefined forEach(callback(valueType, keyType), thisVal) - self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.undefined], - self.getForEachArguments()) + self.addMethod( + "forEach", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.undefined], + self.getForEachArguments(), + ) def getKeyArg(): - return IDLArgument(self.location, - IDLUnresolvedIdentifier(self.location, "key"), - self.keyType) + return IDLArgument( + self.location, + IDLUnresolvedIdentifier(self.location, "key"), + self.keyType, + ) # boolean has(keyType key) - self.addMethod("has", members, False, BuiltinTypes[IDLBuiltinType.Types.boolean], - [getKeyArg()], isPure=True) + self.addMethod( + "has", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.boolean], + [getKeyArg()], + isPure=True, + ) if not self.readonly: # undefined clear() - self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.undefined], - []) + self.addMethod( + "clear", members, True, BuiltinTypes[IDLBuiltinType.Types.undefined], [] + ) # boolean delete(keyType key) - self.addMethod("delete", members, True, - BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()]) - - # Always generate underscored functions (e.g. __add, __clear) for js - # implemented interfaces as convenience functions. - if isJSImplemented: - # undefined clear() - self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.undefined], - [], chromeOnly=True) - # boolean delete(keyType key) - self.addMethod("delete", members, True, - BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()], - chromeOnly=True) + self.addMethod( + "delete", + members, + True, + BuiltinTypes[IDLBuiltinType.Types.boolean], + [getKeyArg()], + ) if self.isSetlike(): if not self.readonly: # Add returns the set object it just added to. # object add(keyType key) - self.addMethod("add", members, True, - BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()]) - if isJSImplemented: - self.addMethod("add", members, True, - BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()], - chromeOnly=True) + self.addMethod( + "add", + members, + True, + BuiltinTypes[IDLBuiltinType.Types.object], + [getKeyArg()], + ) return # If we get this far, we're a maplike declaration. @@ -4311,39 +5048,52 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase): # # TODO: Bug 1155340 may change this to use specific type to provide # more info to JIT. - self.addMethod("get", members, False, BuiltinTypes[IDLBuiltinType.Types.any], - [getKeyArg()], isPure=True) + self.addMethod( + "get", + members, + False, + BuiltinTypes[IDLBuiltinType.Types.any], + [getKeyArg()], + isPure=True, + ) def getValueArg(): - return IDLArgument(self.location, - IDLUnresolvedIdentifier(self.location, "value"), - self.valueType) + return IDLArgument( + self.location, + IDLUnresolvedIdentifier(self.location, "value"), + self.valueType, + ) if not self.readonly: - self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object], - [getKeyArg(), getValueArg()]) - if isJSImplemented: - self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object], - [getKeyArg(), getValueArg()], chromeOnly=True) + self.addMethod( + "set", + members, + True, + BuiltinTypes[IDLBuiltinType.Types.object], + [getKeyArg(), getValueArg()], + ) + class IDLConst(IDLInterfaceMember): def __init__(self, location, identifier, type, value): - IDLInterfaceMember.__init__(self, location, identifier, - IDLInterfaceMember.Tags.Const) + IDLInterfaceMember.__init__( + self, location, identifier, IDLInterfaceMember.Tags.Const + ) assert isinstance(type, IDLType) if type.isDictionary(): - raise WebIDLError("A constant cannot be of a dictionary type", - [self.location]) + raise WebIDLError( + "A constant cannot be of a dictionary type", [self.location] + ) if type.isRecord(): - raise WebIDLError("A constant cannot be of a record type", - [self.location]) + raise WebIDLError("A constant cannot be of a record type", [self.location]) self.type = type self.value = value if identifier.name == "prototype": - raise WebIDLError("The identifier of a constant must not be 'prototype'", - [location]) + raise WebIDLError( + "The identifier of a constant must not be 'prototype'", [location] + ) def __str__(self): return "'%s' const '%s'" % (self.type, self.identifier) @@ -4375,17 +5125,21 @@ class IDLConst(IDLInterfaceMember): identifier = attr.identifier() if identifier == "Exposed": convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) - elif (identifier == "Pref" or - identifier == "ChromeOnly" or - identifier == "Func" or - identifier == "SecureContext" or - identifier == "NonEnumerable" or - identifier == "NeedsWindowsUndef"): + elif ( + identifier == "Pref" + or identifier == "ChromeOnly" + or identifier == "Func" + or identifier == "Trial" + or identifier == "SecureContext" + or identifier == "NonEnumerable" + ): # Known attributes that we don't need to do anything with here pass else: - raise WebIDLError("Unknown extended attribute %s on constant" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on constant" % identifier, + [attr.location], + ) IDLInterfaceMember.handleExtendedAttribute(self, attr) def _getDependentObjects(self): @@ -4393,35 +5147,53 @@ class IDLConst(IDLInterfaceMember): class IDLAttribute(IDLInterfaceMember): - def __init__(self, location, identifier, type, readonly, inherit=False, - static=False, stringifier=False, maplikeOrSetlike=None, - extendedAttrDict=None): - IDLInterfaceMember.__init__(self, location, identifier, - IDLInterfaceMember.Tags.Attr, - extendedAttrDict=extendedAttrDict) + def __init__( + self, + location, + identifier, + type, + readonly, + inherit=False, + static=False, + stringifier=False, + maplikeOrSetlike=None, + extendedAttrDict=None, + ): + IDLInterfaceMember.__init__( + self, + location, + identifier, + IDLInterfaceMember.Tags.Attr, + extendedAttrDict=extendedAttrDict, + ) assert isinstance(type, IDLType) self.type = type self.readonly = readonly self.inherit = inherit self._static = static - self.lenientThis = False - self._unforgeable = False + self.legacyLenientThis = False + self._legacyUnforgeable = False self.stringifier = stringifier self.slotIndices = None - assert maplikeOrSetlike is None or isinstance(maplikeOrSetlike, IDLMaplikeOrSetlike) + assert maplikeOrSetlike is None or isinstance( + maplikeOrSetlike, IDLMaplikeOrSetlike + ) self.maplikeOrSetlike = maplikeOrSetlike self.dependsOn = "Everything" self.affects = "Everything" self.bindingAliases = [] if static and identifier.name == "prototype": - raise WebIDLError("The identifier of a static attribute must not be 'prototype'", - [location]) + raise WebIDLError( + "The identifier of a static attribute must not be 'prototype'", + [location], + ) if readonly and inherit: - raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'", - [self.location]) + raise WebIDLError( + "An attribute cannot be both 'readonly' and 'inherit'", [self.location] + ) def isStatic(self): return self._static @@ -4443,69 +5215,111 @@ class IDLAttribute(IDLInterfaceMember): assert not isinstance(t.name, IDLUnresolvedIdentifier) self.type = t - if self.readonly and (self.type.hasClamp() or self.type.hasEnforceRange() or - self.type.hasAllowShared() or self.type.treatNullAsEmpty): - raise WebIDLError("A readonly attribute cannot be [Clamp] or [EnforceRange] or [AllowShared]", - [self.location]) + if self.readonly and ( + self.type.hasClamp() + or self.type.hasEnforceRange() + or self.type.hasAllowShared() + or self.type.legacyNullToEmptyString + ): + raise WebIDLError( + "A readonly attribute cannot be [Clamp] or [EnforceRange] or [AllowShared]", + [self.location], + ) if self.type.isDictionary() and not self.getExtendedAttribute("Cached"): - raise WebIDLError("An attribute cannot be of a dictionary type", - [self.location]) + raise WebIDLError( + "An attribute cannot be of a dictionary type", [self.location] + ) if self.type.isSequence() and not self.getExtendedAttribute("Cached"): - raise WebIDLError("A non-cached attribute cannot be of a sequence " - "type", [self.location]) + raise WebIDLError( + "A non-cached attribute cannot be of a sequence " "type", + [self.location], + ) if self.type.isRecord() and not self.getExtendedAttribute("Cached"): - raise WebIDLError("A non-cached attribute cannot be of a record " - "type", [self.location]) + raise WebIDLError( + "A non-cached attribute cannot be of a record " "type", [self.location] + ) if self.type.isUnion(): for f in self.type.unroll().flatMemberTypes: if f.isDictionary(): - raise WebIDLError("An attribute cannot be of a union " - "type if one of its member types (or " - "one of its member types's member " - "types, and so on) is a dictionary " - "type", [self.location, f.location]) + raise WebIDLError( + "An attribute cannot be of a union " + "type if one of its member types (or " + "one of its member types's member " + "types, and so on) is a dictionary " + "type", + [self.location, f.location], + ) if f.isSequence(): - raise WebIDLError("An attribute cannot be of a union " - "type if one of its member types (or " - "one of its member types's member " - "types, and so on) is a sequence " - "type", [self.location, f.location]) + raise WebIDLError( + "An attribute cannot be of a union " + "type if one of its member types (or " + "one of its member types's member " + "types, and so on) is a sequence " + "type", + [self.location, f.location], + ) if f.isRecord(): - raise WebIDLError("An attribute cannot be of a union " - "type if one of its member types (or " - "one of its member types's member " - "types, and so on) is a record " - "type", [self.location, f.location]) + raise WebIDLError( + "An attribute cannot be of a union " + "type if one of its member types (or " + "one of its member types's member " + "types, and so on) is a record " + "type", + [self.location, f.location], + ) if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"): - raise WebIDLError("An attribute with [PutForwards] must have an " - "interface type as its type", [self.location]) + raise WebIDLError( + "An attribute with [PutForwards] must have an " + "interface type as its type", + [self.location], + ) - if (not self.type.isInterface() and - self.getExtendedAttribute("SameObject")): - raise WebIDLError("An attribute with [SameObject] must have an " - "interface type as its type", [self.location]) + if not self.type.isInterface() and self.getExtendedAttribute("SameObject"): + raise WebIDLError( + "An attribute with [SameObject] must have an " + "interface type as its type", + [self.location], + ) if self.type.isPromise() and not self.readonly: - raise WebIDLError("Promise-returning attributes must be readonly", - [self.location]) + raise WebIDLError( + "Promise-returning attributes must be readonly", [self.location] + ) + + if self.type.isObservableArray(): + if self.isStatic(): + raise WebIDLError( + "A static attribute cannot have an ObservableArray type", + [self.location], + ) + if self.getExtendedAttribute("Cached") or self.getExtendedAttribute( + "StoreInSlot" + ): + raise WebIDLError( + "[Cached] and [StoreInSlot] must not be used " + "on an attribute whose type is ObservableArray", + [self.location], + ) def validate(self): def typeContainsChromeOnlyDictionaryMember(type): - if (type.nullable() or - type.isSequence() or - type.isRecord()): + if type.nullable() or type.isSequence() or type.isRecord(): return typeContainsChromeOnlyDictionaryMember(type.inner) if type.isUnion(): for memberType in type.flatMemberTypes: - (contains, location) = typeContainsChromeOnlyDictionaryMember(memberType) + (contains, location) = typeContainsChromeOnlyDictionaryMember( + memberType + ) if contains: return (True, location) if type.isDictionary(): dictionary = type.inner while dictionary: - (contains, location) = dictionaryContainsChromeOnlyMember(dictionary) + (contains, location) = dictionaryContainsChromeOnlyMember( + dictionary + ) if contains: return (True, location) dictionary = dictionary.parent @@ -4516,254 +5330,345 @@ class IDLAttribute(IDLInterfaceMember): for member in dictionary.members: if member.getExtendedAttribute("ChromeOnly"): return (True, member.location) - (contains, location) = typeContainsChromeOnlyDictionaryMember(member.type) + (contains, location) = typeContainsChromeOnlyDictionaryMember( + member.type + ) if contains: return (True, location) return (False, None) IDLInterfaceMember.validate(self) - if (self.getExtendedAttribute("Cached") or - self.getExtendedAttribute("StoreInSlot")): + if self.getExtendedAttribute("Cached") or self.getExtendedAttribute( + "StoreInSlot" + ): if not self.affects == "Nothing": - raise WebIDLError("Cached attributes and attributes stored in " - "slots must be Constant or Pure or " - "Affects=Nothing, since the getter won't always " - "be called.", - [self.location]) + raise WebIDLError( + "Cached attributes and attributes stored in " + "slots must be Constant or Pure or " + "Affects=Nothing, since the getter won't always " + "be called.", + [self.location], + ) (contains, location) = typeContainsChromeOnlyDictionaryMember(self.type) if contains: - raise WebIDLError("[Cached] and [StoreInSlot] must not be used " - "on an attribute whose type contains a " - "[ChromeOnly] dictionary member", - [self.location, location]) + raise WebIDLError( + "[Cached] and [StoreInSlot] must not be used " + "on an attribute whose type contains a " + "[ChromeOnly] dictionary member", + [self.location, location], + ) if self.getExtendedAttribute("Frozen"): - if (not self.type.isSequence() and not self.type.isDictionary() and - not self.type.isRecord()): - raise WebIDLError("[Frozen] is only allowed on " - "sequence-valued, dictionary-valued, and " - "record-valued attributes", - [self.location]) + if ( + not self.type.isSequence() + and not self.type.isDictionary() + and not self.type.isRecord() + ): + raise WebIDLError( + "[Frozen] is only allowed on " + "sequence-valued, dictionary-valued, and " + "record-valued attributes", + [self.location], + ) if not self.type.unroll().isExposedInAllOf(self.exposureSet): - raise WebIDLError("Attribute returns a type that is not exposed " - "everywhere where the attribute is exposed", - [self.location]) + raise WebIDLError( + "Attribute returns a type that is not exposed " + "everywhere where the attribute is exposed", + [self.location], + ) if self.getExtendedAttribute("CEReactions"): if self.readonly: - raise WebIDLError("[CEReactions] is not allowed on " - "readonly attributes", - [self.location]) + raise WebIDLError( + "[CEReactions] is not allowed on " "readonly attributes", + [self.location], + ) def handleExtendedAttribute(self, attr): identifier = attr.identifier() - if ((identifier == "SetterThrows" or identifier == "SetterCanOOM" or - identifier == "SetterNeedsSubjectPrincipal") - and self.readonly): - raise WebIDLError("Readonly attributes must not be flagged as " - "[%s]" % identifier, - [self.location]) + if ( + identifier == "SetterThrows" + or identifier == "SetterCanOOM" + or identifier == "SetterNeedsSubjectPrincipal" + ) and self.readonly: + raise WebIDLError( + "Readonly attributes must not be flagged as " "[%s]" % identifier, + [self.location], + ) elif identifier == "BindingAlias": if not attr.hasValue(): - raise WebIDLError("[BindingAlias] takes an identifier or string", - [attr.location]) + raise WebIDLError( + "[BindingAlias] takes an identifier or string", [attr.location] + ) self._addBindingAlias(attr.value()) - elif (((identifier == "Throws" or identifier == "GetterThrows" or - identifier == "CanOOM" or identifier == "GetterCanOOM") and - self.getExtendedAttribute("StoreInSlot")) or - (identifier == "StoreInSlot" and - (self.getExtendedAttribute("Throws") or - self.getExtendedAttribute("GetterThrows") or - self.getExtendedAttribute("CanOOM") or - self.getExtendedAttribute("GetterCanOOM")))): - raise WebIDLError("Throwing things can't be [StoreInSlot]", - [attr.location]) - elif identifier == "LenientThis": + elif ( + ( + identifier == "Throws" + or identifier == "GetterThrows" + or identifier == "CanOOM" + or identifier == "GetterCanOOM" + ) + and self.getExtendedAttribute("StoreInSlot") + ) or ( + identifier == "StoreInSlot" + and ( + self.getExtendedAttribute("Throws") + or self.getExtendedAttribute("GetterThrows") + or self.getExtendedAttribute("CanOOM") + or self.getExtendedAttribute("GetterCanOOM") + ) + ): + raise WebIDLError("Throwing things can't be [StoreInSlot]", [attr.location]) + elif identifier == "LegacyLenientThis": if not attr.noArguments(): - raise WebIDLError("[LenientThis] must take no arguments", - [attr.location]) + raise WebIDLError( + "[LegacyLenientThis] must take no arguments", [attr.location] + ) if self.isStatic(): - raise WebIDLError("[LenientThis] is only allowed on non-static " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientThis] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) if self.getExtendedAttribute("CrossOriginReadable"): - raise WebIDLError("[LenientThis] is not allowed in combination " - "with [CrossOriginReadable]", - [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientThis] is not allowed in combination " + "with [CrossOriginReadable]", + [attr.location, self.location], + ) if self.getExtendedAttribute("CrossOriginWritable"): - raise WebIDLError("[LenientThis] is not allowed in combination " - "with [CrossOriginWritable]", - [attr.location, self.location]) - self.lenientThis = True - elif identifier == "Unforgeable": + raise WebIDLError( + "[LegacyLenientThis] is not allowed in combination " + "with [CrossOriginWritable]", + [attr.location, self.location], + ) + self.legacyLenientThis = True + elif identifier == "LegacyUnforgeable": if self.isStatic(): - raise WebIDLError("[Unforgeable] is only allowed on non-static " - "attributes", [attr.location, self.location]) - self._unforgeable = True + raise WebIDLError( + "[LegacyUnforgeable] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) + self._legacyUnforgeable = True elif identifier == "SameObject" and not self.readonly: - raise WebIDLError("[SameObject] only allowed on readonly attributes", - [attr.location, self.location]) + raise WebIDLError( + "[SameObject] only allowed on readonly attributes", + [attr.location, self.location], + ) elif identifier == "Constant" and not self.readonly: - raise WebIDLError("[Constant] only allowed on readonly attributes", - [attr.location, self.location]) + raise WebIDLError( + "[Constant] only allowed on readonly attributes", + [attr.location, self.location], + ) elif identifier == "PutForwards": if not self.readonly: - raise WebIDLError("[PutForwards] is only allowed on readonly " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[PutForwards] is only allowed on readonly " "attributes", + [attr.location, self.location], + ) if self.type.isPromise(): - raise WebIDLError("[PutForwards] is not allowed on " - "Promise-typed attributes", - [attr.location, self.location]) + raise WebIDLError( + "[PutForwards] is not allowed on " "Promise-typed attributes", + [attr.location, self.location], + ) if self.isStatic(): - raise WebIDLError("[PutForwards] is only allowed on non-static " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[PutForwards] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) if self.getExtendedAttribute("Replaceable") is not None: - raise WebIDLError("[PutForwards] and [Replaceable] can't both " - "appear on the same attribute", - [attr.location, self.location]) + raise WebIDLError( + "[PutForwards] and [Replaceable] can't both " + "appear on the same attribute", + [attr.location, self.location], + ) if not attr.hasValue(): - raise WebIDLError("[PutForwards] takes an identifier", - [attr.location, self.location]) + raise WebIDLError( + "[PutForwards] takes an identifier", [attr.location, self.location] + ) elif identifier == "Replaceable": if not attr.noArguments(): - raise WebIDLError("[Replaceable] must take no arguments", - [attr.location]) + raise WebIDLError( + "[Replaceable] must take no arguments", [attr.location] + ) if not self.readonly: - raise WebIDLError("[Replaceable] is only allowed on readonly " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[Replaceable] is only allowed on readonly " "attributes", + [attr.location, self.location], + ) if self.type.isPromise(): - raise WebIDLError("[Replaceable] is not allowed on " - "Promise-typed attributes", - [attr.location, self.location]) + raise WebIDLError( + "[Replaceable] is not allowed on " "Promise-typed attributes", + [attr.location, self.location], + ) if self.isStatic(): - raise WebIDLError("[Replaceable] is only allowed on non-static " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[Replaceable] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) if self.getExtendedAttribute("PutForwards") is not None: - raise WebIDLError("[PutForwards] and [Replaceable] can't both " - "appear on the same attribute", - [attr.location, self.location]) - elif identifier == "LenientSetter": + raise WebIDLError( + "[PutForwards] and [Replaceable] can't both " + "appear on the same attribute", + [attr.location, self.location], + ) + elif identifier == "LegacyLenientSetter": if not attr.noArguments(): - raise WebIDLError("[LenientSetter] must take no arguments", - [attr.location]) + raise WebIDLError( + "[LegacyLenientSetter] must take no arguments", [attr.location] + ) if not self.readonly: - raise WebIDLError("[LenientSetter] is only allowed on readonly " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientSetter] is only allowed on readonly " "attributes", + [attr.location, self.location], + ) if self.type.isPromise(): - raise WebIDLError("[LenientSetter] is not allowed on " - "Promise-typed attributes", - [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientSetter] is not allowed on " + "Promise-typed attributes", + [attr.location, self.location], + ) if self.isStatic(): - raise WebIDLError("[LenientSetter] is only allowed on non-static " - "attributes", [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientSetter] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) if self.getExtendedAttribute("PutForwards") is not None: - raise WebIDLError("[LenientSetter] and [PutForwards] can't both " - "appear on the same attribute", - [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientSetter] and [PutForwards] can't both " + "appear on the same attribute", + [attr.location, self.location], + ) if self.getExtendedAttribute("Replaceable") is not None: - raise WebIDLError("[LenientSetter] and [Replaceable] can't both " - "appear on the same attribute", - [attr.location, self.location]) + raise WebIDLError( + "[LegacyLenientSetter] and [Replaceable] can't both " + "appear on the same attribute", + [attr.location, self.location], + ) elif identifier == "LenientFloat": if self.readonly: - raise WebIDLError("[LenientFloat] used on a readonly attribute", - [attr.location, self.location]) + raise WebIDLError( + "[LenientFloat] used on a readonly attribute", + [attr.location, self.location], + ) if not self.type.includesRestrictedFloat(): - raise WebIDLError("[LenientFloat] used on an attribute with a " - "non-restricted-float type", - [attr.location, self.location]) + raise WebIDLError( + "[LenientFloat] used on an attribute with a " + "non-restricted-float type", + [attr.location, self.location], + ) elif identifier == "StoreInSlot": if self.getExtendedAttribute("Cached"): - raise WebIDLError("[StoreInSlot] and [Cached] must not be " - "specified on the same attribute", - [attr.location, self.location]) + raise WebIDLError( + "[StoreInSlot] and [Cached] must not be " + "specified on the same attribute", + [attr.location, self.location], + ) elif identifier == "Cached": if self.getExtendedAttribute("StoreInSlot"): - raise WebIDLError("[Cached] and [StoreInSlot] must not be " - "specified on the same attribute", - [attr.location, self.location]) - elif (identifier == "CrossOriginReadable" or - identifier == "CrossOriginWritable"): + raise WebIDLError( + "[Cached] and [StoreInSlot] must not be " + "specified on the same attribute", + [attr.location, self.location], + ) + elif identifier == "CrossOriginReadable" or identifier == "CrossOriginWritable": if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) if self.isStatic(): - raise WebIDLError("[%s] is only allowed on non-static " - "attributes" % identifier, - [attr.location, self.location]) - if self.getExtendedAttribute("LenientThis"): - raise WebIDLError("[LenientThis] is not allowed in combination " - "with [%s]" % identifier, - [attr.location, self.location]) + raise WebIDLError( + "[%s] is only allowed on non-static " "attributes" % identifier, + [attr.location, self.location], + ) + if self.getExtendedAttribute("LegacyLenientThis"): + raise WebIDLError( + "[LegacyLenientThis] is not allowed in combination " + "with [%s]" % identifier, + [attr.location, self.location], + ) elif identifier == "Exposed": convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) elif identifier == "Pure": if not attr.noArguments(): - raise WebIDLError("[Pure] must take no arguments", - [attr.location]) + raise WebIDLError("[Pure] must take no arguments", [attr.location]) self._setDependsOn("DOMState") self._setAffects("Nothing") elif identifier == "Constant" or identifier == "SameObject": if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) self._setDependsOn("Nothing") self._setAffects("Nothing") elif identifier == "Affects": if not attr.hasValue(): - raise WebIDLError("[Affects] takes an identifier", - [attr.location]) + raise WebIDLError("[Affects] takes an identifier", [attr.location]) self._setAffects(attr.value()) elif identifier == "DependsOn": if not attr.hasValue(): - raise WebIDLError("[DependsOn] takes an identifier", - [attr.location]) - if (attr.value() != "Everything" and attr.value() != "DOMState" and - not self.readonly): - raise WebIDLError("[DependsOn=%s] only allowed on " - "readonly attributes" % attr.value(), - [attr.location, self.location]) + raise WebIDLError("[DependsOn] takes an identifier", [attr.location]) + if ( + attr.value() != "Everything" + and attr.value() != "DOMState" + and not self.readonly + ): + raise WebIDLError( + "[DependsOn=%s] only allowed on " + "readonly attributes" % attr.value(), + [attr.location, self.location], + ) self._setDependsOn(attr.value()) elif identifier == "UseCounter": if self.stringifier: - raise WebIDLError("[UseCounter] must not be used on a " - "stringifier attribute", - [attr.location, self.location]) + raise WebIDLError( + "[UseCounter] must not be used on a " "stringifier attribute", + [attr.location, self.location], + ) elif identifier == "Unscopable": if not attr.noArguments(): - raise WebIDLError("[Unscopable] must take no arguments", - [attr.location]) + raise WebIDLError( + "[Unscopable] must take no arguments", [attr.location] + ) if self.isStatic(): - raise WebIDLError("[Unscopable] is only allowed on non-static " - "attributes and operations", - [attr.location, self.location]) + raise WebIDLError( + "[Unscopable] is only allowed on non-static " + "attributes and operations", + [attr.location, self.location], + ) elif identifier == "CEReactions": if not attr.noArguments(): - raise WebIDLError("[CEReactions] must take no arguments", - [attr.location]) - elif (identifier == "Pref" or - identifier == "Deprecated" or - identifier == "SetterThrows" or - identifier == "Throws" or - identifier == "GetterThrows" or - identifier == "SetterCanOOM" or - identifier == "CanOOM" or - identifier == "GetterCanOOM" or - identifier == "ChromeOnly" or - identifier == "Func" or - identifier == "SecureContext" or - identifier == "Frozen" or - identifier == "NewObject" or - identifier == "NeedsSubjectPrincipal" or - identifier == "SetterNeedsSubjectPrincipal" or - identifier == "GetterNeedsSubjectPrincipal" or - identifier == "NeedsCallerType" or - identifier == "ReturnValueNeedsContainsHack" or - identifier == "BinaryName" or - identifier == "NonEnumerable"): + raise WebIDLError( + "[CEReactions] must take no arguments", [attr.location] + ) + elif ( + identifier == "Pref" + or identifier == "Deprecated" + or identifier == "SetterThrows" + or identifier == "Throws" + or identifier == "GetterThrows" + or identifier == "SetterCanOOM" + or identifier == "CanOOM" + or identifier == "GetterCanOOM" + or identifier == "ChromeOnly" + or identifier == "Func" + or identifier == "Trial" + or identifier == "SecureContext" + or identifier == "Frozen" + or identifier == "NewObject" + or identifier == "NeedsSubjectPrincipal" + or identifier == "SetterNeedsSubjectPrincipal" + or identifier == "GetterNeedsSubjectPrincipal" + or identifier == "NeedsCallerType" + or identifier == "ReturnValueNeedsContainsHack" + or identifier == "BinaryName" + or identifier == "NonEnumerable" + ): # Known attributes that we don't need to do anything with here pass else: - raise WebIDLError("Unknown extended attribute %s on attribute" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on attribute" % identifier, + [attr.location], + ) IDLInterfaceMember.handleExtendedAttribute(self, attr) def resolve(self, parentScope): @@ -4771,8 +5676,8 @@ class IDLAttribute(IDLInterfaceMember): self.type.resolveType(parentScope) IDLObjectWithIdentifier.resolve(self, parentScope) - def hasLenientThis(self): - return self.lenientThis + def hasLegacyLenientThis(self): + return self.legacyLenientThis def isMaplikeOrSetlikeAttr(self): """ @@ -4782,24 +5687,35 @@ class IDLAttribute(IDLInterfaceMember): """ return self.maplikeOrSetlike is not None - def isUnforgeable(self): - return self._unforgeable + def isLegacyUnforgeable(self): + return self._legacyUnforgeable def _getDependentObjects(self): return set([self.type]) def expand(self, members): assert self.stringifier - if not self.type.isDOMString() and not self.type.isUSVString(): - raise WebIDLError("The type of a stringifer attribute must be " - "either DOMString or USVString", - [self.location]) - identifier = IDLUnresolvedIdentifier(self.location, "__stringifier", - allowDoubleUnderscore=True) - method = IDLMethod(self.location, - identifier, - returnType=self.type, arguments=[], - stringifier=True, underlyingAttr=self) + if ( + not self.type.isDOMString() + and not self.type.isUSVString() + and not self.type.isUTF8String() + ): + raise WebIDLError( + "The type of a stringifer attribute must be " + "either DOMString, USVString or UTF8String", + [self.location], + ) + identifier = IDLUnresolvedIdentifier( + self.location, "__stringifier", allowDoubleUnderscore=True + ) + method = IDLMethod( + self.location, + identifier, + returnType=self.type, + arguments=[], + stringifier=True, + underlyingAttr=self, + ) allowedExtAttrs = ["Throws", "NeedsSubjectPrincipal", "Pure"] # Safe to ignore these as they are only meaningful for attributes attributeOnlyExtAttrs = [ @@ -4807,24 +5723,40 @@ class IDLAttribute(IDLInterfaceMember): "CrossOriginWritable", "SetterThrows", ] - for (key, value) in list(self._extendedAttrDict.items()): + for (key, value) in self._extendedAttrDict.items(): if key in allowedExtAttrs: if value is not True: - raise WebIDLError("[%s] with a value is currently " - "unsupported in stringifier attributes, " - "please file a bug to add support" % key, - [self.location]) - method.addExtendedAttributes([IDLExtendedAttribute(self.location, (key,))]) + raise WebIDLError( + "[%s] with a value is currently " + "unsupported in stringifier attributes, " + "please file a bug to add support" % key, + [self.location], + ) + method.addExtendedAttributes( + [IDLExtendedAttribute(self.location, (key,))] + ) elif not key in attributeOnlyExtAttrs: - raise WebIDLError("[%s] is currently unsupported in " - "stringifier attributes, please file a bug " - "to add support" % key, - [self.location]) + raise WebIDLError( + "[%s] is currently unsupported in " + "stringifier attributes, please file a bug " + "to add support" % key, + [self.location], + ) members.append(method) class IDLArgument(IDLObjectWithIdentifier): - def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False, allowTypeAttributes=False): + def __init__( + self, + location, + identifier, + type, + optional=False, + defaultValue=None, + variadic=False, + dictionaryMember=False, + allowTypeAttributes=False, + ): IDLObjectWithIdentifier.__init__(self, location, None, identifier) assert isinstance(type, IDLType) @@ -4845,24 +5777,37 @@ class IDLArgument(IDLObjectWithIdentifier): def addExtendedAttributes(self, attrs): for attribute in attrs: identifier = attribute.identifier() - if self.allowTypeAttributes and (identifier == "EnforceRange" or identifier == "Clamp" or - identifier == "TreatNullAs" or identifier == "AllowShared"): + if self.allowTypeAttributes and ( + identifier == "EnforceRange" + or identifier == "Clamp" + or identifier == "LegacyNullToEmptyString" + or identifier == "AllowShared" + ): self.type = self.type.withExtendedAttributes([attribute]) elif identifier == "TreatNonCallableAsNull": self._allowTreatNonCallableAsNull = True - elif (self.dictionaryMember and - (identifier == "ChromeOnly" or - identifier == "Func" or - identifier == "Pref")): + elif self.dictionaryMember and ( + identifier == "ChromeOnly" + or identifier == "Func" + or identifier == "Trial" + or identifier == "Pref" + ): if not self.optional: - raise WebIDLError("[%s] must not be used on a required " - "dictionary member" % identifier, - [attribute.location]) + raise WebIDLError( + "[%s] must not be used on a required " + "dictionary member" % identifier, + [attribute.location], + ) else: - raise WebIDLError("Unhandled extended attribute on %s" % - ("a dictionary member" if self.dictionaryMember else - "an argument"), - [attribute.location]) + raise WebIDLError( + "Unhandled extended attribute on %s" + % ( + "a dictionary member" + if self.dictionaryMember + else "an argument" + ), + [attribute.location], + ) attrlist = attribute.listValue() self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True @@ -4885,22 +5830,37 @@ class IDLArgument(IDLObjectWithIdentifier): assert not isinstance(type.name, IDLUnresolvedIdentifier) self.type = type + if self.type.isUndefined(): + raise WebIDLError( + "undefined must not be used as the type of an argument in any circumstance", + [self.location], + ) + if self.type.isAny(): - assert (self.defaultValue is None or - isinstance(self.defaultValue, IDLNullValue)) + assert self.defaultValue is None or isinstance( + self.defaultValue, IDLNullValue + ) # optional 'any' values always have a default value if self.optional and not self.defaultValue and not self.variadic: # Set the default value to undefined, for simplicity, so the # codegen doesn't have to special-case this. self.defaultValue = IDLUndefinedValue(self.location) - if self.dictionaryMember and self.type.treatNullAsEmpty: - raise WebIDLError("Dictionary members cannot be [TreatNullAs]", [self.location]) + if self.dictionaryMember and self.type.legacyNullToEmptyString: + raise WebIDLError( + "Dictionary members cannot be [LegacyNullToEmptyString]", + [self.location], + ) + if self.type.isObservableArray(): + raise WebIDLError( + "%s cannot have an ObservableArray type" + % ("Dictionary members" if self.dictionaryMember else "Arguments"), + [self.location], + ) # Now do the coercing thing; this needs to happen after the # above creation of a default value. if self.defaultValue: - self.defaultValue = self.defaultValue.coerceToType(self.type, - self.location) + self.defaultValue = self.defaultValue.coerceToType(self.type, self.location) assert self.defaultValue def allowTreatNonCallableAsNull(self): @@ -4917,7 +5877,9 @@ class IDLArgument(IDLObjectWithIdentifier): class IDLCallback(IDLObjectWithScope): - def __init__(self, location, parentScope, identifier, returnType, arguments, isConstructor): + def __init__( + self, location, parentScope, identifier, returnType, arguments, isConstructor + ): assert isinstance(returnType, IDLType) self._returnType = returnType @@ -4965,29 +5927,42 @@ class IDLCallback(IDLObjectWithScope): argument.type = type def validate(self): - pass + for argument in self._arguments: + if argument.type.isUndefined(): + raise WebIDLError( + "undefined must not be used as the type of an argument in any circumstance", + [self.location], + ) def addExtendedAttributes(self, attrs): unhandledAttrs = [] for attr in attrs: if attr.identifier() == "TreatNonCallableAsNull": self._treatNonCallableAsNull = True - elif attr.identifier() == "TreatNonObjectAsNull": + elif attr.identifier() == "LegacyTreatNonObjectAsNull": if self._isConstructor: - raise WebIDLError("[TreatNonObjectAsNull] is not supported " - "on constructors", [self.location]) + raise WebIDLError( + "[LegacyTreatNonObjectAsNull] is not supported " + "on constructors", + [self.location], + ) self._treatNonObjectAsNull = True elif attr.identifier() == "MOZ_CAN_RUN_SCRIPT_BOUNDARY": if self._isConstructor: - raise WebIDLError("[MOZ_CAN_RUN_SCRIPT_BOUNDARY] is not " - "permitted on constructors", - [self.location]) + raise WebIDLError( + "[MOZ_CAN_RUN_SCRIPT_BOUNDARY] is not " + "permitted on constructors", + [self.location], + ) self._isRunScriptBoundary = True else: unhandledAttrs.append(attr) if self._treatNonCallableAsNull and self._treatNonObjectAsNull: - raise WebIDLError("Cannot specify both [TreatNonCallableAsNull] " - "and [TreatNonObjectAsNull]", [self.location]) + raise WebIDLError( + "Cannot specify both [TreatNonCallableAsNull] " + "and [LegacyTreatNonObjectAsNull]", + [self.location], + ) if len(unhandledAttrs) != 0: IDLType.addExtendedAttributes(self, unhandledAttrs) @@ -4995,7 +5970,7 @@ class IDLCallback(IDLObjectWithScope): return set([self._returnType] + self._arguments) def isRunScriptBoundary(self): - return self._isRunScriptBoundary; + return self._isRunScriptBoundary class IDLCallbackType(IDLType): @@ -5015,8 +5990,14 @@ class IDLCallbackType(IDLType): if other.isUnion(): # Just forward to the union; it'll deal return other.isDistinguishableFrom(self) - return (other.isPrimitive() or other.isString() or other.isEnum() or - other.isNonCallbackInterface() or other.isSequence()) + return ( + other.isUndefined() + or other.isPrimitive() + or other.isString() + or other.isEnum() + or other.isNonCallbackInterface() + or other.isSequence() + ) def _getDependentObjects(self): return self.callback._getDependentObjects() @@ -5031,6 +6012,7 @@ class IDLMethodOverload: IDLMethodOverload for each one, all hanging off an IDLMethod representing the full set of overloads. """ + def __init__(self, returnType, arguments, location): self.returnType = returnType # Clone the list of arguments, just in case @@ -5049,28 +6031,31 @@ class IDLMethodOverload: class IDLMethod(IDLInterfaceMember, IDLScope): Special = enum( - 'Getter', - 'Setter', - 'Deleter', - 'LegacyCaller', - base=IDLInterfaceMember.Special + "Getter", "Setter", "Deleter", "LegacyCaller", base=IDLInterfaceMember.Special ) - NamedOrIndexed = enum( - 'Neither', - 'Named', - 'Indexed' - ) - - def __init__(self, location, identifier, returnType, arguments, - static=False, getter=False, setter=False, - deleter=False, specialType=NamedOrIndexed.Neither, - legacycaller=False, stringifier=False, - maplikeOrSetlikeOrIterable=None, - underlyingAttr=None): + NamedOrIndexed = enum("Neither", "Named", "Indexed") + + def __init__( + self, + location, + identifier, + returnType, + arguments, + static=False, + getter=False, + setter=False, + deleter=False, + specialType=NamedOrIndexed.Neither, + legacycaller=False, + stringifier=False, + maplikeOrSetlikeOrIterable=None, + underlyingAttr=None, + ): # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up. - IDLInterfaceMember.__init__(self, location, identifier, - IDLInterfaceMember.Tags.Method) + IDLInterfaceMember.__init__( + self, location, identifier, IDLInterfaceMember.Tags.Method + ) self._hasOverloads = False @@ -5091,19 +6076,23 @@ class IDLMethod(IDLInterfaceMember, IDLScope): self._legacycaller = legacycaller assert isinstance(stringifier, bool) self._stringifier = stringifier - assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase) + assert maplikeOrSetlikeOrIterable is None or isinstance( + maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase + ) self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable self._htmlConstructor = False self.underlyingAttr = underlyingAttr self._specialType = specialType - self._unforgeable = False + self._legacyUnforgeable = False self.dependsOn = "Everything" self.affects = "Everything" self.aliases = [] if static and identifier.name == "prototype": - raise WebIDLError("The identifier of a static operation must not be 'prototype'", - [location]) + raise WebIDLError( + "The identifier of a static operation must not be 'prototype'", + [location], + ) self.assertSignatureConstraints() @@ -5116,8 +6105,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope): overload = self._overloads[0] arguments = overload.arguments assert len(arguments) == 1 - assert (arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or - arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]) + assert ( + arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] + or arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long] + ) assert not arguments[0].optional and not arguments[0].variadic assert not self._getter or not overload.returnType.isUndefined() @@ -5125,8 +6116,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope): assert len(self._overloads) == 1 arguments = self._overloads[0].arguments assert len(arguments) == 2 - assert (arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or - arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]) + assert ( + arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] + or arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long] + ) assert not arguments[0].optional and not arguments[0].variadic assert not arguments[1].optional and not arguments[1].variadic @@ -5135,7 +6128,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope): overload = self._overloads[0] assert len(overload.arguments) == 0 if not self.underlyingAttr: - assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring] + assert ( + overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring] + ) def isStatic(self): return self._static @@ -5153,13 +6148,17 @@ class IDLMethod(IDLInterfaceMember, IDLScope): return self._deleter def isNamed(self): - assert (self._specialType == IDLMethod.NamedOrIndexed.Named or - self._specialType == IDLMethod.NamedOrIndexed.Indexed) + assert ( + self._specialType == IDLMethod.NamedOrIndexed.Named + or self._specialType == IDLMethod.NamedOrIndexed.Indexed + ) return self._specialType == IDLMethod.NamedOrIndexed.Named def isIndexed(self): - assert (self._specialType == IDLMethod.NamedOrIndexed.Named or - self._specialType == IDLMethod.NamedOrIndexed.Indexed) + assert ( + self._specialType == IDLMethod.NamedOrIndexed.Named + or self._specialType == IDLMethod.NamedOrIndexed.Indexed + ) return self._specialType == IDLMethod.NamedOrIndexed.Indexed def isLegacycaller(self): @@ -5182,11 +6181,13 @@ class IDLMethod(IDLInterfaceMember, IDLScope): return self.maplikeOrSetlikeOrIterable is not None def isSpecial(self): - return (self.isGetter() or - self.isSetter() or - self.isDeleter() or - self.isLegacycaller() or - self.isStringifier()) + return ( + self.isGetter() + or self.isSetter() + or self.isDeleter() + or self.isLegacycaller() + or self.isStringifier() + ) def isHTMLConstructor(self): return self._htmlConstructor @@ -5202,8 +6203,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope): implemented interfaces, so while these functions use what is considered an non-identifier name, they actually DO have an identifier. """ - return (self.identifier.name[:2] == "__" and - not self.isMaplikeOrSetlikeOrIterableMethod()) + return ( + self.identifier.name[:2] == "__" + and not self.isMaplikeOrSetlikeOrIterableMethod() + ) def resolve(self, parentScope): assert isinstance(parentScope, IDLScope) @@ -5217,36 +6220,52 @@ class IDLMethod(IDLInterfaceMember, IDLScope): assert len(method._overloads) == 1 if self._extendedAttrDict != method._extendedAttrDict: - extendedAttrDiff = set(self._extendedAttrDict.keys()) ^ set(method._extendedAttrDict.keys()) + extendedAttrDiff = set(self._extendedAttrDict.keys()) ^ set( + method._extendedAttrDict.keys() + ) - if extendedAttrDiff == { "LenientFloat" }: + if extendedAttrDiff == {"LenientFloat"}: if "LenientFloat" not in self._extendedAttrDict: for overload in self._overloads: if overload.includesRestrictedFloatArgument(): - raise WebIDLError("Restricted float behavior differs on different " - "overloads of %s" % method.identifier, - [overload.location, method.location]) - self._extendedAttrDict["LenientFloat"] = method._extendedAttrDict["LenientFloat"] + raise WebIDLError( + "Restricted float behavior differs on different " + "overloads of %s" % method.identifier, + [overload.location, method.location], + ) + self._extendedAttrDict["LenientFloat"] = method._extendedAttrDict[ + "LenientFloat" + ] elif method._overloads[0].includesRestrictedFloatArgument(): - raise WebIDLError("Restricted float behavior differs on different " - "overloads of %s" % method.identifier, - [self.location, method.location]) + raise WebIDLError( + "Restricted float behavior differs on different " + "overloads of %s" % method.identifier, + [self.location, method.location], + ) else: - raise WebIDLError("Extended attributes differ on different " - "overloads of %s" % method.identifier, - [self.location, method.location]) + raise WebIDLError( + "Extended attributes differ on different " + "overloads of %s" % method.identifier, + [self.location, method.location], + ) self._overloads.extend(method._overloads) self._hasOverloads = True if self.isStatic() != method.isStatic(): - raise WebIDLError("Overloaded identifier %s appears with different values of the 'static' attribute" % method.identifier, - [method.location]) + raise WebIDLError( + "Overloaded identifier %s appears with different values of the 'static' attribute" + % method.identifier, + [method.location], + ) if self.isLegacycaller() != method.isLegacycaller(): - raise WebIDLError("Overloaded identifier %s appears with different values of the 'legacycaller' attribute" % method.identifier, - [method.location]) + raise WebIDLError( + "Overloaded identifier %s appears with different values of the 'legacycaller' attribute" + % method.identifier, + [method.location], + ) # Can't overload special things! assert not self.isGetter() @@ -5263,8 +6282,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope): return self def signatures(self): - return [(overload.returnType, overload.arguments) for overload in - self._overloads] + return [ + (overload.returnType, overload.arguments) for overload in self._overloads + ] def finish(self, scope): IDLInterfaceMember.finish(self, scope) @@ -5286,8 +6306,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope): # Now compute various information that will be used by the # WebIDL overload resolution algorithm. self.maxArgCount = max(len(s[1]) for s in self.signatures()) - self.allowedArgCounts = [i for i in range(self.maxArgCount+1) - if len(self.signaturesForArgCount(i)) != 0] + self.allowedArgCounts = [ + i + for i in range(self.maxArgCount + 1) + if len(self.signaturesForArgCount(i)) != 0 + ] def validate(self): IDLInterfaceMember.validate(self) @@ -5306,19 +6329,26 @@ class IDLMethod(IDLInterfaceMember, IDLScope): raise WebIDLError( "Signatures for method '%s' with %d arguments have " "different types of arguments at index %d, which " - "is before distinguishing index %d" % - (self.identifier.name, argCount, idx, - distinguishingIndex), - [self.location, overload.location]) + "is before distinguishing index %d" + % ( + self.identifier.name, + argCount, + idx, + distinguishingIndex, + ), + [self.location, overload.location], + ) overloadWithPromiseReturnType = None overloadWithoutPromiseReturnType = None for overload in self._overloads: returnType = overload.returnType if not returnType.unroll().isExposedInAllOf(self.exposureSet): - raise WebIDLError("Overload returns a type that is not exposed " - "everywhere where the method is exposed", - [overload.location]) + raise WebIDLError( + "Overload returns a type that is not exposed " + "everywhere where the method is exposed", + [overload.location], + ) variadicArgument = None @@ -5326,46 +6356,62 @@ class IDLMethod(IDLInterfaceMember, IDLScope): for (idx, argument) in enumerate(arguments): assert argument.type.isComplete() - if ((argument.type.isDictionary() and - argument.type.unroll().inner.canBeEmpty()) or - (argument.type.isUnion() and - argument.type.unroll().hasPossiblyEmptyDictionaryType())): + if ( + argument.type.isDictionary() + and argument.type.unroll().inner.canBeEmpty() + ) or ( + argument.type.isUnion() + and argument.type.unroll().hasPossiblyEmptyDictionaryType() + ): # Optional dictionaries and unions containing optional # dictionaries at the end of the list or followed by # optional arguments must be optional. - if (not argument.optional and - all(arg.optional for arg in arguments[idx+1:])): - raise WebIDLError("Dictionary argument without any " - "required fields or union argument " - "containing such dictionary not " - "followed by a required argument " - "must be optional", - [argument.location]) - - if (not argument.defaultValue and - all(arg.optional for arg in arguments[idx+1:])): - raise WebIDLError("Dictionary argument without any " - "required fields or union argument " - "containing such dictionary not " - "followed by a required argument " - "must have a default value", - [argument.location]) + if not argument.optional and all( + arg.optional for arg in arguments[idx + 1 :] + ): + raise WebIDLError( + "Dictionary argument without any " + "required fields or union argument " + "containing such dictionary not " + "followed by a required argument " + "must be optional", + [argument.location], + ) + + if not argument.defaultValue and all( + arg.optional for arg in arguments[idx + 1 :] + ): + raise WebIDLError( + "Dictionary argument without any " + "required fields or union argument " + "containing such dictionary not " + "followed by a required argument " + "must have a default value", + [argument.location], + ) # An argument cannot be a nullable dictionary or a # nullable union containing a dictionary. - if (argument.type.nullable() and - (argument.type.isDictionary() or - (argument.type.isUnion() and - argument.type.unroll().hasDictionaryType()))): - raise WebIDLError("An argument cannot be a nullable " - "dictionary or nullable union " - "containing a dictionary", - [argument.location]) + if argument.type.nullable() and ( + argument.type.isDictionary() + or ( + argument.type.isUnion() + and argument.type.unroll().hasDictionaryType() + ) + ): + raise WebIDLError( + "An argument cannot be a nullable " + "dictionary or nullable union " + "containing a dictionary", + [argument.location], + ) # Only the last argument can be variadic if variadicArgument: - raise WebIDLError("Variadic argument is not last argument", - [variadicArgument.location]) + raise WebIDLError( + "Variadic argument is not last argument", + [variadicArgument.location], + ) if argument.variadic: variadicArgument = argument @@ -5376,47 +6422,64 @@ class IDLMethod(IDLInterfaceMember, IDLScope): # Make sure either all our overloads return Promises or none do if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType: - raise WebIDLError("We have overloads with both Promise and " - "non-Promise return types", - [overloadWithPromiseReturnType.location, - overloadWithoutPromiseReturnType.location]) + raise WebIDLError( + "We have overloads with both Promise and " "non-Promise return types", + [ + overloadWithPromiseReturnType.location, + overloadWithoutPromiseReturnType.location, + ], + ) if overloadWithPromiseReturnType and self._legacycaller: - raise WebIDLError("May not have a Promise return type for a " - "legacycaller.", - [overloadWithPromiseReturnType.location]) + raise WebIDLError( + "May not have a Promise return type for a " "legacycaller.", + [overloadWithPromiseReturnType.location], + ) - if self.getExtendedAttribute("StaticClassOverride") and not \ - (self.identifier.scope.isJSImplemented() and self.isStatic()): - raise WebIDLError("StaticClassOverride can be applied to static" - " methods on JS-implemented classes only.", - [self.location]) + if self.getExtendedAttribute("StaticClassOverride") and not ( + self.identifier.scope.isJSImplemented() and self.isStatic() + ): + raise WebIDLError( + "StaticClassOverride can be applied to static" + " methods on JS-implemented classes only.", + [self.location], + ) # Ensure that toJSON methods satisfy the spec constraints on them. if self.identifier.name == "toJSON": if len(self.signatures()) != 1: - raise WebIDLError("toJSON method has multiple overloads", - [self._overloads[0].location, - self._overloads[1].location]) + raise WebIDLError( + "toJSON method has multiple overloads", + [self._overloads[0].location, self._overloads[1].location], + ) if len(self.signatures()[0][1]) != 0: - raise WebIDLError("toJSON method has arguments", - [self.location]) + raise WebIDLError("toJSON method has arguments", [self.location]) if not self.signatures()[0][0].isJSONType(): - raise WebIDLError("toJSON method has non-JSON return type", - [self.location]) + raise WebIDLError( + "toJSON method has non-JSON return type", [self.location] + ) def overloadsForArgCount(self, argc): - return [overload for overload in self._overloads if - len(overload.arguments) == argc or - (len(overload.arguments) > argc and - all(arg.optional for arg in overload.arguments[argc:])) or - (len(overload.arguments) < argc and - len(overload.arguments) > 0 and - overload.arguments[-1].variadic)] + return [ + overload + for overload in self._overloads + if len(overload.arguments) == argc + or ( + len(overload.arguments) > argc + and all(arg.optional for arg in overload.arguments[argc:]) + ) + or ( + len(overload.arguments) < argc + and len(overload.arguments) > 0 + and overload.arguments[-1].variadic + ) + ] def signaturesForArgCount(self, argc): - return [(overload.returnType, overload.arguments) for overload - in self.overloadsForArgCount(argc)] + return [ + (overload.returnType, overload.arguments) + for overload in self.overloadsForArgCount(argc) + ] def locationsForArgCount(self, argc): return [overload.location for overload in self.overloadsForArgCount(argc)] @@ -5424,163 +6487,199 @@ class IDLMethod(IDLInterfaceMember, IDLScope): def distinguishingIndexForArgCount(self, argc): def isValidDistinguishingIndex(idx, signatures): for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]): - for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]: + for (secondRetval, secondArgs) in signatures[firstSigIndex + 1 :]: if idx < len(firstArgs): firstType = firstArgs[idx].type else: - assert(firstArgs[-1].variadic) + assert firstArgs[-1].variadic firstType = firstArgs[-1].type if idx < len(secondArgs): secondType = secondArgs[idx].type else: - assert(secondArgs[-1].variadic) + assert secondArgs[-1].variadic secondType = secondArgs[-1].type if not firstType.isDistinguishableFrom(secondType): return False return True + signatures = self.signaturesForArgCount(argc) for idx in range(argc): if isValidDistinguishingIndex(idx, signatures): return idx # No valid distinguishing index. Time to throw locations = self.locationsForArgCount(argc) - raise WebIDLError("Signatures with %d arguments for method '%s' are not " - "distinguishable" % (argc, self.identifier.name), - locations) + raise WebIDLError( + "Signatures with %d arguments for method '%s' are not " + "distinguishable" % (argc, self.identifier.name), + locations, + ) def handleExtendedAttribute(self, attr): identifier = attr.identifier() - if (identifier == "GetterThrows" or - identifier == "SetterThrows" or - identifier == "GetterCanOOM" or - identifier == "SetterCanOOM" or - identifier == "SetterNeedsSubjectPrincipal" or - identifier == "GetterNeedsSubjectPrincipal"): - raise WebIDLError("Methods must not be flagged as " - "[%s]" % identifier, - [attr.location, self.location]) - elif identifier == "Unforgeable": + if ( + identifier == "GetterThrows" + or identifier == "SetterThrows" + or identifier == "GetterCanOOM" + or identifier == "SetterCanOOM" + or identifier == "SetterNeedsSubjectPrincipal" + or identifier == "GetterNeedsSubjectPrincipal" + ): + raise WebIDLError( + "Methods must not be flagged as " "[%s]" % identifier, + [attr.location, self.location], + ) + elif identifier == "LegacyUnforgeable": if self.isStatic(): - raise WebIDLError("[Unforgeable] is only allowed on non-static " - "methods", [attr.location, self.location]) - self._unforgeable = True + raise WebIDLError( + "[LegacyUnforgeable] is only allowed on non-static " "methods", + [attr.location, self.location], + ) + self._legacyUnforgeable = True elif identifier == "SameObject": - raise WebIDLError("Methods must not be flagged as [SameObject]", - [attr.location, self.location]) + raise WebIDLError( + "Methods must not be flagged as [SameObject]", + [attr.location, self.location], + ) elif identifier == "Constant": - raise WebIDLError("Methods must not be flagged as [Constant]", - [attr.location, self.location]) + raise WebIDLError( + "Methods must not be flagged as [Constant]", + [attr.location, self.location], + ) elif identifier == "PutForwards": - raise WebIDLError("Only attributes support [PutForwards]", - [attr.location, self.location]) - elif identifier == "LenientSetter": - raise WebIDLError("Only attributes support [LenientSetter]", - [attr.location, self.location]) + raise WebIDLError( + "Only attributes support [PutForwards]", [attr.location, self.location] + ) + elif identifier == "LegacyLenientSetter": + raise WebIDLError( + "Only attributes support [LegacyLenientSetter]", + [attr.location, self.location], + ) elif identifier == "LenientFloat": # This is called before we've done overload resolution overloads = self._overloads assert len(overloads) == 1 if not overloads[0].returnType.isUndefined(): - raise WebIDLError("[LenientFloat] used on a non-undefined returning method", - [attr.location, self.location]) + raise WebIDLError( + "[LenientFloat] used on a non-undefined method", + [attr.location, self.location], + ) if not overloads[0].includesRestrictedFloatArgument(): - raise WebIDLError("[LenientFloat] used on an operation with no " - "restricted float type arguments", - [attr.location, self.location]) + raise WebIDLError( + "[LenientFloat] used on an operation with no " + "restricted float type arguments", + [attr.location, self.location], + ) elif identifier == "Exposed": convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) - elif (identifier == "CrossOriginCallable" or - identifier == "WebGLHandlesContextLoss"): + elif ( + identifier == "CrossOriginCallable" + or identifier == "WebGLHandlesContextLoss" + ): # Known no-argument attributes. if not attr.noArguments(): - raise WebIDLError("[%s] must take no arguments" % identifier, - [attr.location]) + raise WebIDLError( + "[%s] must take no arguments" % identifier, [attr.location] + ) if identifier == "CrossOriginCallable" and self.isStatic(): - raise WebIDLError("[CrossOriginCallable] is only allowed on non-static " - "attributes", - [attr.location, self.location]) + raise WebIDLError( + "[CrossOriginCallable] is only allowed on non-static " "attributes", + [attr.location, self.location], + ) elif identifier == "Pure": if not attr.noArguments(): - raise WebIDLError("[Pure] must take no arguments", - [attr.location]) + raise WebIDLError("[Pure] must take no arguments", [attr.location]) self._setDependsOn("DOMState") self._setAffects("Nothing") elif identifier == "Affects": if not attr.hasValue(): - raise WebIDLError("[Affects] takes an identifier", - [attr.location]) + raise WebIDLError("[Affects] takes an identifier", [attr.location]) self._setAffects(attr.value()) elif identifier == "DependsOn": if not attr.hasValue(): - raise WebIDLError("[DependsOn] takes an identifier", - [attr.location]) + raise WebIDLError("[DependsOn] takes an identifier", [attr.location]) self._setDependsOn(attr.value()) elif identifier == "Alias": if not attr.hasValue(): - raise WebIDLError("[Alias] takes an identifier or string", - [attr.location]) + raise WebIDLError( + "[Alias] takes an identifier or string", [attr.location] + ) self._addAlias(attr.value()) elif identifier == "UseCounter": if self.isSpecial(): - raise WebIDLError("[UseCounter] must not be used on a special " - "operation", - [attr.location, self.location]) + raise WebIDLError( + "[UseCounter] must not be used on a special " "operation", + [attr.location, self.location], + ) elif identifier == "Unscopable": if not attr.noArguments(): - raise WebIDLError("[Unscopable] must take no arguments", - [attr.location]) + raise WebIDLError( + "[Unscopable] must take no arguments", [attr.location] + ) if self.isStatic(): - raise WebIDLError("[Unscopable] is only allowed on non-static " - "attributes and operations", - [attr.location, self.location]) + raise WebIDLError( + "[Unscopable] is only allowed on non-static " + "attributes and operations", + [attr.location, self.location], + ) elif identifier == "CEReactions": if not attr.noArguments(): - raise WebIDLError("[CEReactions] must take no arguments", - [attr.location]) + raise WebIDLError( + "[CEReactions] must take no arguments", [attr.location] + ) if self.isSpecial() and not self.isSetter() and not self.isDeleter(): - raise WebIDLError("[CEReactions] is only allowed on operation, " - "attribute, setter, and deleter", - [attr.location, self.location]) + raise WebIDLError( + "[CEReactions] is only allowed on operation, " + "attribute, setter, and deleter", + [attr.location, self.location], + ) elif identifier == "Default": if not attr.noArguments(): - raise WebIDLError("[Default] must take no arguments", - [attr.location]) + raise WebIDLError("[Default] must take no arguments", [attr.location]) if not self.isToJSON(): - raise WebIDLError("[Default] is only allowed on toJSON operations", - [attr.location, self.location]) + raise WebIDLError( + "[Default] is only allowed on toJSON operations", + [attr.location, self.location], + ) if self.signatures()[0][0] != BuiltinTypes[IDLBuiltinType.Types.object]: - raise WebIDLError("The return type of the default toJSON " - "operation must be 'object'", - [attr.location, self.location]) - elif (identifier == "Throws" or - identifier == "CanOOM" or - identifier == "NewObject" or - identifier == "ChromeOnly" or - identifier == "Pref" or - identifier == "Deprecated" or - identifier == "Func" or - identifier == "SecureContext" or - identifier == "BinaryName" or - identifier == "NeedsSubjectPrincipal" or - identifier == "NeedsCallerType" or - identifier == "StaticClassOverride" or - identifier == "NonEnumerable" or - identifier == "Unexposed"): + raise WebIDLError( + "The return type of the default toJSON " + "operation must be 'object'", + [attr.location, self.location], + ) + elif ( + identifier == "Throws" + or identifier == "CanOOM" + or identifier == "NewObject" + or identifier == "ChromeOnly" + or identifier == "Pref" + or identifier == "Deprecated" + or identifier == "Func" + or identifier == "Trial" + or identifier == "SecureContext" + or identifier == "BinaryName" + or identifier == "NeedsSubjectPrincipal" + or identifier == "NeedsCallerType" + or identifier == "StaticClassOverride" + or identifier == "NonEnumerable" + or identifier == "Unexposed" + or identifier == "WebExtensionStub" + ): # Known attributes that we don't need to do anything with here pass else: - raise WebIDLError("Unknown extended attribute %s on method" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on method" % identifier, [attr.location] + ) IDLInterfaceMember.handleExtendedAttribute(self, attr) def returnsPromise(self): return self._overloads[0].returnType.isPromise() - def isUnforgeable(self): - return self._unforgeable + def isLegacyUnforgeable(self): + return self._legacyUnforgeable def _getDependentObjects(self): deps = set() @@ -5607,45 +6706,55 @@ class IDLConstructor(IDLMethod): def handleExtendedAttribute(self, attr): identifier = attr.identifier() - if (identifier == "BinaryName" or - identifier == "ChromeOnly" or - identifier == "NewObject" or - identifier == "SecureContext" or - identifier == "Throws" or - identifier == "Func" or - identifier == "Pref"): + if ( + identifier == "BinaryName" + or identifier == "ChromeOnly" + or identifier == "NewObject" + or identifier == "SecureContext" + or identifier == "Throws" + or identifier == "Func" + or identifier == "Trial" + or identifier == "Pref" + or identifier == "UseCounter" + ): IDLMethod.handleExtendedAttribute(self, attr) elif identifier == "HTMLConstructor": if not attr.noArguments(): - raise WebIDLError("[HTMLConstructor] must take no arguments", - [attr.location]) - # We shouldn't end up here for named constructors. - assert(self.identifier.name == "constructor") + raise WebIDLError( + "[HTMLConstructor] must take no arguments", [attr.location] + ) + # We shouldn't end up here for legacy factory functions. + assert self.identifier.name == "constructor" if any(len(sig[1]) != 0 for sig in self.signatures()): - raise WebIDLError("[HTMLConstructor] must not be applied to a " - "constructor operation that has arguments.", - [attr.location]) + raise WebIDLError( + "[HTMLConstructor] must not be applied to a " + "constructor operation that has arguments.", + [attr.location], + ) self._htmlConstructor = True else: - raise WebIDLError("Unknown extended attribute %s on method" % identifier, - [attr.location]) + raise WebIDLError( + "Unknown extended attribute %s on method" % identifier, [attr.location] + ) def reallyInit(self, parentInterface): name = self._initName location = self._initLocation identifier = IDLUnresolvedIdentifier(location, name, allowForbidden=True) retType = IDLWrapperType(parentInterface.location, parentInterface) - IDLMethod.__init__(self, location, identifier, retType, self._initArgs, - static=True) - self._inited = True; + IDLMethod.__init__( + self, location, identifier, retType, self._initArgs, static=True + ) + self._inited = True # Propagate through whatever extended attributes we already had self.addExtendedAttributes(self._initExtendedAttrs) self._initExtendedAttrs = [] # Constructors are always NewObject. Whether they throw or not is # indicated by [Throws] annotations in the usual way. self.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("NewObject",))]) + [IDLExtendedAttribute(self.location, ("NewObject",))] + ) class IDLIncludesStatement(IDLObject): @@ -5659,25 +6768,28 @@ class IDLIncludesStatement(IDLObject): if self._finished: return self._finished = True - assert(isinstance(self.interface, IDLIdentifierPlaceholder)) - assert(isinstance(self.mixin, IDLIdentifierPlaceholder)) + assert isinstance(self.interface, IDLIdentifierPlaceholder) + assert isinstance(self.mixin, IDLIdentifierPlaceholder) interface = self.interface.finish(scope) mixin = self.mixin.finish(scope) # NOTE: we depend on not setting self.interface and # self.mixin here to keep track of the original # locations. if not isinstance(interface, IDLInterface): - raise WebIDLError("Left-hand side of 'includes' is not an " - "interface", - [self.interface.location, interface.location]) + raise WebIDLError( + "Left-hand side of 'includes' is not an " "interface", + [self.interface.location, interface.location], + ) if interface.isCallback(): - raise WebIDLError("Left-hand side of 'includes' is a callback " - "interface", - [self.interface.location, interface.location]) + raise WebIDLError( + "Left-hand side of 'includes' is a callback " "interface", + [self.interface.location, interface.location], + ) if not isinstance(mixin, IDLInterfaceMixin): - raise WebIDLError("Right-hand side of 'includes' is not an " - "interface mixin", - [self.mixin.location, mixin.location]) + raise WebIDLError( + "Right-hand side of 'includes' is not an " "interface mixin", + [self.mixin.location, mixin.location], + ) mixin.actualExposureGlobalNames.update(interface._exposureGlobalNames) @@ -5690,14 +6802,18 @@ class IDLIncludesStatement(IDLObject): def addExtendedAttributes(self, attrs): if len(attrs) != 0: - raise WebIDLError("There are no extended attributes that are " - "allowed on includes statements", - [attrs[0].location, self.location]) + raise WebIDLError( + "There are no extended attributes that are " + "allowed on includes statements", + [attrs[0].location, self.location], + ) + class IDLExtendedAttribute(IDLObject): """ A class to represent IDL extended attributes so we can give them locations """ + def __init__(self, location, tuple): IDLObject.__init__(self, location) self._tuple = tuple @@ -5712,15 +6828,18 @@ class IDLExtendedAttribute(IDLObject): return len(self._tuple) >= 2 and isinstance(self._tuple[1], str) def value(self): - assert(self.hasValue()) + assert self.hasValue() return self._tuple[1] def hasArgs(self): - return (len(self._tuple) == 2 and isinstance(self._tuple[1], list) or - len(self._tuple) == 3) + return ( + len(self._tuple) == 2 + and isinstance(self._tuple[1], list) + or len(self._tuple) == 3 + ) def args(self): - assert(self.hasArgs()) + assert self.hasArgs() # Our args are our last element return self._tuple[-1] @@ -5730,41 +6849,40 @@ class IDLExtendedAttribute(IDLObject): """ return list(self._tuple)[1:] + # Parser class Tokenizer(object): - tokens = [ - "INTEGER", - "FLOATLITERAL", - "IDENTIFIER", - "STRING", - "COMMENTS", - "WHITESPACE", - "OTHER" - ] + tokens = ["INTEGER", "FLOATLITERAL", "IDENTIFIER", "STRING", "WHITESPACE", "OTHER"] def t_FLOATLITERAL(self, t): - r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN' + r"(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN" t.value = float(t.value) return t def t_INTEGER(self, t): - r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)' + r"-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)" try: # Can't use int(), because that doesn't handle octal properly. t.value = parseInt(t.value) except: - raise WebIDLError("Invalid integer literal", - [Location(lexer=self.lexer, - lineno=self.lexer.lineno, - lexpos=self.lexer.lexpos, - filename=self._filename)]) + raise WebIDLError( + "Invalid integer literal", + [ + Location( + lexer=self.lexer, + lineno=self.lexer.lineno, + lexpos=self.lexer.lexpos, + filename=self._filename, + ) + ], + ) return t def t_IDENTIFIER(self, t): - r'[_-]?[A-Za-z][0-9A-Z_a-z-]*' - t.type = self.keywords.get(t.value, 'IDENTIFIER') + r"[_-]?[A-Za-z][0-9A-Z_a-z-]*" + t.type = self.keywords.get(t.value, "IDENTIFIER") return t def t_STRING(self, t): @@ -5772,22 +6890,18 @@ class Tokenizer(object): t.value = t.value[1:-1] return t - def t_COMMENTS(self, t): - r'(\/\*(.|\n)*?\*\/)|(\/\/.*)' - pass - def t_WHITESPACE(self, t): - r'[\t\n\r ]+' + r"[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+" pass def t_ELLIPSIS(self, t): - r'\.\.\.' + r"\.\.\." t.type = self.keywords.get(t.value) return t def t_OTHER(self, t): - r'[^\t\n\r 0-9A-Z_a-z]' - t.type = self.keywords.get(t.value, 'OTHER') + r"[^\t\n\r 0-9A-Z_a-z]" + t.type = self.keywords.get(t.value, "OTHER") return t keywords = { @@ -5830,6 +6944,7 @@ class Tokenizer(object): "float": "FLOAT", "long": "LONG", "object": "OBJECT", + "ObservableArray": "OBSERVABLEARRAY", "octet": "OCTET", "Promise": "PROMISE", "required": "REQUIRED", @@ -5847,6 +6962,7 @@ class Tokenizer(object): "[": "LBRACKET", "]": "RBRACKET", "?": "QUESTIONMARK", + "*": "ASTERISK", ",": "COMMA", "=": "EQUALS", "<": "LT", @@ -5857,36 +6973,40 @@ class Tokenizer(object): "setlike": "SETLIKE", "iterable": "ITERABLE", "namespace": "NAMESPACE", - "ReadableStream": "READABLESTREAM", "constructor": "CONSTRUCTOR", "symbol": "SYMBOL", "async": "ASYNC", - } + } - tokens.extend(list(keywords.values())) + tokens.extend(keywords.values()) def t_error(self, t): - raise WebIDLError("Unrecognized Input", - [Location(lexer=self.lexer, - lineno=self.lexer.lineno, - lexpos=self.lexer.lexpos, - filename=self.filename)]) + raise WebIDLError( + "Unrecognized Input", + [ + Location( + lexer=self.lexer, + lineno=self.lexer.lineno, + lexpos=self.lexer.lexpos, + filename=self.filename, + ) + ], + ) - def __init__(self, lexer=None): + def __init__(self, outputdir, lexer=None): if lexer: self.lexer = lexer else: - self.lexer = lex.lex(object=self) + self.lexer = lex.lex(object=self, reflags=re.DOTALL) class SqueakyCleanLogger(object): errorWhitelist = [ - # Web IDL defines the WHITESPACE and COMMENTS token, but doesn't actually + # Web IDL defines the WHITESPACE token, but doesn't actually # use it ... so far. "Token 'WHITESPACE' defined, but not used", - "Token 'COMMENTS' defined, but not used", - # And that means we have unused tokens - "There are 2 unused tokens", + # And that means we have an unused token + "There is 1 unused token", # Web IDL defines a OtherOrComma rule that's only used in # ExtendedAttributeInner, which we don't use yet. "Rule 'OtherOrComma' defined, but not used", @@ -5896,18 +7016,21 @@ class SqueakyCleanLogger(object): "Symbol 'OtherOrComma' is unreachable", # Which means the Other symbol is unreachable. "Symbol 'Other' is unreachable", - ] + ] def __init__(self): self.errors = [] def debug(self, msg, *args, **kwargs): pass + info = debug def warning(self, msg, *args, **kwargs): - if msg == "%s:%d: Rule %r defined, but not used" or \ - msg == "%s:%d: Rule '%s' defined, but not used": + if ( + msg == "%s:%d: Rule %r defined, but not used" + or msg == "%s:%d: Rule '%s' defined, but not used" + ): # Munge things so we don't have to hardcode filenames and # line numbers in our whitelist. whitelistmsg = "Rule %r defined, but not used" @@ -5917,6 +7040,7 @@ class SqueakyCleanLogger(object): whitelistargs = args if (whitelistmsg % whitelistargs) not in SqueakyCleanLogger.errorWhitelist: self.errors.append(msg % args) + error = warning def reportGrammarErrors(self): @@ -5935,7 +7059,7 @@ class Parser(Tokenizer): # It's acceptable to split things at '|' boundaries. def p_Definitions(self, p): """ - Definitions : ExtendedAttributeList Definition Definitions + Definitions : ExtendedAttributeList Definition Definitions """ if p[2]: p[0] = [p[2]] @@ -5948,27 +7072,27 @@ class Parser(Tokenizer): def p_DefinitionsEmpty(self, p): """ - Definitions : + Definitions : """ p[0] = [] def p_Definition(self, p): """ - Definition : CallbackOrInterfaceOrMixin - | Namespace - | Partial - | Dictionary - | Exception - | Enum - | Typedef - | IncludesStatement + Definition : CallbackOrInterfaceOrMixin + | Namespace + | Partial + | Dictionary + | Exception + | Enum + | Typedef + | IncludesStatement """ p[0] = p[1] assert p[1] # We might not have implemented something ... def p_CallbackOrInterfaceOrMixinCallback(self, p): """ - CallbackOrInterfaceOrMixin : CALLBACK CallbackRestOrInterface + CallbackOrInterfaceOrMixin : CALLBACK CallbackRestOrInterface """ if p[2].isInterface(): assert isinstance(p[2], IDLInterface) @@ -5978,21 +7102,22 @@ class Parser(Tokenizer): def p_CallbackOrInterfaceOrMixinInterfaceOrMixin(self, p): """ - CallbackOrInterfaceOrMixin : INTERFACE InterfaceOrMixin + CallbackOrInterfaceOrMixin : INTERFACE InterfaceOrMixin """ p[0] = p[2] def p_CallbackRestOrInterface(self, p): """ - CallbackRestOrInterface : CallbackRest - | CallbackConstructorRest - | CallbackInterface + CallbackRestOrInterface : CallbackRest + | CallbackConstructorRest + | CallbackInterface """ assert p[1] p[0] = p[1] - def handleNonPartialObject(self, location, identifier, constructor, - constructorArgs, nonPartialArgs): + def handleNonPartialObject( + self, location, identifier, constructor, constructorArgs, nonPartialArgs + ): """ This handles non-partial objects (interfaces, namespaces and dictionaries) by checking for an existing partial object, and promoting @@ -6013,10 +7138,11 @@ class Parser(Tokenizer): existingObj = self.globalScope()._lookupIdentifier(identifier) if existingObj: if not isinstance(existingObj, constructor): - raise WebIDLError("%s has the same name as " - "non-%s object" % - (prettyname.capitalize(), prettyname), - [location, existingObj.location]) + raise WebIDLError( + "%s has the same name as " + "non-%s object" % (prettyname.capitalize(), prettyname), + [location, existingObj.location], + ) existingObj.setNonPartial(*nonPartialArgs) return existingObj except Exception as ex: @@ -6029,20 +7155,20 @@ class Parser(Tokenizer): def p_InterfaceOrMixin(self, p): """ - InterfaceOrMixin : InterfaceRest - | MixinRest + InterfaceOrMixin : InterfaceRest + | MixinRest """ p[0] = p[1] def p_CallbackInterface(self, p): """ - CallbackInterface : INTERFACE InterfaceRest + CallbackInterface : INTERFACE InterfaceRest """ p[0] = p[2] def p_InterfaceRest(self, p): """ - InterfaceRest : IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON + InterfaceRest : IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(location, p[1]) @@ -6050,13 +7176,16 @@ class Parser(Tokenizer): parent = p[2] p[0] = self.handleNonPartialObject( - location, identifier, IDLInterface, + location, + identifier, + IDLInterface, [location, self.globalScope(), identifier, parent, members], - [location, parent, members]) + [location, parent, members], + ) def p_InterfaceForwardDecl(self, p): """ - InterfaceRest : IDENTIFIER SEMICOLON + InterfaceRest : IDENTIFIER SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(location, p[1]) @@ -6065,10 +7194,12 @@ class Parser(Tokenizer): if self.globalScope()._lookupIdentifier(identifier): p[0] = self.globalScope()._lookupIdentifier(identifier) if not isinstance(p[0], IDLExternalInterface): - raise WebIDLError("Name collision between external " - "interface declaration for identifier " - "%s and %s" % (identifier.name, p[0]), - [location, p[0].location]) + raise WebIDLError( + "Name collision between external " + "interface declaration for identifier " + "%s and %s" % (identifier.name, p[0]), + [location, p[0].location], + ) return except Exception as ex: if isinstance(ex, WebIDLError): @@ -6079,52 +7210,63 @@ class Parser(Tokenizer): def p_MixinRest(self, p): """ - MixinRest : MIXIN IDENTIFIER LBRACE MixinMembers RBRACE SEMICOLON + MixinRest : MIXIN IDENTIFIER LBRACE MixinMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) members = p[4] p[0] = self.handleNonPartialObject( - location, identifier, IDLInterfaceMixin, + location, + identifier, + IDLInterfaceMixin, [location, self.globalScope(), identifier, members], - [location, members]) + [location, members], + ) def p_Namespace(self, p): """ - Namespace : NAMESPACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON + Namespace : NAMESPACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) members = p[4] p[0] = self.handleNonPartialObject( - location, identifier, IDLNamespace, + location, + identifier, + IDLNamespace, [location, self.globalScope(), identifier, members], - [location, None, members]) + [location, None, members], + ) def p_Partial(self, p): """ - Partial : PARTIAL PartialDefinition + Partial : PARTIAL PartialDefinition """ p[0] = p[2] def p_PartialDefinitionInterface(self, p): """ - PartialDefinition : INTERFACE PartialInterfaceOrPartialMixin + PartialDefinition : INTERFACE PartialInterfaceOrPartialMixin """ p[0] = p[2] def p_PartialDefinition(self, p): """ - PartialDefinition : PartialNamespace - | PartialDictionary + PartialDefinition : PartialNamespace + | PartialDictionary """ p[0] = p[1] - def handlePartialObject(self, location, identifier, nonPartialConstructor, - nonPartialConstructorArgs, - partialConstructorArgs): + def handlePartialObject( + self, + location, + identifier, + nonPartialConstructor, + nonPartialConstructorArgs, + partialConstructorArgs, + ): """ This handles partial objects (interfaces, namespaces and dictionaries) by checking for an existing non-partial object, and adding ourselves to @@ -6148,10 +7290,11 @@ class Parser(Tokenizer): nonPartialObject = self.globalScope()._lookupIdentifier(identifier) if nonPartialObject: if not isinstance(nonPartialObject, nonPartialConstructor): - raise WebIDLError("Partial %s has the same name as " - "non-%s object" % - (prettyname, prettyname), - [location, nonPartialObject.location]) + raise WebIDLError( + "Partial %s has the same name as " + "non-%s object" % (prettyname, prettyname), + [location, nonPartialObject.location], + ) except Exception as ex: if isinstance(ex, WebIDLError): raise ex @@ -6160,96 +7303,115 @@ class Parser(Tokenizer): if not nonPartialObject: nonPartialObject = nonPartialConstructor( # No members, False for isKnownNonPartial - *(nonPartialConstructorArgs), members=[], isKnownNonPartial=False) + *(nonPartialConstructorArgs), + members=[], + isKnownNonPartial=False + ) partialObject = None if isinstance(nonPartialObject, IDLDictionary): partialObject = IDLPartialDictionary( - *(partialConstructorArgs + [nonPartialObject])) - elif isinstance(nonPartialObject, (IDLInterface, IDLInterfaceMixin, IDLNamespace)): + *(partialConstructorArgs + [nonPartialObject]) + ) + elif isinstance( + nonPartialObject, (IDLInterface, IDLInterfaceMixin, IDLNamespace) + ): partialObject = IDLPartialInterfaceOrNamespace( - *(partialConstructorArgs + [nonPartialObject])) + *(partialConstructorArgs + [nonPartialObject]) + ) else: - raise WebIDLError("Unknown partial object type %s" % - type(partialObject), - [location]) + raise WebIDLError( + "Unknown partial object type %s" % type(partialObject), [location] + ) return partialObject def p_PartialInterfaceOrPartialMixin(self, p): """ - PartialInterfaceOrPartialMixin : PartialInterfaceRest - | PartialMixinRest + PartialInterfaceOrPartialMixin : PartialInterfaceRest + | PartialMixinRest """ p[0] = p[1] def p_PartialInterfaceRest(self, p): """ - PartialInterfaceRest : IDENTIFIER LBRACE PartialInterfaceMembers RBRACE SEMICOLON + PartialInterfaceRest : IDENTIFIER LBRACE PartialInterfaceMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(location, p[1]) members = p[3] p[0] = self.handlePartialObject( - location, identifier, IDLInterface, + location, + identifier, + IDLInterface, [location, self.globalScope(), identifier, None], - [location, identifier, members]) + [location, identifier, members], + ) def p_PartialMixinRest(self, p): """ - PartialMixinRest : MIXIN IDENTIFIER LBRACE MixinMembers RBRACE SEMICOLON + PartialMixinRest : MIXIN IDENTIFIER LBRACE MixinMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) members = p[4] p[0] = self.handlePartialObject( - location, identifier, IDLInterfaceMixin, + location, + identifier, + IDLInterfaceMixin, [location, self.globalScope(), identifier], - [location, identifier, members]) + [location, identifier, members], + ) def p_PartialNamespace(self, p): """ - PartialNamespace : NAMESPACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON + PartialNamespace : NAMESPACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) members = p[4] p[0] = self.handlePartialObject( - location, identifier, IDLNamespace, + location, + identifier, + IDLNamespace, [location, self.globalScope(), identifier], - [location, identifier, members]) + [location, identifier, members], + ) def p_PartialDictionary(self, p): """ - PartialDictionary : DICTIONARY IDENTIFIER LBRACE DictionaryMembers RBRACE SEMICOLON + PartialDictionary : DICTIONARY IDENTIFIER LBRACE DictionaryMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) members = p[4] p[0] = self.handlePartialObject( - location, identifier, IDLDictionary, + location, + identifier, + IDLDictionary, [location, self.globalScope(), identifier], - [location, identifier, members]) + [location, identifier, members], + ) def p_Inheritance(self, p): """ - Inheritance : COLON ScopedName + Inheritance : COLON ScopedName """ p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2]) def p_InheritanceEmpty(self, p): """ - Inheritance : + Inheritance : """ pass def p_InterfaceMembers(self, p): """ - InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers + InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers """ p[0] = [p[2]] @@ -6260,26 +7422,26 @@ class Parser(Tokenizer): def p_InterfaceMembersEmpty(self, p): """ - InterfaceMembers : + InterfaceMembers : """ p[0] = [] def p_InterfaceMember(self, p): """ - InterfaceMember : PartialInterfaceMember - | Constructor + InterfaceMember : PartialInterfaceMember + | Constructor """ p[0] = p[1] def p_Constructor(self, p): """ - Constructor : CONSTRUCTOR LPAREN ArgumentList RPAREN SEMICOLON + Constructor : CONSTRUCTOR LPAREN ArgumentList RPAREN SEMICOLON """ p[0] = IDLConstructor(self.getLocation(p, 1), p[3], "constructor") def p_PartialInterfaceMembers(self, p): """ - PartialInterfaceMembers : ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers + PartialInterfaceMembers : ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers """ p[0] = [p[2]] @@ -6290,27 +7452,26 @@ class Parser(Tokenizer): def p_PartialInterfaceMembersEmpty(self, p): """ - PartialInterfaceMembers : + PartialInterfaceMembers : """ p[0] = [] def p_PartialInterfaceMember(self, p): """ - PartialInterfaceMember : Const - | AttributeOrOperationOrMaplikeOrSetlikeOrIterable + PartialInterfaceMember : Const + | AttributeOrOperationOrMaplikeOrSetlikeOrIterable """ p[0] = p[1] - def p_MixinMembersEmpty(self, p): """ - MixinMembers : + MixinMembers : """ p[0] = [] def p_MixinMembers(self, p): """ - MixinMembers : ExtendedAttributeList MixinMember MixinMembers + MixinMembers : ExtendedAttributeList MixinMember MixinMembers """ p[0] = [p[2]] @@ -6321,15 +7482,15 @@ class Parser(Tokenizer): def p_MixinMember(self, p): """ - MixinMember : Const - | Attribute - | Operation + MixinMember : Const + | Attribute + | Operation """ p[0] = p[1] def p_Dictionary(self, p): """ - Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON + Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) @@ -6338,8 +7499,8 @@ class Parser(Tokenizer): def p_DictionaryMembers(self, p): """ - DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers - | + DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers + | """ if len(p) == 1: # We're at the end of the list @@ -6351,21 +7512,26 @@ class Parser(Tokenizer): def p_DictionaryMemberRequired(self, p): """ - DictionaryMember : REQUIRED TypeWithExtendedAttributes IDENTIFIER SEMICOLON + DictionaryMember : REQUIRED TypeWithExtendedAttributes IDENTIFIER SEMICOLON """ # These quack a lot like required arguments, so just treat them that way. t = p[2] assert isinstance(t, IDLType) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3]) - p[0] = IDLArgument(self.getLocation(p, 3), identifier, t, - optional=False, - defaultValue=None, variadic=False, - dictionaryMember=True) + p[0] = IDLArgument( + self.getLocation(p, 3), + identifier, + t, + optional=False, + defaultValue=None, + variadic=False, + dictionaryMember=True, + ) def p_DictionaryMember(self, p): """ - DictionaryMember : Type IDENTIFIER Default SEMICOLON + DictionaryMember : Type IDENTIFIER Default SEMICOLON """ # These quack a lot like optional arguments, so just treat them that way. t = p[1] @@ -6376,15 +7542,21 @@ class Parser(Tokenizer): # Any attributes that precede this may apply to the type, so # we configure the argument to forward type attributes down instead of producing # a parse error - p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, - optional=True, - defaultValue=defaultValue, variadic=False, - dictionaryMember=True, allowTypeAttributes=True) + p[0] = IDLArgument( + self.getLocation(p, 2), + identifier, + t, + optional=True, + defaultValue=defaultValue, + variadic=False, + dictionaryMember=True, + allowTypeAttributes=True, + ) def p_Default(self, p): """ - Default : EQUALS DefaultValue - | + Default : EQUALS DefaultValue + | """ if len(p) > 1: p[0] = p[2] @@ -6393,9 +7565,9 @@ class Parser(Tokenizer): def p_DefaultValue(self, p): """ - DefaultValue : ConstValue - | LBRACKET RBRACKET - | LBRACE RBRACE + DefaultValue : ConstValue + | LBRACKET RBRACKET + | LBRACE RBRACE """ if len(p) == 2: p[0] = p[1] @@ -6409,19 +7581,25 @@ class Parser(Tokenizer): def p_DefaultValueNull(self, p): """ - DefaultValue : NULL + DefaultValue : NULL """ p[0] = IDLNullValue(self.getLocation(p, 1)) + def p_DefaultValueUndefined(self, p): + """ + DefaultValue : UNDEFINED + """ + p[0] = IDLUndefinedValue(self.getLocation(p, 1)) + def p_Exception(self, p): """ - Exception : EXCEPTION IDENTIFIER Inheritance LBRACE ExceptionMembers RBRACE SEMICOLON + Exception : EXCEPTION IDENTIFIER Inheritance LBRACE ExceptionMembers RBRACE SEMICOLON """ pass def p_Enum(self, p): """ - Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON + Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON """ location = self.getLocation(p, 1) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) @@ -6432,79 +7610,90 @@ class Parser(Tokenizer): def p_EnumValueList(self, p): """ - EnumValueList : STRING EnumValueListComma + EnumValueList : STRING EnumValueListComma """ p[0] = [p[1]] p[0].extend(p[2]) def p_EnumValueListComma(self, p): """ - EnumValueListComma : COMMA EnumValueListString + EnumValueListComma : COMMA EnumValueListString """ p[0] = p[2] def p_EnumValueListCommaEmpty(self, p): """ - EnumValueListComma : + EnumValueListComma : """ p[0] = [] def p_EnumValueListString(self, p): """ - EnumValueListString : STRING EnumValueListComma + EnumValueListString : STRING EnumValueListComma """ p[0] = [p[1]] p[0].extend(p[2]) def p_EnumValueListStringEmpty(self, p): """ - EnumValueListString : + EnumValueListString : """ p[0] = [] def p_CallbackRest(self, p): """ - CallbackRest : IDENTIFIER EQUALS ReturnType LPAREN ArgumentList RPAREN SEMICOLON + CallbackRest : IDENTIFIER EQUALS Type LPAREN ArgumentList RPAREN SEMICOLON """ identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) - p[0] = IDLCallback(self.getLocation(p, 1), self.globalScope(), - identifier, p[3], p[5], isConstructor=False) + p[0] = IDLCallback( + self.getLocation(p, 1), + self.globalScope(), + identifier, + p[3], + p[5], + isConstructor=False, + ) def p_CallbackConstructorRest(self, p): """ - CallbackConstructorRest : CONSTRUCTOR IDENTIFIER EQUALS ReturnType LPAREN ArgumentList RPAREN SEMICOLON + CallbackConstructorRest : CONSTRUCTOR IDENTIFIER EQUALS Type LPAREN ArgumentList RPAREN SEMICOLON """ identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) - p[0] = IDLCallback(self.getLocation(p, 2), self.globalScope(), - identifier, p[4], p[6], isConstructor=True) + p[0] = IDLCallback( + self.getLocation(p, 2), + self.globalScope(), + identifier, + p[4], + p[6], + isConstructor=True, + ) def p_ExceptionMembers(self, p): """ - ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers - | + ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers + | """ pass def p_Typedef(self, p): """ - Typedef : TYPEDEF TypeWithExtendedAttributes IDENTIFIER SEMICOLON + Typedef : TYPEDEF TypeWithExtendedAttributes IDENTIFIER SEMICOLON """ - typedef = IDLTypedef(self.getLocation(p, 1), self.globalScope(), - p[2], p[3]) + typedef = IDLTypedef(self.getLocation(p, 1), self.globalScope(), p[2], p[3]) p[0] = typedef def p_IncludesStatement(self, p): """ - IncludesStatement : ScopedName INCLUDES ScopedName SEMICOLON + IncludesStatement : ScopedName INCLUDES ScopedName SEMICOLON """ - assert(p[2] == "includes") + assert p[2] == "includes" interface = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1]) mixin = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3]) p[0] = IDLIncludesStatement(self.getLocation(p, 1), interface, mixin) def p_Const(self, p): """ - Const : CONST ConstType IDENTIFIER EQUALS ConstValue SEMICOLON + Const : CONST ConstType IDENTIFIER EQUALS ConstValue SEMICOLON """ location = self.getLocation(p, 1) type = p[2] @@ -6514,7 +7703,7 @@ class Parser(Tokenizer): def p_ConstValueBoolean(self, p): """ - ConstValue : BooleanLiteral + ConstValue : BooleanLiteral """ location = self.getLocation(p, 1) booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean] @@ -6522,7 +7711,7 @@ class Parser(Tokenizer): def p_ConstValueInteger(self, p): """ - ConstValue : INTEGER + ConstValue : INTEGER """ location = self.getLocation(p, 1) @@ -6536,14 +7725,16 @@ class Parser(Tokenizer): def p_ConstValueFloat(self, p): """ - ConstValue : FLOATLITERAL + ConstValue : FLOATLITERAL """ location = self.getLocation(p, 1) - p[0] = IDLValue(location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1]) + p[0] = IDLValue( + location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1] + ) def p_ConstValueString(self, p): """ - ConstValue : STRING + ConstValue : STRING """ location = self.getLocation(p, 1) stringType = BuiltinTypes[IDLBuiltinType.Types.domstring] @@ -6551,35 +7742,37 @@ class Parser(Tokenizer): def p_BooleanLiteralTrue(self, p): """ - BooleanLiteral : TRUE + BooleanLiteral : TRUE """ p[0] = True def p_BooleanLiteralFalse(self, p): """ - BooleanLiteral : FALSE + BooleanLiteral : FALSE """ p[0] = False def p_AttributeOrOperationOrMaplikeOrSetlikeOrIterable(self, p): """ - AttributeOrOperationOrMaplikeOrSetlikeOrIterable : Attribute - | Maplike - | Setlike - | Iterable - | Operation + AttributeOrOperationOrMaplikeOrSetlikeOrIterable : Attribute + | Maplike + | Setlike + | Iterable + | AsyncIterable + | Operation """ p[0] = p[1] def p_Iterable(self, p): """ - Iterable : ITERABLE LT TypeWithExtendedAttributes GT SEMICOLON - | ITERABLE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON + Iterable : ITERABLE LT TypeWithExtendedAttributes GT SEMICOLON + | ITERABLE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON """ location = self.getLocation(p, 2) - identifier = IDLUnresolvedIdentifier(location, "__iterable", - allowDoubleUnderscore=True) - if (len(p) > 6): + identifier = IDLUnresolvedIdentifier( + location, "__iterable", allowDoubleUnderscore=True + ) + if len(p) > 6: keyType = p[3] valueType = p[5] else: @@ -6588,61 +7781,98 @@ class Parser(Tokenizer): p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope()) + def p_AsyncIterable(self, p): + """ + AsyncIterable : ASYNC ITERABLE LT TypeWithExtendedAttributes GT SEMICOLON + | ASYNC ITERABLE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON + | ASYNC ITERABLE LT TypeWithExtendedAttributes GT LPAREN ArgumentList RPAREN SEMICOLON + | ASYNC ITERABLE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT LPAREN ArgumentList RPAREN SEMICOLON + """ + location = self.getLocation(p, 2) + identifier = IDLUnresolvedIdentifier( + location, "__iterable", allowDoubleUnderscore=True + ) + if len(p) == 12: + keyType = p[4] + valueType = p[6] + argList = p[9] + elif len(p) == 10: + keyType = None + valueType = p[4] + argList = p[7] + elif len(p) == 9: + keyType = p[4] + valueType = p[6] + argList = [] + else: + keyType = None + valueType = p[4] + argList = [] + + p[0] = IDLAsyncIterable( + location, identifier, keyType, valueType, argList, self.globalScope() + ) + def p_Setlike(self, p): """ - Setlike : ReadOnly SETLIKE LT TypeWithExtendedAttributes GT SEMICOLON + Setlike : ReadOnly SETLIKE LT TypeWithExtendedAttributes GT SEMICOLON """ readonly = p[1] maplikeOrSetlikeType = p[2] location = self.getLocation(p, 2) - identifier = IDLUnresolvedIdentifier(location, "__setlike", - allowDoubleUnderscore=True) + identifier = IDLUnresolvedIdentifier( + location, "__setlike", allowDoubleUnderscore=True + ) keyType = p[4] valueType = keyType - p[0] = IDLMaplikeOrSetlike(location, identifier, maplikeOrSetlikeType, - readonly, keyType, valueType) + p[0] = IDLMaplikeOrSetlike( + location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType + ) def p_Maplike(self, p): """ - Maplike : ReadOnly MAPLIKE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON + Maplike : ReadOnly MAPLIKE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON """ readonly = p[1] maplikeOrSetlikeType = p[2] location = self.getLocation(p, 2) - identifier = IDLUnresolvedIdentifier(location, "__maplike", - allowDoubleUnderscore=True) + identifier = IDLUnresolvedIdentifier( + location, "__maplike", allowDoubleUnderscore=True + ) keyType = p[4] valueType = p[6] - p[0] = IDLMaplikeOrSetlike(location, identifier, maplikeOrSetlikeType, - readonly, keyType, valueType) + p[0] = IDLMaplikeOrSetlike( + location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType + ) def p_AttributeWithQualifier(self, p): """ - Attribute : Qualifier AttributeRest + Attribute : Qualifier AttributeRest """ static = IDLInterfaceMember.Special.Static in p[1] stringifier = IDLInterfaceMember.Special.Stringifier in p[1] (location, identifier, type, readonly) = p[2] - p[0] = IDLAttribute(location, identifier, type, readonly, - static=static, stringifier=stringifier) + p[0] = IDLAttribute( + location, identifier, type, readonly, static=static, stringifier=stringifier + ) def p_AttributeInherited(self, p): """ - Attribute : INHERIT AttributeRest + Attribute : INHERIT AttributeRest """ (location, identifier, type, readonly) = p[2] p[0] = IDLAttribute(location, identifier, type, readonly, inherit=True) def p_Attribute(self, p): """ - Attribute : AttributeRest + Attribute : AttributeRest """ (location, identifier, type, readonly) = p[1] p[0] = IDLAttribute(location, identifier, type, readonly, inherit=False) def p_AttributeRest(self, p): """ - AttributeRest : ReadOnly ATTRIBUTE TypeWithExtendedAttributes AttributeName SEMICOLON + AttributeRest : ReadOnly ATTRIBUTE TypeWithExtendedAttributes AttributeName SEMICOLON """ location = self.getLocation(p, 2) readonly = p[1] @@ -6652,26 +7882,27 @@ class Parser(Tokenizer): def p_ReadOnly(self, p): """ - ReadOnly : READONLY + ReadOnly : READONLY """ p[0] = True def p_ReadOnlyEmpty(self, p): """ - ReadOnly : + ReadOnly : """ p[0] = False def p_Operation(self, p): """ - Operation : Qualifiers OperationRest + Operation : Qualifiers OperationRest """ qualifiers = p[1] # Disallow duplicates in the qualifier set if not len(set(qualifiers)) == len(qualifiers): - raise WebIDLError("Duplicate qualifiers are not allowed", - [self.getLocation(p, 1)]) + raise WebIDLError( + "Duplicate qualifiers are not allowed", [self.getLocation(p, 1)] + ) static = IDLInterfaceMember.Special.Static in p[1] # If static is there that's all that's allowed. This is disallowed @@ -6690,8 +7921,10 @@ class Parser(Tokenizer): if getter or deleter: if setter: - raise WebIDLError("getter and deleter are incompatible with setter", - [self.getLocation(p, 1)]) + raise WebIDLError( + "getter and deleter are incompatible with setter", + [self.getLocation(p, 1)], + ) (returnType, identifier, arguments) = p[2] @@ -6701,234 +7934,285 @@ class Parser(Tokenizer): if getter or deleter: if len(arguments) != 1: - raise WebIDLError("%s has wrong number of arguments" % - ("getter" if getter else "deleter"), - [self.getLocation(p, 2)]) + raise WebIDLError( + "%s has wrong number of arguments" + % ("getter" if getter else "deleter"), + [self.getLocation(p, 2)], + ) argType = arguments[0].type if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]: specialType = IDLMethod.NamedOrIndexed.Named elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]: specialType = IDLMethod.NamedOrIndexed.Indexed if deleter: - raise WebIDLError("There is no such thing as an indexed deleter.", - [self.getLocation(p, 1)]) + raise WebIDLError( + "There is no such thing as an indexed deleter.", + [self.getLocation(p, 1)], + ) else: - raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" % - ("getter" if getter else "deleter"), - [arguments[0].location]) + raise WebIDLError( + "%s has wrong argument type (must be DOMString or UnsignedLong)" + % ("getter" if getter else "deleter"), + [arguments[0].location], + ) if arguments[0].optional or arguments[0].variadic: - raise WebIDLError("%s cannot have %s argument" % - ("getter" if getter else "deleter", - "optional" if arguments[0].optional else "variadic"), - [arguments[0].location]) + raise WebIDLError( + "%s cannot have %s argument" + % ( + "getter" if getter else "deleter", + "optional" if arguments[0].optional else "variadic", + ), + [arguments[0].location], + ) if getter: if returnType.isUndefined(): - raise WebIDLError("getter cannot have undefined return type", - [self.getLocation(p, 2)]) + raise WebIDLError( + "getter cannot have undefined return type", [self.getLocation(p, 2)] + ) if setter: if len(arguments) != 2: - raise WebIDLError("setter has wrong number of arguments", - [self.getLocation(p, 2)]) + raise WebIDLError( + "setter has wrong number of arguments", [self.getLocation(p, 2)] + ) argType = arguments[0].type if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]: specialType = IDLMethod.NamedOrIndexed.Named elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]: specialType = IDLMethod.NamedOrIndexed.Indexed else: - raise WebIDLError("settter has wrong argument type (must be DOMString or UnsignedLong)", - [arguments[0].location]) + raise WebIDLError( + "settter has wrong argument type (must be DOMString or UnsignedLong)", + [arguments[0].location], + ) if arguments[0].optional or arguments[0].variadic: - raise WebIDLError("setter cannot have %s argument" % - ("optional" if arguments[0].optional else "variadic"), - [arguments[0].location]) + raise WebIDLError( + "setter cannot have %s argument" + % ("optional" if arguments[0].optional else "variadic"), + [arguments[0].location], + ) if arguments[1].optional or arguments[1].variadic: - raise WebIDLError("setter cannot have %s argument" % - ("optional" if arguments[1].optional else "variadic"), - [arguments[1].location]) + raise WebIDLError( + "setter cannot have %s argument" + % ("optional" if arguments[1].optional else "variadic"), + [arguments[1].location], + ) if stringifier: if len(arguments) != 0: - raise WebIDLError("stringifier has wrong number of arguments", - [self.getLocation(p, 2)]) + raise WebIDLError( + "stringifier has wrong number of arguments", + [self.getLocation(p, 2)], + ) if not returnType.isDOMString(): - raise WebIDLError("stringifier must have DOMString return type", - [self.getLocation(p, 2)]) + raise WebIDLError( + "stringifier must have DOMString return type", + [self.getLocation(p, 2)], + ) # identifier might be None. This is only permitted for special methods. if not identifier: - if (not getter and not setter and - not deleter and not legacycaller and not stringifier): - raise WebIDLError("Identifier required for non-special methods", - [self.getLocation(p, 2)]) + if ( + not getter + and not setter + and not deleter + and not legacycaller + and not stringifier + ): + raise WebIDLError( + "Identifier required for non-special methods", + [self.getLocation(p, 2)], + ) location = BuiltinLocation("<auto-generated-identifier>") identifier = IDLUnresolvedIdentifier( location, - "__%s%s%s%s%s%s" % - ("named" if specialType == IDLMethod.NamedOrIndexed.Named else - "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "", - "getter" if getter else "", - "setter" if setter else "", - "deleter" if deleter else "", - "legacycaller" if legacycaller else "", - "stringifier" if stringifier else ""), - allowDoubleUnderscore=True) - - method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments, - static=static, getter=getter, setter=setter, - deleter=deleter, specialType=specialType, - legacycaller=legacycaller, stringifier=stringifier) + "__%s%s%s%s%s%s" + % ( + "named" + if specialType == IDLMethod.NamedOrIndexed.Named + else "indexed" + if specialType == IDLMethod.NamedOrIndexed.Indexed + else "", + "getter" if getter else "", + "setter" if setter else "", + "deleter" if deleter else "", + "legacycaller" if legacycaller else "", + "stringifier" if stringifier else "", + ), + allowDoubleUnderscore=True, + ) + + method = IDLMethod( + self.getLocation(p, 2), + identifier, + returnType, + arguments, + static=static, + getter=getter, + setter=setter, + deleter=deleter, + specialType=specialType, + legacycaller=legacycaller, + stringifier=stringifier, + ) p[0] = method def p_Stringifier(self, p): """ - Operation : STRINGIFIER SEMICOLON + Operation : STRINGIFIER SEMICOLON """ - identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), - "__stringifier", - allowDoubleUnderscore=True) - method = IDLMethod(self.getLocation(p, 1), - identifier, - returnType=BuiltinTypes[IDLBuiltinType.Types.domstring], - arguments=[], - stringifier=True) + identifier = IDLUnresolvedIdentifier( + BuiltinLocation("<auto-generated-identifier>"), + "__stringifier", + allowDoubleUnderscore=True, + ) + method = IDLMethod( + self.getLocation(p, 1), + identifier, + returnType=BuiltinTypes[IDLBuiltinType.Types.domstring], + arguments=[], + stringifier=True, + ) p[0] = method def p_QualifierStatic(self, p): """ - Qualifier : STATIC + Qualifier : STATIC """ p[0] = [IDLInterfaceMember.Special.Static] def p_QualifierStringifier(self, p): """ - Qualifier : STRINGIFIER + Qualifier : STRINGIFIER """ p[0] = [IDLInterfaceMember.Special.Stringifier] def p_Qualifiers(self, p): """ - Qualifiers : Qualifier - | Specials + Qualifiers : Qualifier + | Specials """ p[0] = p[1] def p_Specials(self, p): """ - Specials : Special Specials + Specials : Special Specials """ p[0] = [p[1]] p[0].extend(p[2]) def p_SpecialsEmpty(self, p): """ - Specials : + Specials : """ p[0] = [] def p_SpecialGetter(self, p): """ - Special : GETTER + Special : GETTER """ p[0] = IDLMethod.Special.Getter def p_SpecialSetter(self, p): """ - Special : SETTER + Special : SETTER """ p[0] = IDLMethod.Special.Setter def p_SpecialDeleter(self, p): """ - Special : DELETER + Special : DELETER """ p[0] = IDLMethod.Special.Deleter def p_SpecialLegacyCaller(self, p): """ - Special : LEGACYCALLER + Special : LEGACYCALLER """ p[0] = IDLMethod.Special.LegacyCaller def p_OperationRest(self, p): """ - OperationRest : ReturnType OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON + OperationRest : Type OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON """ p[0] = (p[1], p[2], p[4]) def p_OptionalIdentifier(self, p): """ - OptionalIdentifier : IDENTIFIER + OptionalIdentifier : IDENTIFIER """ p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) def p_OptionalIdentifierEmpty(self, p): """ - OptionalIdentifier : + OptionalIdentifier : """ pass def p_ArgumentList(self, p): """ - ArgumentList : Argument Arguments + ArgumentList : Argument Arguments """ p[0] = [p[1]] if p[1] else [] p[0].extend(p[2]) def p_ArgumentListEmpty(self, p): """ - ArgumentList : + ArgumentList : """ p[0] = [] def p_Arguments(self, p): """ - Arguments : COMMA Argument Arguments + Arguments : COMMA Argument Arguments """ p[0] = [p[2]] if p[2] else [] p[0].extend(p[3]) def p_ArgumentsEmpty(self, p): """ - Arguments : + Arguments : """ p[0] = [] def p_Argument(self, p): """ - Argument : ExtendedAttributeList ArgumentRest + Argument : ExtendedAttributeList ArgumentRest """ p[0] = p[2] p[0].addExtendedAttributes(p[1]) def p_ArgumentRestOptional(self, p): """ - ArgumentRest : OPTIONAL TypeWithExtendedAttributes ArgumentName Default + ArgumentRest : OPTIONAL TypeWithExtendedAttributes ArgumentName Default """ t = p[2] assert isinstance(t, IDLType) # Arg names can be reserved identifiers - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3], - allowForbidden=True) + identifier = IDLUnresolvedIdentifier( + self.getLocation(p, 3), p[3], allowForbidden=True + ) defaultValue = p[4] - # We can't test t.isAny() here and give it a default value as needed, # since at this point t is not a fully resolved type yet (e.g. it might # be a typedef). We'll handle the 'any' case in IDLArgument.complete. - p[0] = IDLArgument(self.getLocation(p, 3), identifier, t, True, defaultValue, False) + p[0] = IDLArgument( + self.getLocation(p, 3), identifier, t, True, defaultValue, False + ) def p_ArgumentRest(self, p): """ - ArgumentRest : Type Ellipsis ArgumentName + ArgumentRest : Type Ellipsis ArgumentName """ t = p[1] assert isinstance(t, IDLType) # Arg names can be reserved identifiers - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3], - allowForbidden=True) + identifier = IDLUnresolvedIdentifier( + self.getLocation(p, 3), p[3], allowForbidden=True + ) variadic = p[2] @@ -6940,90 +8224,98 @@ class Parser(Tokenizer): # Any attributes that precede this may apply to the type, so # we configure the argument to forward type attributes down instead of producing # a parse error - p[0] = IDLArgument(self.getLocation(p, 3), identifier, t, variadic, None, variadic, allowTypeAttributes=True) + p[0] = IDLArgument( + self.getLocation(p, 3), + identifier, + t, + variadic, + None, + variadic, + allowTypeAttributes=True, + ) def p_ArgumentName(self, p): """ - ArgumentName : IDENTIFIER - | ArgumentNameKeyword + ArgumentName : IDENTIFIER + | ArgumentNameKeyword """ p[0] = p[1] def p_ArgumentNameKeyword(self, p): """ - ArgumentNameKeyword : ASYNC - | ATTRIBUTE - | CALLBACK - | CONST - | CONSTRUCTOR - | DELETER - | DICTIONARY - | ENUM - | EXCEPTION - | GETTER - | INCLUDES - | INHERIT - | INTERFACE - | ITERABLE - | LEGACYCALLER - | MAPLIKE - | MIXIN - | NAMESPACE - | PARTIAL - | READONLY - | REQUIRED - | SERIALIZER - | SETLIKE - | SETTER - | STATIC - | STRINGIFIER - | TYPEDEF - | UNRESTRICTED + ArgumentNameKeyword : ASYNC + | ATTRIBUTE + | CALLBACK + | CONST + | CONSTRUCTOR + | DELETER + | DICTIONARY + | ENUM + | EXCEPTION + | GETTER + | INCLUDES + | INHERIT + | INTERFACE + | ITERABLE + | LEGACYCALLER + | MAPLIKE + | MIXIN + | NAMESPACE + | PARTIAL + | READONLY + | REQUIRED + | SERIALIZER + | SETLIKE + | SETTER + | STATIC + | STRINGIFIER + | TYPEDEF + | UNRESTRICTED """ p[0] = p[1] def p_AttributeName(self, p): """ - AttributeName : IDENTIFIER - | AttributeNameKeyword + AttributeName : IDENTIFIER + | AttributeNameKeyword """ p[0] = p[1] def p_AttributeNameKeyword(self, p): """ - AttributeNameKeyword : ASYNC - | REQUIRED + AttributeNameKeyword : ASYNC + | REQUIRED """ p[0] = p[1] def p_Ellipsis(self, p): """ - Ellipsis : ELLIPSIS + Ellipsis : ELLIPSIS """ p[0] = True def p_EllipsisEmpty(self, p): """ - Ellipsis : + Ellipsis : """ p[0] = False def p_ExceptionMember(self, p): """ - ExceptionMember : Const - | ExceptionField + ExceptionMember : Const + | ExceptionField """ pass def p_ExceptionField(self, p): """ - ExceptionField : Type IDENTIFIER SEMICOLON + ExceptionField : Type IDENTIFIER SEMICOLON """ pass def p_ExtendedAttributeList(self, p): """ - ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET + ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET """ p[0] = [p[2]] if p[3]: @@ -7031,131 +8323,131 @@ class Parser(Tokenizer): def p_ExtendedAttributeListEmpty(self, p): """ - ExtendedAttributeList : + ExtendedAttributeList : """ p[0] = [] def p_ExtendedAttribute(self, p): """ - ExtendedAttribute : ExtendedAttributeNoArgs - | ExtendedAttributeArgList - | ExtendedAttributeIdent - | ExtendedAttributeNamedArgList - | ExtendedAttributeIdentList + ExtendedAttribute : ExtendedAttributeNoArgs + | ExtendedAttributeArgList + | ExtendedAttributeIdent + | ExtendedAttributeWildcard + | ExtendedAttributeNamedArgList + | ExtendedAttributeIdentList """ p[0] = IDLExtendedAttribute(self.getLocation(p, 1), p[1]) def p_ExtendedAttributeEmpty(self, p): """ - ExtendedAttribute : + ExtendedAttribute : """ pass def p_ExtendedAttributes(self, p): """ - ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes + ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes """ p[0] = [p[2]] if p[2] else [] p[0].extend(p[3]) def p_ExtendedAttributesEmpty(self, p): """ - ExtendedAttributes : + ExtendedAttributes : """ p[0] = [] def p_Other(self, p): """ - Other : INTEGER - | FLOATLITERAL - | IDENTIFIER - | STRING - | OTHER - | ELLIPSIS - | COLON - | SCOPE - | SEMICOLON - | LT - | EQUALS - | GT - | QUESTIONMARK - | DOMSTRING - | BYTESTRING - | USVSTRING - | UTF8STRING - | JSSTRING - | PROMISE - | ANY - | BOOLEAN - | BYTE - | DOUBLE - | FALSE - | FLOAT - | LONG - | NULL - | OBJECT - | OCTET - | OR - | OPTIONAL - | RECORD - | SEQUENCE - | SHORT - | SYMBOL - | TRUE - | UNSIGNED - | UNDEFINED - | ArgumentNameKeyword + Other : INTEGER + | FLOATLITERAL + | IDENTIFIER + | STRING + | OTHER + | ELLIPSIS + | COLON + | SCOPE + | SEMICOLON + | LT + | EQUALS + | GT + | QUESTIONMARK + | ASTERISK + | DOMSTRING + | BYTESTRING + | USVSTRING + | UTF8STRING + | JSSTRING + | PROMISE + | ANY + | BOOLEAN + | BYTE + | DOUBLE + | FALSE + | FLOAT + | LONG + | NULL + | OBJECT + | OCTET + | OR + | OPTIONAL + | RECORD + | SEQUENCE + | SHORT + | SYMBOL + | TRUE + | UNSIGNED + | UNDEFINED + | ArgumentNameKeyword """ pass def p_OtherOrComma(self, p): """ - OtherOrComma : Other - | COMMA + OtherOrComma : Other + | COMMA """ pass def p_TypeSingleType(self, p): """ - Type : SingleType + Type : SingleType """ p[0] = p[1] def p_TypeUnionType(self, p): """ - Type : UnionType Null + Type : UnionType Null """ p[0] = self.handleNullable(p[1], p[2]) def p_TypeWithExtendedAttributes(self, p): """ - TypeWithExtendedAttributes : ExtendedAttributeList Type + TypeWithExtendedAttributes : ExtendedAttributeList Type """ p[0] = p[2].withExtendedAttributes(p[1]) def p_SingleTypeDistinguishableType(self, p): """ - SingleType : DistinguishableType + SingleType : DistinguishableType """ p[0] = p[1] def p_SingleTypeAnyType(self, p): """ - SingleType : ANY + SingleType : ANY """ p[0] = BuiltinTypes[IDLBuiltinType.Types.any] - # Note: Promise<undefined> is allowed, so we want to parametrize on ReturnType, - # not Type. Promise types can't be null, hence no "Null" in there. def p_SingleTypePromiseType(self, p): """ - SingleType : PROMISE LT ReturnType GT + SingleType : PROMISE LT Type GT """ p[0] = IDLPromiseType(self.getLocation(p, 1), p[3]) def p_UnionType(self, p): """ - UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN + UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN """ types = [p[2], p[4]] types.extend(p[5]) @@ -7163,42 +8455,42 @@ class Parser(Tokenizer): def p_UnionMemberTypeDistinguishableType(self, p): """ - UnionMemberType : ExtendedAttributeList DistinguishableType + UnionMemberType : ExtendedAttributeList DistinguishableType """ p[0] = p[2].withExtendedAttributes(p[1]) def p_UnionMemberType(self, p): """ - UnionMemberType : UnionType Null + UnionMemberType : UnionType Null """ p[0] = self.handleNullable(p[1], p[2]) def p_UnionMemberTypes(self, p): """ - UnionMemberTypes : OR UnionMemberType UnionMemberTypes + UnionMemberTypes : OR UnionMemberType UnionMemberTypes """ p[0] = [p[2]] p[0].extend(p[3]) def p_UnionMemberTypesEmpty(self, p): """ - UnionMemberTypes : + UnionMemberTypes : """ p[0] = [] def p_DistinguishableType(self, p): """ - DistinguishableType : PrimitiveType Null - | ARRAYBUFFER Null - | READABLESTREAM Null - | OBJECT Null + DistinguishableType : PrimitiveType Null + | ARRAYBUFFER Null + | OBJECT Null + | UNDEFINED Null """ if p[1] == "object": type = BuiltinTypes[IDLBuiltinType.Types.object] elif p[1] == "ArrayBuffer": type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer] - elif p[1] == "ReadableStream": - type = BuiltinTypes[IDLBuiltinType.Types.ReadableStream] + elif p[1] == "undefined": + type = BuiltinTypes[IDLBuiltinType.Types.undefined] else: type = BuiltinTypes[p[1]] @@ -7206,13 +8498,13 @@ class Parser(Tokenizer): def p_DistinguishableTypeStringType(self, p): """ - DistinguishableType : StringType Null + DistinguishableType : StringType Null """ p[0] = self.handleNullable(p[1], p[2]) def p_DistinguishableTypeSequenceType(self, p): """ - DistinguishableType : SEQUENCE LT TypeWithExtendedAttributes GT Null + DistinguishableType : SEQUENCE LT TypeWithExtendedAttributes GT Null """ innerType = p[3] type = IDLSequenceType(self.getLocation(p, 1), innerType) @@ -7220,23 +8512,32 @@ class Parser(Tokenizer): def p_DistinguishableTypeRecordType(self, p): """ - DistinguishableType : RECORD LT StringType COMMA TypeWithExtendedAttributes GT Null + DistinguishableType : RECORD LT StringType COMMA TypeWithExtendedAttributes GT Null """ keyType = p[3] valueType = p[5] type = IDLRecordType(self.getLocation(p, 1), keyType, valueType) p[0] = self.handleNullable(type, p[7]) + def p_DistinguishableTypeObservableArrayType(self, p): + """ + DistinguishableType : OBSERVABLEARRAY LT TypeWithExtendedAttributes GT Null + """ + innerType = p[3] + type = IDLObservableArrayType(self.getLocation(p, 1), innerType) + p[0] = self.handleNullable(type, p[5]) + def p_DistinguishableTypeScopedName(self, p): """ - DistinguishableType : ScopedName Null + DistinguishableType : ScopedName Null """ assert isinstance(p[1], IDLUnresolvedIdentifier) if p[1].name == "Promise": - raise WebIDLError("Promise used without saying what it's " - "parametrized over", - [self.getLocation(p, 1)]) + raise WebIDLError( + "Promise used without saying what it's " "parametrized over", + [self.getLocation(p, 1)], + ) type = None @@ -7245,8 +8546,9 @@ class Parser(Tokenizer): obj = self.globalScope()._lookupIdentifier(p[1]) assert not obj.isType() if obj.isTypedef(): - type = IDLTypedefType(self.getLocation(p, 1), obj.innerType, - obj.identifier.name) + type = IDLTypedefType( + self.getLocation(p, 1), obj.innerType, obj.identifier.name + ) elif obj.isCallback() and not obj.isInterface(): type = IDLCallbackType(obj.location, obj) else: @@ -7261,13 +8563,13 @@ class Parser(Tokenizer): def p_ConstType(self, p): """ - ConstType : PrimitiveType + ConstType : PrimitiveType """ p[0] = BuiltinTypes[p[1]] def p_ConstTypeIdentifier(self, p): """ - ConstType : IDENTIFIER + ConstType : IDENTIFIER """ identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) @@ -7275,110 +8577,110 @@ class Parser(Tokenizer): def p_PrimitiveTypeUint(self, p): """ - PrimitiveType : UnsignedIntegerType + PrimitiveType : UnsignedIntegerType """ p[0] = p[1] def p_PrimitiveTypeBoolean(self, p): """ - PrimitiveType : BOOLEAN + PrimitiveType : BOOLEAN """ p[0] = IDLBuiltinType.Types.boolean def p_PrimitiveTypeByte(self, p): """ - PrimitiveType : BYTE + PrimitiveType : BYTE """ p[0] = IDLBuiltinType.Types.byte def p_PrimitiveTypeOctet(self, p): """ - PrimitiveType : OCTET + PrimitiveType : OCTET """ p[0] = IDLBuiltinType.Types.octet def p_PrimitiveTypeFloat(self, p): """ - PrimitiveType : FLOAT + PrimitiveType : FLOAT """ p[0] = IDLBuiltinType.Types.float def p_PrimitiveTypeUnrestictedFloat(self, p): """ - PrimitiveType : UNRESTRICTED FLOAT + PrimitiveType : UNRESTRICTED FLOAT """ p[0] = IDLBuiltinType.Types.unrestricted_float def p_PrimitiveTypeDouble(self, p): """ - PrimitiveType : DOUBLE + PrimitiveType : DOUBLE """ p[0] = IDLBuiltinType.Types.double def p_PrimitiveTypeUnrestictedDouble(self, p): """ - PrimitiveType : UNRESTRICTED DOUBLE + PrimitiveType : UNRESTRICTED DOUBLE """ p[0] = IDLBuiltinType.Types.unrestricted_double def p_StringType(self, p): """ - StringType : BuiltinStringType + StringType : BuiltinStringType """ p[0] = BuiltinTypes[p[1]] def p_BuiltinStringTypeDOMString(self, p): """ - BuiltinStringType : DOMSTRING + BuiltinStringType : DOMSTRING """ p[0] = IDLBuiltinType.Types.domstring def p_BuiltinStringTypeBytestring(self, p): """ - BuiltinStringType : BYTESTRING + BuiltinStringType : BYTESTRING """ p[0] = IDLBuiltinType.Types.bytestring def p_BuiltinStringTypeUSVString(self, p): """ - BuiltinStringType : USVSTRING + BuiltinStringType : USVSTRING """ p[0] = IDLBuiltinType.Types.usvstring def p_BuiltinStringTypeUTF8String(self, p): """ - BuiltinStringType : UTF8STRING + BuiltinStringType : UTF8STRING """ p[0] = IDLBuiltinType.Types.utf8string def p_BuiltinStringTypeJSString(self, p): """ - BuiltinStringType : JSSTRING + BuiltinStringType : JSSTRING """ p[0] = IDLBuiltinType.Types.jsstring def p_UnsignedIntegerTypeUnsigned(self, p): """ - UnsignedIntegerType : UNSIGNED IntegerType + UnsignedIntegerType : UNSIGNED IntegerType """ # Adding one to a given signed integer type gets you the unsigned type: p[0] = p[2] + 1 def p_UnsignedIntegerType(self, p): """ - UnsignedIntegerType : IntegerType + UnsignedIntegerType : IntegerType """ p[0] = p[1] def p_IntegerTypeShort(self, p): """ - IntegerType : SHORT + IntegerType : SHORT """ p[0] = IDLBuiltinType.Types.short def p_IntegerTypeLong(self, p): """ - IntegerType : LONG OptionalLong + IntegerType : LONG OptionalLong """ if p[2]: p[0] = IDLBuiltinType.Types.long_long @@ -7387,55 +8689,43 @@ class Parser(Tokenizer): def p_OptionalLong(self, p): """ - OptionalLong : LONG + OptionalLong : LONG """ p[0] = True def p_OptionalLongEmpty(self, p): """ - OptionalLong : + OptionalLong : """ p[0] = False def p_Null(self, p): """ - Null : QUESTIONMARK - | + Null : QUESTIONMARK + | """ if len(p) > 1: p[0] = self.getLocation(p, 1) else: p[0] = None - def p_ReturnTypeType(self, p): - """ - ReturnType : Type - """ - p[0] = p[1] - - def p_ReturnTypeUndefined(self, p): - """ - ReturnType : UNDEFINED - """ - p[0] = BuiltinTypes[IDLBuiltinType.Types.undefined] - def p_ScopedName(self, p): """ - ScopedName : AbsoluteScopedName - | RelativeScopedName + ScopedName : AbsoluteScopedName + | RelativeScopedName """ p[0] = p[1] def p_AbsoluteScopedName(self, p): """ - AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts + AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts """ assert False pass def p_RelativeScopedName(self, p): """ - RelativeScopedName : IDENTIFIER ScopedNameParts + RelativeScopedName : IDENTIFIER ScopedNameParts """ assert not p[2] # Not implemented! @@ -7443,100 +8733,122 @@ class Parser(Tokenizer): def p_ScopedNameParts(self, p): """ - ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts + ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts """ assert False pass def p_ScopedNamePartsEmpty(self, p): """ - ScopedNameParts : + ScopedNameParts : """ p[0] = None def p_ExtendedAttributeNoArgs(self, p): """ - ExtendedAttributeNoArgs : IDENTIFIER + ExtendedAttributeNoArgs : IDENTIFIER """ p[0] = (p[1],) def p_ExtendedAttributeArgList(self, p): """ - ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN + ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN """ p[0] = (p[1], p[3]) def p_ExtendedAttributeIdent(self, p): """ - ExtendedAttributeIdent : IDENTIFIER EQUALS STRING - | IDENTIFIER EQUALS IDENTIFIER + ExtendedAttributeIdent : IDENTIFIER EQUALS STRING + | IDENTIFIER EQUALS IDENTIFIER + """ + p[0] = (p[1], p[3]) + + def p_ExtendedAttributeWildcard(self, p): + """ + ExtendedAttributeWildcard : IDENTIFIER EQUALS ASTERISK """ p[0] = (p[1], p[3]) def p_ExtendedAttributeNamedArgList(self, p): """ - ExtendedAttributeNamedArgList : IDENTIFIER EQUALS IDENTIFIER LPAREN ArgumentList RPAREN + ExtendedAttributeNamedArgList : IDENTIFIER EQUALS IDENTIFIER LPAREN ArgumentList RPAREN """ p[0] = (p[1], p[3], p[5]) def p_ExtendedAttributeIdentList(self, p): """ - ExtendedAttributeIdentList : IDENTIFIER EQUALS LPAREN IdentifierList RPAREN + ExtendedAttributeIdentList : IDENTIFIER EQUALS LPAREN IdentifierList RPAREN """ p[0] = (p[1], p[4]) def p_IdentifierList(self, p): """ - IdentifierList : IDENTIFIER Identifiers + IdentifierList : IDENTIFIER Identifiers """ idents = list(p[2]) # This is only used for identifier-list-valued extended attributes, and if # we're going to restrict to IDENTIFIER here we should at least allow # escaping with leading '_' as usual for identifiers. ident = p[1] - if ident[0] == '_': + if ident[0] == "_": ident = ident[1:] idents.insert(0, ident) p[0] = idents def p_IdentifiersList(self, p): """ - Identifiers : COMMA IDENTIFIER Identifiers + Identifiers : COMMA IDENTIFIER Identifiers """ idents = list(p[3]) # This is only used for identifier-list-valued extended attributes, and if # we're going to restrict to IDENTIFIER here we should at least allow # escaping with leading '_' as usual for identifiers. ident = p[2] - if ident[0] == '_': + if ident[0] == "_": ident = ident[1:] idents.insert(0, ident) p[0] = idents def p_IdentifiersEmpty(self, p): """ - Identifiers : + Identifiers : """ p[0] = [] def p_error(self, p): if not p: - raise WebIDLError("Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both", - [self._filename]) + raise WebIDLError( + "Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both", + [self._filename], + ) else: - raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)]) + raise WebIDLError( + "invalid syntax", + [Location(self.lexer, p.lineno, p.lexpos, self._filename)], + ) - def __init__(self, outputdir='', lexer=None): - Tokenizer.__init__(self, lexer) + def __init__(self, outputdir="", lexer=None): + Tokenizer.__init__(self, outputdir, lexer) logger = SqueakyCleanLogger() try: - self.parser = yacc.yacc(module=self, errorlog=logger, debug=False) + self.parser = yacc.yacc( + module=self, + outputdir=outputdir, + errorlog=logger, + debug=False, + write_tables=False, + # Pickling the grammar is a speedup in + # some cases (older Python?) but a + # significant slowdown in others. + # We're not pickling for now, until it + # becomes a speedup again. + # , picklefile='WebIDLGrammar.pkl' + ) finally: logger.reportGrammarErrors() self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None) - self._installBuiltins(self._globalScope) self._productions = [] @@ -7550,12 +8862,16 @@ class Parser(Tokenizer): assert isinstance(scope, IDLScope) # range omits the last value. - for x in range(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1): + for x in range( + IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1 + ): builtin = BuiltinTypes[x] name = builtin.name - typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name) + typedef = IDLTypedef( + BuiltinLocation("<builtin type>"), scope, builtin, name + ) - @ staticmethod + @staticmethod def handleNullable(type, questionMarkLocation): if questionMarkLocation is not None: type = IDLNullableType(questionMarkLocation, type) @@ -7563,12 +8879,12 @@ class Parser(Tokenizer): return type def parse(self, t, filename=None): - self._filename = filename - self.lexer.input(t.decode(encoding = 'utf-8')) + self.lexer.input(t) # for tok in iter(self.lexer.token, None): # print tok + self._filename = filename self._productions.extend(self.parser.parse(lexer=self.lexer, tracking=True)) self._filename = None @@ -7580,7 +8896,6 @@ class Parser(Tokenizer): if isinstance(p, IDLInterface): interfaceStatements.append(p) - iterableIteratorIface = None for iface in interfaceStatements: iterable = None # We haven't run finish() on the interface yet, so we don't know @@ -7588,26 +8903,77 @@ class Parser(Tokenizer): # means we have to loop through the members to see if we have an # iterable member. for m in iface.members: - if isinstance(m, IDLIterable): + if isinstance(m, (IDLIterable, IDLAsyncIterable)): iterable = m break - if iterable and iterable.isPairIterator(): + if iterable and (iterable.isPairIterator() or iterable.isAsyncIterable()): + def simpleExtendedAttr(str): - return IDLExtendedAttribute(iface.location, (str, )) + return IDLExtendedAttribute(iface.location, (str,)) + + if isinstance(iterable, IDLAsyncIterable): + nextReturnType = IDLPromiseType( + iterable.location, BuiltinTypes[IDLBuiltinType.Types.any] + ) + else: + nextReturnType = BuiltinTypes[IDLBuiltinType.Types.object] nextMethod = IDLMethod( - iface.location, - IDLUnresolvedIdentifier(iface.location, "next"), - BuiltinTypes[IDLBuiltinType.Types.object], []) + iterable.location, + IDLUnresolvedIdentifier(iterable.location, "next"), + nextReturnType, + [], + ) nextMethod.addExtendedAttributes([simpleExtendedAttr("Throws")]) - itr_ident = IDLUnresolvedIdentifier(iface.location, - iface.identifier.name + "Iterator") - toStringTag = iface.identifier.name + " Iterator" - itr_iface = IDLInterface(iface.location, self.globalScope(), - itr_ident, None, [nextMethod], - isKnownNonPartial=True, - classNameOverride=toStringTag, - toStringTag=toStringTag) - itr_iface.addExtendedAttributes([simpleExtendedAttr("NoInterfaceObject")]) + + methods = [nextMethod] + + if iterable.getExtendedAttribute("GenerateReturnMethod"): + assert isinstance(iterable, IDLAsyncIterable) + + returnMethod = IDLMethod( + iterable.location, + IDLUnresolvedIdentifier(iterable.location, "return"), + IDLPromiseType( + iterable.location, BuiltinTypes[IDLBuiltinType.Types.any] + ), + [ + IDLArgument( + iterable.location, + IDLUnresolvedIdentifier( + BuiltinLocation("<auto-generated-identifier>"), + "value", + ), + BuiltinTypes[IDLBuiltinType.Types.any], + optional=True, + ), + ], + ) + returnMethod.addExtendedAttributes([simpleExtendedAttr("Throws")]) + methods.append(returnMethod) + + if iterable.isIterable(): + itr_suffix = "Iterator" + else: + itr_suffix = "AsyncIterator" + itr_ident = IDLUnresolvedIdentifier( + iface.location, iface.identifier.name + itr_suffix + ) + if iterable.isIterable(): + classNameOverride = iface.identifier.name + " Iterator" + elif iterable.isAsyncIterable(): + classNameOverride = iface.identifier.name + " AsyncIterator" + itr_iface = IDLInterface( + iface.location, + self.globalScope(), + itr_ident, + None, + methods, + isKnownNonPartial=True, + classNameOverride=classNameOverride, + ) + itr_iface.addExtendedAttributes( + [simpleExtendedAttr("LegacyNoInterfaceObject")] + ) # Make sure the exposure set for the iterator interface is the # same as the exposure set for the iterable interface, because # we're going to generate methods on the iterable that return @@ -7616,17 +8982,22 @@ class Parser(Tokenizer): # Always append generated iterable interfaces after the # interface they're a member of, otherwise nativeType generation # won't work correctly. - itr_iface.iterableInterface = iface + if iterable.isIterable(): + itr_iface.iterableInterface = iface + else: + itr_iface.asyncIterableInterface = iface self._productions.append(itr_iface) iterable.iteratorType = IDLWrapperType(iface.location, itr_iface) # Make sure we finish IDLIncludesStatements before we finish the # IDLInterfaces. # XXX khuey hates this bit and wants to nuke it from orbit. - includesStatements = [p for p in self._productions if - isinstance(p, IDLIncludesStatement)] - otherStatements = [p for p in self._productions if - not isinstance(p, IDLIncludesStatement)] + includesStatements = [ + p for p in self._productions if isinstance(p, IDLIncludesStatement) + ] + otherStatements = [ + p for p in self._productions if not isinstance(p, IDLIncludesStatement) + ] for production in includesStatements: production.finish(self.globalScope()) for production in otherStatements: @@ -7650,7 +9021,6 @@ class Parser(Tokenizer): # Builtin IDL defined by WebIDL _builtins = """ - typedef unsigned long long DOMTimeStamp; typedef (ArrayBufferView or ArrayBuffer) BufferSource; """ @@ -7658,12 +9028,21 @@ class Parser(Tokenizer): def main(): # Parse arguments. from optparse import OptionParser + usageString = "usage: %prog [options] files" o = OptionParser(usage=usageString) - o.add_option("--cachedir", dest='cachedir', default=None, - help="Directory in which to cache lex/parse tables.") - o.add_option("--verbose-errors", action='store_true', default=False, - help="When an error happens, display the Python traceback.") + o.add_option( + "--cachedir", + dest="cachedir", + default=None, + help="Directory in which to cache lex/parse tables.", + ) + o.add_option( + "--verbose-errors", + action="store_true", + default=False, + help="When an error happens, display the Python traceback.", + ) (options, args) = o.parse_args() if len(args) < 1: @@ -7677,11 +9056,11 @@ def main(): try: for filename in fileList: fullPath = os.path.normpath(os.path.join(baseDir, filename)) - f = open(fullPath, 'rb') + f = open(fullPath, "rb") lines = f.readlines() f.close() print(fullPath) - parser.parse(''.join(lines), fullPath) + parser.parse("".join(lines), fullPath) parser.finish() except WebIDLError as e: if options.verbose_errors: @@ -7689,5 +9068,6 @@ def main(): else: print(e) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_any_null.py b/components/script/dom/bindings/codegen/parser/tests/test_any_null.py index e3b690bf6f1..f9afdacb02f 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_any_null.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_any_null.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DoubleNull { attribute any? foo; }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py b/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py index 9ae85531fa3..3f50cb05158 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface ArgumentIdentifierConflict { undefined foo(boolean arg1, boolean arg1); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py b/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py index 2b29658d678..bbed33df926 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py @@ -1,17 +1,22 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface Foo { undefined foo(object constructor); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 1, "Should have an interface"); - iface = results[0]; - harness.check(len(iface.members), 1, "Should have an operation"); - operation = iface.members[0]; - harness.check(len(operation.signatures()), 1, "Should have one signature"); - (retval, args) = operation.signatures()[0]; - harness.check(len(args), 1, "Should have an argument"); - harness.check(args[0].identifier.name, "constructor", - "Should have an identifier named 'constructor'"); + harness.check(len(results), 1, "Should have an interface") + iface = results[0] + harness.check(len(iface.members), 1, "Should have an operation") + operation = iface.members[0] + harness.check(len(operation.signatures()), 1, "Should have one signature") + (retval, args) = operation.signatures()[0] + harness.check(len(args), 1, "Should have an argument") + harness.check( + args[0].identifier.name, + "constructor", + "Should have an identifier named 'constructor'", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py b/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py deleted file mode 100644 index 42e0776e677..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_argument_novoid.py +++ /dev/null @@ -1,14 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse(""" - interface UndefinedArgument1 { - undefined foo(undefined arg2); - }; - """) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py b/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py index 7020db59f3e..b762d06ac29 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestArrayBuffer { attribute ArrayBuffer bufferAttr; undefined bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3); @@ -36,7 +38,8 @@ def WebIDLTest(parser, harness): attribute Float64Array float64ArrayAttr; undefined float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3); }; - """) + """ + ) results = parser.finish() @@ -55,24 +58,35 @@ def WebIDLTest(parser, harness): harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface") (retType, arguments) = method.signatures()[0] - harness.ok(retType.isUndefined(), "Should have a undefined return type") + harness.ok(retType.isUndefined(), "Should have an undefined return type") harness.check(len(arguments), 3, "Expect 3 arguments") - harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type") - harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface") - - harness.check(str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type") - harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface") - - harness.check(str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type") - harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface") - - - checkStuff(members[0], members[1], "ArrayBuffer") - checkStuff(members[2], members[3], "ArrayBufferView") - checkStuff(members[4], members[5], "Int8Array") - checkStuff(members[6], members[7], "Uint8Array") - checkStuff(members[8], members[9], "Uint8ClampedArray") + harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type") + harness.ok( + arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface" + ) + + harness.check( + str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type" + ) + harness.ok( + arguments[1].type.inner.isSpiderMonkeyInterface(), + "Should test as a js interface", + ) + + harness.check( + str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type" + ) + harness.ok( + arguments[2].type.inner.isSpiderMonkeyInterface(), + "Should test as a js interface", + ) + + checkStuff(members[0], members[1], "ArrayBuffer") + checkStuff(members[2], members[3], "ArrayBufferView") + checkStuff(members[4], members[5], "Int8Array") + checkStuff(members[6], members[7], "Uint8Array") + checkStuff(members[8], members[9], "Uint8ClampedArray") checkStuff(members[10], members[11], "Int16Array") checkStuff(members[12], members[13], "Uint16Array") checkStuff(members[14], members[15], "Int32Array") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_attr.py index 35f680aaa82..e19689a81a9 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_attr.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_attr.py @@ -1,31 +1,35 @@ import WebIDL + def WebIDLTest(parser, harness): - testData = [("::TestAttr%s::b", "b", "Byte%s", False), - ("::TestAttr%s::rb", "rb", "Byte%s", True), - ("::TestAttr%s::o", "o", "Octet%s", False), - ("::TestAttr%s::ro", "ro", "Octet%s", True), - ("::TestAttr%s::s", "s", "Short%s", False), - ("::TestAttr%s::rs", "rs", "Short%s", True), - ("::TestAttr%s::us", "us", "UnsignedShort%s", False), - ("::TestAttr%s::rus", "rus", "UnsignedShort%s", True), - ("::TestAttr%s::l", "l", "Long%s", False), - ("::TestAttr%s::rl", "rl", "Long%s", True), - ("::TestAttr%s::ul", "ul", "UnsignedLong%s", False), - ("::TestAttr%s::rul", "rul", "UnsignedLong%s", True), - ("::TestAttr%s::ll", "ll", "LongLong%s", False), - ("::TestAttr%s::rll", "rll", "LongLong%s", True), - ("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False), - ("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True), - ("::TestAttr%s::str", "str", "String%s", False), - ("::TestAttr%s::rstr", "rstr", "String%s", True), - ("::TestAttr%s::obj", "obj", "Object%s", False), - ("::TestAttr%s::robj", "robj", "Object%s", True), - ("::TestAttr%s::object", "object", "Object%s", False), - ("::TestAttr%s::f", "f", "Float%s", False), - ("::TestAttr%s::rf", "rf", "Float%s", True)] - - parser.parse(""" + testData = [ + ("::TestAttr%s::b", "b", "Byte%s", False), + ("::TestAttr%s::rb", "rb", "Byte%s", True), + ("::TestAttr%s::o", "o", "Octet%s", False), + ("::TestAttr%s::ro", "ro", "Octet%s", True), + ("::TestAttr%s::s", "s", "Short%s", False), + ("::TestAttr%s::rs", "rs", "Short%s", True), + ("::TestAttr%s::us", "us", "UnsignedShort%s", False), + ("::TestAttr%s::rus", "rus", "UnsignedShort%s", True), + ("::TestAttr%s::l", "l", "Long%s", False), + ("::TestAttr%s::rl", "rl", "Long%s", True), + ("::TestAttr%s::ul", "ul", "UnsignedLong%s", False), + ("::TestAttr%s::rul", "rul", "UnsignedLong%s", True), + ("::TestAttr%s::ll", "ll", "LongLong%s", False), + ("::TestAttr%s::rll", "rll", "LongLong%s", True), + ("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False), + ("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True), + ("::TestAttr%s::str", "str", "String%s", False), + ("::TestAttr%s::rstr", "rstr", "String%s", True), + ("::TestAttr%s::obj", "obj", "Object%s", False), + ("::TestAttr%s::robj", "robj", "Object%s", True), + ("::TestAttr%s::object", "object", "Object%s", False), + ("::TestAttr%s::f", "f", "Float%s", False), + ("::TestAttr%s::rf", "rf", "Float%s", True), + ] + + parser.parse( + """ interface TestAttr { attribute byte b; readonly attribute byte rb; @@ -77,13 +81,13 @@ def WebIDLTest(parser, harness): attribute float? f; readonly attribute float? rf; }; - """) + """ + ) results = parser.finish() def checkAttr(attr, QName, name, type, readonly): - harness.ok(isinstance(attr, WebIDL.IDLAttribute), - "Should be an IDLAttribute") + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") harness.ok(attr.isAttr(), "Attr is an Attr") harness.ok(not attr.isMethod(), "Attr is not an method") harness.ok(not attr.isConst(), "Attr is not a const") @@ -95,11 +99,14 @@ def WebIDLTest(parser, harness): harness.ok(True, "TestAttr interface parsed without error.") harness.check(len(results), 2, "Should be two productions.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestAttr", "Interface has the right QName") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestAttr", "Interface has the right QName" + ) harness.check(iface.identifier.name, "TestAttr", "Interface has the right name") - harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData)) + harness.check( + len(iface.members), len(testData), "Expect %s members" % len(testData) + ) attrs = iface.members @@ -110,11 +117,16 @@ def WebIDLTest(parser, harness): checkAttr(attr, QName % "", name, type % "", readonly) iface = results[1] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName") - harness.check(iface.identifier.name, "TestAttrNullable", "Interface has the right name") - harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData)) + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName" + ) + harness.check( + iface.identifier.name, "TestAttrNullable", "Interface has the right name" + ) + harness.check( + len(iface.members), len(testData), "Expect %s members" % len(testData) + ) attrs = iface.members @@ -127,11 +139,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [SetterThrows] readonly attribute boolean foo; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -140,11 +154,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throw] readonly attribute boolean foo; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -153,24 +169,30 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [SameObject] readonly attribute boolean foo; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type") + harness.ok( + threw, "Should not allow [SameObject] on attributes not of interface type" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [SameObject] readonly attribute A foo; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py b/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py index fb1b97812bc..f3249de900a 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface AttrSequenceType { attribute sequence<object> foo; }; - """) + """ + ) results = parser.finish() except: @@ -17,51 +19,59 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface AttrUnionWithSequenceType { attribute (sequence<object> or DOMString) foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Attribute type must not be a union with a sequence member type") + harness.ok(threw, "Attribute type must not be a union with a sequence member type") parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface AttrNullableUnionWithSequenceType { attribute (sequence<object>? or DOMString) foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Attribute type must not be a union with a nullable sequence " - "member type") + harness.ok( + threw, + "Attribute type must not be a union with a nullable sequence " "member type", + ) parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface AttrUnionWithUnionWithSequenceType { attribute ((sequence<object> or DOMString) or AttrUnionWithUnionWithSequenceType) foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Attribute type must not be a union type with a union member " - "type that has a sequence member type") + harness.ok( + threw, + "Attribute type must not be a union type with a union member " + "type that has a sequence member type", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py b/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py index 9ba39018c77..97a7f47859a 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py @@ -1,14 +1,16 @@ # Import the WebIDL module, so we can do isinstance checks and whatnot import WebIDL + def WebIDLTest(parser, harness): # Basic functionality threw = False try: - parser.parse(""" + parser.parse( + """ typedef [EnforceRange] long Foo; typedef [Clamp] long Bar; - typedef [TreatNullAs=EmptyString] DOMString Baz; + typedef [LegacyNullToEmptyString] DOMString Baz; dictionary A { required [EnforceRange] long a; required [Clamp] long b; @@ -19,11 +21,12 @@ def WebIDLTest(parser, harness): attribute Foo typedefFoo; attribute [EnforceRange] long foo; attribute [Clamp] long bar; - attribute [TreatNullAs=EmptyString] DOMString baz; + attribute [LegacyNullToEmptyString] DOMString baz; undefined method([EnforceRange] long foo, [Clamp] long bar, - [TreatNullAs=EmptyString] DOMString baz); + [LegacyNullToEmptyString] DOMString baz); undefined method2(optional [EnforceRange] long foo, optional [Clamp] long bar, - optional [TreatNullAs=EmptyString] DOMString baz); + optional [LegacyNullToEmptyString] DOMString baz); + undefined method3(optional [LegacyNullToEmptyString] UTF8String foo = ""); }; interface C { attribute [EnforceRange] long? foo; @@ -40,34 +43,88 @@ def WebIDLTest(parser, harness): interface Iterable { iterable<[Clamp] long, [EnforceRange] long>; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(not threw, "Should not have thrown on parsing normal") if not threw: - harness.check(results[0].innerType.hasEnforceRange(), True, "Foo is [EnforceRange]") + harness.check( + results[0].innerType.hasEnforceRange(), True, "Foo is [EnforceRange]" + ) harness.check(results[1].innerType.hasClamp(), True, "Bar is [Clamp]") - harness.check(results[2].innerType.treatNullAsEmpty, True, "Baz is [TreatNullAs=EmptyString]") + harness.check( + results[2].innerType.legacyNullToEmptyString, + True, + "Baz is [LegacyNullToEmptyString]", + ) A = results[3] - harness.check(A.members[0].type.hasEnforceRange(), True, "A.a is [EnforceRange]") + harness.check( + A.members[0].type.hasEnforceRange(), True, "A.a is [EnforceRange]" + ) harness.check(A.members[1].type.hasClamp(), True, "A.b is [Clamp]") - harness.check(A.members[2].type.hasEnforceRange(), True, "A.c is [EnforceRange]") - harness.check(A.members[3].type.hasEnforceRange(), True, "A.d is [EnforceRange]") + harness.check( + A.members[2].type.hasEnforceRange(), True, "A.c is [EnforceRange]" + ) + harness.check( + A.members[3].type.hasEnforceRange(), True, "A.d is [EnforceRange]" + ) B = results[4] - harness.check(B.members[0].type.hasEnforceRange(), True, "B.typedefFoo is [EnforceRange]") - harness.check(B.members[1].type.hasEnforceRange(), True, "B.foo is [EnforceRange]") + harness.check( + B.members[0].type.hasEnforceRange(), True, "B.typedefFoo is [EnforceRange]" + ) + harness.check( + B.members[1].type.hasEnforceRange(), True, "B.foo is [EnforceRange]" + ) harness.check(B.members[2].type.hasClamp(), True, "B.bar is [Clamp]") - harness.check(B.members[3].type.treatNullAsEmpty, True, "B.baz is [TreatNullAs=EmptyString]") + harness.check( + B.members[3].type.legacyNullToEmptyString, + True, + "B.baz is [LegacyNullToEmptyString]", + ) method = B.members[4].signatures()[0][1] - harness.check(method[0].type.hasEnforceRange(), True, "foo argument of method is [EnforceRange]") - harness.check(method[1].type.hasClamp(), True, "bar argument of method is [Clamp]") - harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method is [TreatNullAs=EmptyString]") + harness.check( + method[0].type.hasEnforceRange(), + True, + "foo argument of method is [EnforceRange]", + ) + harness.check( + method[1].type.hasClamp(), True, "bar argument of method is [Clamp]" + ) + harness.check( + method[2].type.legacyNullToEmptyString, + True, + "baz argument of method is [LegacyNullToEmptyString]", + ) method2 = B.members[5].signatures()[0][1] - harness.check(method[0].type.hasEnforceRange(), True, "foo argument of method2 is [EnforceRange]") - harness.check(method[1].type.hasClamp(), True, "bar argument of method2 is [Clamp]") - harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method2 is [TreatNullAs=EmptyString]") + harness.check( + method2[0].type.hasEnforceRange(), + True, + "foo argument of method2 is [EnforceRange]", + ) + harness.check( + method2[1].type.hasClamp(), True, "bar argument of method2 is [Clamp]" + ) + harness.check( + method2[2].type.legacyNullToEmptyString, + True, + "baz argument of method2 is [LegacyNullToEmptyString]", + ) + + method3 = B.members[6].signatures()[0][1] + harness.check( + method3[0].type.legacyNullToEmptyString, + True, + "bar argument of method2 is [LegacyNullToEmptyString]", + ) + harness.check( + method3[0].defaultValue.type.isUTF8String(), + True, + "default value of bar argument of method2 is correctly coerced to UTF8String", + ) + C = results[5] harness.ok(C.members[0].type.nullable(), "C.foo is nullable") harness.ok(C.members[0].type.hasEnforceRange(), "C.foo has [EnforceRange]") @@ -75,12 +132,18 @@ def WebIDLTest(parser, harness): harness.ok(C.members[1].type.hasClamp(), "C.bar has [Clamp]") method = C.members[2].signatures()[0][1] harness.ok(method[0].type.nullable(), "foo argument of method is nullable") - harness.ok(method[0].type.hasEnforceRange(), "foo argument of method has [EnforceRange]") + harness.ok( + method[0].type.hasEnforceRange(), + "foo argument of method has [EnforceRange]", + ) harness.ok(method[1].type.nullable(), "bar argument of method is nullable") harness.ok(method[1].type.hasClamp(), "bar argument of method has [Clamp]") method2 = C.members[3].signatures()[0][1] harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable") - harness.ok(method2[0].type.hasEnforceRange(), "foo argument of method2 has [EnforceRange]") + harness.ok( + method2[0].type.hasEnforceRange(), + "foo argument of method2 has [EnforceRange]", + ) harness.ok(method2[1].type.nullable(), "bar argument of method2 is nullable") harness.ok(method2[1].type.hasClamp(), "bar argument of method2 has [Clamp]") @@ -88,7 +151,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [AllowShared] ArrayBufferView Foo; dictionary A { required [AllowShared] ArrayBufferView a; @@ -115,7 +179,8 @@ def WebIDLTest(parser, harness): interface Iterable { iterable<[Clamp] long, [AllowShared] ArrayBufferView>; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -131,63 +196,101 @@ def WebIDLTest(parser, harness): harness.ok(B.members[0].type.hasAllowShared(), "B.typedefFoo is [AllowShared]") harness.ok(B.members[1].type.hasAllowShared(), "B.foo is [AllowShared]") method = B.members[2].signatures()[0][1] - harness.ok(method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]") + harness.ok( + method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]" + ) method2 = B.members[3].signatures()[0][1] - harness.ok(method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]") + harness.ok( + method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]" + ) C = results[3] harness.ok(C.members[0].type.nullable(), "C.foo is nullable") harness.ok(C.members[0].type.hasAllowShared(), "C.foo is [AllowShared]") method = C.members[1].signatures()[0][1] harness.ok(method[0].type.nullable(), "foo argument of method is nullable") - harness.ok(method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]") + harness.ok( + method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]" + ) method2 = C.members[2].signatures()[0][1] harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable") - harness.ok(method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]") + harness.ok( + method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]" + ) - ATTRIBUTES = [("[Clamp]", "long"), ("[EnforceRange]", "long"), - ("[TreatNullAs=EmptyString]", "DOMString"), ("[AllowShared]", "ArrayBufferView")] + ATTRIBUTES = [ + ("[Clamp]", "long"), + ("[EnforceRange]", "long"), + ("[LegacyNullToEmptyString]", "DOMString"), + ("[AllowShared]", "ArrayBufferView"), + ] TEMPLATES = [ - ("required dictionary members", """ + ( + "required dictionary members", + """ dictionary Foo { %s required %s foo; }; - """), - ("optional arguments", """ + """, + ), + ( + "optional arguments", + """ interface Foo { undefined foo(%s optional %s foo); }; - """), - ("typedefs", """ + """, + ), + ( + "typedefs", + """ %s typedef %s foo; - """), - ("attributes", """ + """, + ), + ( + "attributes", + """ interface Foo { %s attribute %s foo; }; - """), - ("readonly attributes", """ + """, + ), + ( + "readonly attributes", + """ interface Foo { readonly attribute %s %s foo; }; - """), - ("readonly unresolved attributes", """ + """, + ), + ( + "readonly unresolved attributes", + """ interface Foo { readonly attribute Bar baz; }; typedef %s %s Bar; - """), - ("method", """ + """, + ), + ( + "method", + """ interface Foo { %s %s foo(); }; - """), - ("interface",""" + """, + ), + ( + "interface", + """ %s interface Foo { attribute %s foo; }; - """), - ("partial interface",""" + """, + ), + ( + "partial interface", + """ interface Foo { undefined foo(); }; @@ -195,20 +298,29 @@ def WebIDLTest(parser, harness): partial interface Foo { attribute %s bar; }; - """), - ("interface mixin",""" + """, + ), + ( + "interface mixin", + """ %s interface mixin Foo { attribute %s foo; }; - """), - ("namespace",""" + """, + ), + ( + "namespace", + """ %s namespace Foo { attribute %s foo; }; - """), - ("partial namespace",""" + """, + ), + ( + "partial namespace", + """ namespace Foo { undefined foo(); }; @@ -216,14 +328,18 @@ def WebIDLTest(parser, harness): partial namespace Foo { attribute %s bar; }; - """), - ("dictionary",""" + """, + ), + ( + "dictionary", + """ %s dictionary Foo { %s foo; }; - """) - ]; + """, + ), + ] for (name, template) in TEMPLATES: parser = parser.reset() @@ -242,15 +358,16 @@ def WebIDLTest(parser, harness): parser.finish() except: threw = True - harness.ok(threw, - "Should not allow %s on %s" % (attribute, name)) + harness.ok(threw, "Should not allow %s on %s" % (attribute, name)) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [Clamp, EnforceRange] long Foo; - """) + """ + ) parser.finish() except: threw = True @@ -260,23 +377,26 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [EnforceRange, Clamp] long Foo; - """) + """ + ) parser.finish() except: threw = True harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange]") - parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [Clamp] long Foo; typedef [EnforceRange] Foo bar; - """) + """ + ) parser.finish() except: threw = True @@ -286,25 +406,36 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [EnforceRange] long Foo; typedef [Clamp] Foo bar; - """) + """ + ) parser.finish() except: threw = True harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs") - TYPES = ["DOMString", "unrestricted float", "float", "unrestricted double", "double"] + TYPES = [ + "DOMString", + "unrestricted float", + "float", + "unrestricted double", + "double", + ] for type in TYPES: parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [Clamp] %s Foo; - """ % type) + """ + % type + ) parser.finish() except: threw = True @@ -314,58 +445,70 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [EnforceRange] %s Foo; - """ % type) + """ + % type + ) parser.finish() except: threw = True harness.ok(threw, "Should not allow [EnforceRange] on %s" % type) - parser = parser.reset() threw = False try: - parser.parse(""" - typedef [TreatNullAs=EmptyString] long Foo; - """) + parser.parse( + """ + typedef [LegacyNullToEmptyString] long Foo; + """ + ) parser.finish() except: threw = True - harness.ok(threw, "Should not allow [TreatNullAs] on long") + harness.ok(threw, "Should not allow [LegacyNullToEmptyString] on long") parser = parser.reset() threw = False try: - parser.parse(""" - typedef [TreatNullAs=EmptyString] JSString Foo; - """) + parser.parse( + """ + typedef [LegacyNullToEmptyString] JSString Foo; + """ + ) parser.finish() except: threw = True - harness.ok(threw, "Should not allow [TreatNullAs] on JSString") + harness.ok(threw, "Should not allow [LegacyNullToEmptyString] on JSString") parser = parser.reset() threw = False try: - parser.parse(""" - typedef [TreatNullAs=EmptyString] DOMString? Foo; - """) + parser.parse( + """ + typedef [LegacyNullToEmptyString] DOMString? Foo; + """ + ) parser.finish() except: threw = True - harness.ok(threw, "Should not allow [TreatNullAs] on nullable DOMString") + harness.ok( + threw, "Should not allow [LegacyNullToEmptyString] on nullable DOMString" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [AllowShared] DOMString Foo; - """) + """ + ) results = parser.finish() except: threw = True @@ -374,9 +517,11 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef [AllowShared=something] ArrayBufferView Foo; - """) + """ + ) results = parser.finish() except: threw = True @@ -385,31 +530,41 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { undefined foo([Clamp] Bar arg); }; typedef long Bar; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(not threw, "Should allow type attributes on unresolved types") - harness.check(results[0].members[0].signatures()[0][1][0].type.hasClamp(), True, - "Unresolved types with type attributes should correctly resolve with attributes") + harness.check( + results[0].members[0].signatures()[0][1][0].type.hasClamp(), + True, + "Unresolved types with type attributes should correctly resolve with attributes", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { undefined foo(Bar arg); }; typedef [Clamp] long Bar; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(not threw, "Should allow type attributes on typedefs") - harness.check(results[0].members[0].signatures()[0][1][0].type.hasClamp(), True, - "Unresolved types that resolve to typedefs with attributes should correctly resolve with attributes") + harness.check( + results[0].members[0].signatures()[0][1][0].type.hasClamp(), + True, + "Unresolved types that resolve to typedefs with attributes should correctly resolve with attributes", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py b/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py index 631e52eba0b..6c913bba822 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py @@ -1,11 +1,14 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface Test { attribute long b; }; - """); + """ + ) attr = parser.finish()[0].members[0] - harness.check(attr.type.filename(), '<builtin>', 'Filename on builtin type') + harness.check(attr.type.filename(), "<builtin>", "Filename on builtin type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_builtins.py b/components/script/dom/bindings/codegen/parser/tests/test_builtins.py index f8563fc2d9b..a75a12e8143 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_builtins.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_builtins.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestBuiltins { attribute boolean b; attribute byte s8; @@ -12,30 +14,46 @@ def WebIDLTest(parser, harness): attribute unsigned long u32; attribute long long s64; attribute unsigned long long u64; - attribute DOMTimeStamp ts; }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestBuiltins interface parsed without error.") harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") iface = results[0] - harness.check(iface.identifier.QName(), "::TestBuiltins", "Interface has the right QName") + harness.check( + iface.identifier.QName(), "::TestBuiltins", "Interface has the right QName" + ) harness.check(iface.identifier.name, "TestBuiltins", "Interface has the right name") harness.check(iface.parent, None, "Interface has no parent") members = iface.members - harness.check(len(members), 10, "Should be one production") + harness.check(len(members), 9, "Should be one production") names = ["b", "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "ts"] - types = ["Boolean", "Byte", "Octet", "Short", "UnsignedShort", "Long", "UnsignedLong", "LongLong", "UnsignedLongLong", "UnsignedLongLong"] - for i in range(10): + types = [ + "Boolean", + "Byte", + "Octet", + "Short", + "UnsignedShort", + "Long", + "UnsignedLong", + "LongLong", + "UnsignedLongLong", + "UnsignedLongLong", + ] + for i in range(9): attr = members[i] harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check(attr.identifier.QName(), "::TestBuiltins::" + names[i], "Attr has correct QName") + harness.check( + attr.identifier.QName(), + "::TestBuiltins::" + names[i], + "Attr has correct QName", + ) harness.check(attr.identifier.name, names[i], "Attr has correct name") harness.check(str(attr.type), types[i], "Attr type is the correct name") harness.ok(attr.type.isPrimitive(), "Should be a primitive type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py index 51289f5db6e..a6f9f6ab9cb 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py @@ -2,24 +2,30 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestByteString { attribute ByteString bs; attribute DOMString ds; }; - """) + """ + ) - results = parser.finish(); + results = parser.finish() harness.ok(True, "TestByteString interface parsed without error.") harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") iface = results[0] - harness.check(iface.identifier.QName(), "::TestByteString", "Interface has the right QName") - harness.check(iface.identifier.name, "TestByteString", "Interface has the right name") + harness.check( + iface.identifier.QName(), "::TestByteString", "Interface has the right QName" + ) + harness.check( + iface.identifier.name, "TestByteString", "Interface has the right name" + ) harness.check(iface.parent, None, "Interface has no parent") members = iface.members @@ -27,7 +33,9 @@ def WebIDLTest(parser, harness): attr = members[0] harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check(attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName") + harness.check( + attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName" + ) harness.check(attr.identifier.name, "bs", "Attr has correct name") harness.check(str(attr.type), "ByteString", "Attr type is the correct name") harness.ok(attr.type.isByteString(), "Should be ByteString type") @@ -37,7 +45,9 @@ def WebIDLTest(parser, harness): # now check we haven't broken DOMStrings in the process. attr = members[1] harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check(attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName") + harness.check( + attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName" + ) harness.check(attr.identifier.name, "ds", "Attr has correct name") harness.check(str(attr.type), "String", "Attr type is the correct name") harness.ok(attr.type.isDOMString(), "Should be DOMString type") @@ -47,53 +57,69 @@ def WebIDLTest(parser, harness): # Cannot represent constant ByteString in IDL. threw = False try: - parser.parse(""" + parser.parse( + """ interface ConstByteString { const ByteString foo = "hello" }; - """) + """ + ) except WebIDL.WebIDLError: threw = True - harness.ok(threw, "Should have thrown a WebIDL error for ByteString default in interface") + harness.ok( + threw, "Should have thrown a WebIDL error for ByteString default in interface" + ) # Can have optional ByteStrings with default values try: - parser.parse(""" + parser.parse( + """ interface OptionalByteString { undefined passByteString(optional ByteString arg = "hello"); - }; - """) - results2 = parser.finish(); + }; + """ + ) + results2 = parser.finish() except WebIDL.WebIDLError as e: - harness.ok(False, - "Should not have thrown a WebIDL error for ByteString " - "default in dictionary. " + str(e)) + harness.ok( + False, + "Should not have thrown a WebIDL error for ByteString " + "default in dictionary. " + str(e), + ) # Can have a default ByteString value in a dictionary try: - parser.parse(""" + parser.parse( + """ dictionary OptionalByteStringDict { ByteString item = "some string"; }; - """) - results3 = parser.finish(); + """ + ) + results3 = parser.finish() except WebIDL.WebIDLError as e: - harness.ok(False, - "Should not have thrown a WebIDL error for ByteString " - "default in dictionary. " + str(e)) + harness.ok( + False, + "Should not have thrown a WebIDL error for ByteString " + "default in dictionary. " + str(e), + ) # Don't allow control characters in ByteString literals threw = False try: - parser.parse(""" + parser.parse( + """ dictionary OptionalByteStringDict2 { ByteString item = "\x03"; }; - """) + """ + ) results4 = parser.finish() except WebIDL.WebIDLError as e: threw = True - harness.ok(threw, - "Should have thrown a WebIDL error for invalid ByteString " - "default in dictionary") + harness.ok( + threw, + "Should have thrown a WebIDL error for invalid ByteString " + "default in dictionary", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback.py b/components/script/dom/bindings/codegen/parser/tests/test_callback.py index c304d085ce5..407644a6a8d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_callback.py @@ -1,32 +1,37 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestCallback { attribute CallbackType? listener; }; callback CallbackType = boolean (unsigned long arg); - """) + """ + ) results = parser.finish() harness.ok(True, "TestCallback interface parsed without error.") harness.check(len(results), 2, "Should be two productions.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestCallback", "Interface has the right QName") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestCallback", "Interface has the right QName" + ) harness.check(iface.identifier.name, "TestCallback", "Interface has the right name") harness.check(len(iface.members), 1, "Expect %s members" % 1) attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), - "Should be an IDLAttribute") + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") harness.ok(attr.isAttr(), "Should be an attribute") harness.ok(not attr.isMethod(), "Attr is not an method") harness.ok(not attr.isConst(), "Attr is not a const") - harness.check(attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName") + harness.check( + attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName" + ) harness.check(attr.identifier.name, "listener", "Attr has the right name") t = attr.type harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py index 4999deef623..832a92bb147 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py @@ -1,33 +1,46 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestCallbackConstructor { attribute CallbackConstructorType? constructorAttribute; }; callback constructor CallbackConstructorType = TestCallbackConstructor (unsigned long arg); - """) + """ + ) results = parser.finish() harness.ok(True, "TestCallbackConstructor interface parsed without error.") harness.check(len(results), 2, "Should be two productions.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestCallbackConstructor", "Interface has the right QName") - harness.check(iface.identifier.name, "TestCallbackConstructor", "Interface has the right name") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), + "::TestCallbackConstructor", + "Interface has the right QName", + ) + harness.check( + iface.identifier.name, "TestCallbackConstructor", "Interface has the right name" + ) harness.check(len(iface.members), 1, "Expect %s members" % 1) attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), - "Should be an IDLAttribute") + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") harness.ok(attr.isAttr(), "Should be an attribute") harness.ok(not attr.isMethod(), "Attr is not an method") harness.ok(not attr.isConst(), "Attr is not a const") - harness.check(attr.identifier.QName(), "::TestCallbackConstructor::constructorAttribute", "Attr has the right QName") - harness.check(attr.identifier.name, "constructorAttribute", "Attr has the right name") + harness.check( + attr.identifier.QName(), + "::TestCallbackConstructor::constructorAttribute", + "Attr has the right QName", + ) + harness.check( + attr.identifier.name, "constructorAttribute", "Attr has the right name" + ) t = attr.type harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type") harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type") @@ -39,25 +52,33 @@ def WebIDLTest(parser, harness): parser.reset() threw = False try: - parser.parse(""" - [TreatNonObjectAsNull] + parser.parse( + """ + [LegacyTreatNonObjectAsNull] callback constructor CallbackConstructorType = object (); - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should throw on TreatNonObjectAsNull callback constructors") + harness.ok( + threw, "Should throw on LegacyTreatNonObjectAsNull callback constructors" + ) parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [MOZ_CAN_RUN_SCRIPT_BOUNDARY] callback constructor CallbackConstructorType = object (); - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not permit MOZ_CAN_RUN_SCRIPT_BOUNDARY callback constructors") + harness.ok( + threw, "Should not permit MOZ_CAN_RUN_SCRIPT_BOUNDARY callback constructors" + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py index 34813bcab99..0d657f48032 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py @@ -1,11 +1,14 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ callback interface TestCallbackInterface { attribute boolean bool; }; - """) + """ + ) results = parser.finish() @@ -16,13 +19,15 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestInterface { }; callback interface TestCallbackInterface : TestInterface { attribute boolean bool; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -32,13 +37,15 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestInterface : TestCallbackInterface { }; callback interface TestCallbackInterface { attribute boolean bool; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -46,7 +53,8 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should not allow callback parent of non-callback interface") parser = parser.reset() - parser.parse(""" + parser.parse( + """ callback interface TestCallbackInterface1 { undefined foo(); }; @@ -86,9 +94,13 @@ def WebIDLTest(parser, harness): callback interface TestCallbackInterface10 : TestCallbackInterface1 { undefined bar(); }; - """) + """ + ) results = parser.finish() for (i, iface) in enumerate(results): - harness.check(iface.isSingleOperationInterface(), i < 4, - "Interface %s should be a single operation interface" % - iface.identifier.name) + harness.check( + iface.isSingleOperationInterface(), + i < 4, + "Interface %s should be a single operation interface" + % iface.identifier.name, + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py b/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py index ebc688bfd9c..c56c3dbde10 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions(DOMString a)] undefined foo(boolean arg2); }; - """) + """ + ) results = parser.finish() except: @@ -16,11 +18,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions(DOMString b)] readonly attribute boolean bar; }; - """) + """ + ) results = parser.finish() except: @@ -31,54 +35,72 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] attribute boolean bar; }; - """) + """ + ) results = parser.finish() except Exception as e: - harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e) + harness.ok( + False, + "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" + % e, + ) threw = True parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] undefined foo(boolean arg2); }; - """) + """ + ) results = parser.finish() except Exception as e: - harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e) + harness.ok( + False, + "Shouldn't have thrown for [CEReactions] used on regular operations. %s" + % e, + ) threw = True parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] readonly attribute boolean A; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should have thrown for [CEReactions] used on a readonly attribute") + harness.ok( + threw, "Should have thrown for [CEReactions] used on a readonly attribute" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [CEReactions] interface Foo { } - """) + """ + ) results = parser.finish() except: @@ -89,45 +111,47 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] getter any(DOMString name); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [CEReactions] used on a named getter") + harness.ok(threw, "Should have thrown for [CEReactions] used on a named getter") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] legacycaller double compute(double x); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [CEReactions] used on a legacycaller") + harness.ok(threw, "Should have thrown for [CEReactions] used on a legacycaller") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { [CEReactions] stringifier DOMString (); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [CEReactions] used on a stringifier") - + harness.ok(threw, "Should have thrown for [CEReactions] used on a stringifier") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py b/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py index 8420f2ee4e0..2aef8ebe8ff 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py @@ -1,23 +1,28 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ dictionary Dict { any foo; [ChromeOnly] any bar; }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should have a dictionary") - members = results[0].members; + members = results[0].members harness.check(len(members), 2, "Should have two members") # Note that members are ordered lexicographically, so "bar" comes # before "foo". - harness.ok(members[0].getExtendedAttribute("ChromeOnly"), - "First member is not ChromeOnly") - harness.ok(not members[1].getExtendedAttribute("ChromeOnly"), - "Second member is ChromeOnly") + harness.ok( + members[0].getExtendedAttribute("ChromeOnly"), "First member is not ChromeOnly" + ) + harness.ok( + not members[1].getExtendedAttribute("ChromeOnly"), "Second member is ChromeOnly" + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary Dict { any foo; any bar; @@ -26,14 +31,16 @@ def WebIDLTest(parser, harness): interface Iface { [Constant, Cached] readonly attribute Dict dict; }; - """) + """ + ) results = parser.finish() harness.check(len(results), 2, "Should have a dictionary and an interface") parser = parser.reset() exception = None try: - parser.parse(""" + parser.parse( + """ dictionary Dict { any foo; [ChromeOnly] any bar; @@ -42,21 +49,25 @@ def WebIDLTest(parser, harness): interface Iface { [Constant, Cached] readonly attribute Dict dict; }; - """) - results = parser.finish() + """ + ) + results = parser.finish() except Exception as e: - exception = e + exception = e harness.ok(exception, "Should have thrown.") - harness.check(exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception") + harness.check( + exception.message, + "[Cached] and [StoreInSlot] must not be used on an attribute " + "whose type contains a [ChromeOnly] dictionary member", + "Should have thrown the right exception", + ) parser = parser.reset() exception = None try: - parser.parse(""" + parser.parse( + """ dictionary ParentDict { [ChromeOnly] any bar; }; @@ -68,21 +79,25 @@ def WebIDLTest(parser, harness): interface Iface { [Constant, Cached] readonly attribute Dict dict; }; - """) - results = parser.finish() + """ + ) + results = parser.finish() except Exception as e: - exception = e + exception = e harness.ok(exception, "Should have thrown (2).") - harness.check(exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception (2)") + harness.check( + exception.message, + "[Cached] and [StoreInSlot] must not be used on an attribute " + "whose type contains a [ChromeOnly] dictionary member", + "Should have thrown the right exception (2)", + ) parser = parser.reset() exception = None try: - parser.parse(""" + parser.parse( + """ dictionary GrandParentDict { [ChromeOnly] any baz; }; @@ -98,13 +113,16 @@ def WebIDLTest(parser, harness): interface Iface { [Constant, Cached] readonly attribute Dict dict; }; - """) - results = parser.finish() + """ + ) + results = parser.finish() except Exception as e: - exception = e + exception = e harness.ok(exception, "Should have thrown (3).") - harness.check(exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception (3)") + harness.check( + exception.message, + "[Cached] and [StoreInSlot] must not be used on an attribute " + "whose type contains a [ChromeOnly] dictionary member", + "Should have thrown the right exception (3)", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_const.py b/components/script/dom/bindings/codegen/parser/tests/test_const.py index 918f284a226..f2d4b79d467 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_const.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_const.py @@ -22,8 +22,10 @@ expected = [ ("::TestConsts::udbi", "udbi", "UnrestrictedDouble", 2), ] + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestConsts { const byte zero = 0; const byte b = -1; @@ -45,22 +47,25 @@ def WebIDLTest(parser, harness): const unrestricted float ufli = 2; const unrestricted double udbi = 2; }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestConsts interface parsed without error.") harness.check(len(results), 1, "Should be one production.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestConsts", "Interface has the right QName" + ) harness.check(iface.identifier.name, "TestConsts", "Interface has the right name") - harness.check(len(iface.members), len(expected), "Expect %s members" % len(expected)) + harness.check( + len(iface.members), len(expected), "Expect %s members" % len(expected) + ) for (const, (QName, name, type, value)) in zip(iface.members, expected): - harness.ok(isinstance(const, WebIDL.IDLConst), - "Should be an IDLConst") + harness.ok(isinstance(const, WebIDL.IDLConst), "Should be an IDLConst") harness.ok(const.isConst(), "Const is a const") harness.ok(not const.isAttr(), "Const is not an attr") harness.ok(not const.isMethod(), "Const is not a method") @@ -68,19 +73,23 @@ def WebIDLTest(parser, harness): harness.check(const.identifier.name, name, "Const has the right name") harness.check(str(const.type), type, "Const has the right type") harness.ok(const.type.isPrimitive(), "All consts should be primitive") - harness.check(str(const.value.type), str(const.type), - "Const's value has the same type as the type") + harness.check( + str(const.value.type), + str(const.type), + "Const's value has the same type as the type", + ) harness.check(const.value.value, value, "Const value has the right value.") - parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestConsts { const boolean? zero = 0; }; - """) + """ + ) parser.finish() except: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py index 83e1f4fc34f..de5d52f1412 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py @@ -1,21 +1,39 @@ import WebIDL + def WebIDLTest(parser, harness): def checkArgument(argument, QName, name, type, optional, variadic): - harness.ok(isinstance(argument, WebIDL.IDLArgument), - "Should be an IDLArgument") - harness.check(argument.identifier.QName(), QName, "Argument has the right QName") + harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") + harness.check( + argument.identifier.QName(), QName, "Argument has the right QName" + ) harness.check(argument.identifier.name, name, "Argument has the right name") harness.check(str(argument.type), type, "Argument has the right return type") - harness.check(argument.optional, optional, "Argument has the right optional value") - harness.check(argument.variadic, variadic, "Argument has the right variadic value") - - def checkMethod(method, QName, name, signatures, - static=True, getter=False, setter=False, deleter=False, - legacycaller=False, stringifier=False, chromeOnly=False, - htmlConstructor=False, secureContext=False, pref=None, func=None): - harness.ok(isinstance(method, WebIDL.IDLMethod), - "Should be an IDLMethod") + harness.check( + argument.optional, optional, "Argument has the right optional value" + ) + harness.check( + argument.variadic, variadic, "Argument has the right variadic value" + ) + + def checkMethod( + method, + QName, + name, + signatures, + static=True, + getter=False, + setter=False, + deleter=False, + legacycaller=False, + stringifier=False, + chromeOnly=False, + htmlConstructor=False, + secureContext=False, + pref=None, + func=None, + ): + harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") harness.ok(method.isMethod(), "Method is a method") harness.ok(not method.isAttr(), "Method is not an attr") harness.ok(not method.isConst(), "Method is not a const") @@ -24,23 +42,58 @@ def WebIDLTest(parser, harness): harness.check(method.isStatic(), static, "Method has the correct static value") harness.check(method.isGetter(), getter, "Method has the correct getter value") harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check(method.isDeleter(), deleter, "Method has the correct deleter value") - harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value") - harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") - harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly") - harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value") - harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") - harness.check(method.getExtendedAttribute("Pref"), pref, "Method has the correct pref value") - harness.check(method.getExtendedAttribute("Func"), func, "Method has the correct func value") - harness.check(method.getExtendedAttribute("SecureContext") is not None, secureContext, "Method has the correct SecureContext value") + harness.check( + method.isDeleter(), deleter, "Method has the correct deleter value" + ) + harness.check( + method.isLegacycaller(), + legacycaller, + "Method has the correct legacycaller value", + ) + harness.check( + method.isStringifier(), + stringifier, + "Method has the correct stringifier value", + ) + harness.check( + method.getExtendedAttribute("ChromeOnly") is not None, + chromeOnly, + "Method has the correct value for ChromeOnly", + ) + harness.check( + method.isHTMLConstructor(), + htmlConstructor, + "Method has the correct htmlConstructor value", + ) + harness.check( + len(method.signatures()), + len(signatures), + "Method has the correct number of signatures", + ) + harness.check( + method.getExtendedAttribute("Pref"), + pref, + "Method has the correct pref value", + ) + harness.check( + method.getExtendedAttribute("Func"), + func, + "Method has the correct func value", + ) + harness.check( + method.getExtendedAttribute("SecureContext") is not None, + secureContext, + "Method has the correct SecureContext value", + ) sigpairs = zip(method.signatures(), signatures) for (gotSignature, expectedSignature) in sigpairs: (gotRetType, gotArgs) = gotSignature (expectedRetType, expectedArgs) = expectedSignature - harness.check(str(gotRetType), expectedRetType, - "Method has the expected return type.") + harness.check( + str(gotRetType), expectedRetType, "Method has the expected return type." + ) for i in range(0, len(gotArgs)): (QName, name, type, optional, variadic) = expectedArgs[i] @@ -48,33 +101,88 @@ def WebIDLTest(parser, harness): def checkResults(results): harness.check(len(results), 3, "Should be three productions") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.ok(isinstance(results[2], WebIDL.IDLInterface), - "Should be an IDLInterface") - - checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor", - "constructor", [("TestConstructorNoArgs (Wrapper)", [])]) - harness.check(len(results[0].members), 0, - "TestConstructorNoArgs should not have members") - checkMethod(results[1].ctor(), "::TestConstructorWithArgs::constructor", - "constructor", - [("TestConstructorWithArgs (Wrapper)", - [("::TestConstructorWithArgs::constructor::name", "name", "String", False, False)])]) - harness.check(len(results[1].members), 0, - "TestConstructorWithArgs should not have members") - checkMethod(results[2].ctor(), "::TestConstructorOverloads::constructor", - "constructor", - [("TestConstructorOverloads (Wrapper)", - [("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]), - ("TestConstructorOverloads (Wrapper)", - [("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])]) - harness.check(len(results[2].members), 0, - "TestConstructorOverloads should not have members") - - parser.parse(""" + harness.ok( + isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface" + ) + harness.ok( + isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface" + ) + harness.ok( + isinstance(results[2], WebIDL.IDLInterface), "Should be an IDLInterface" + ) + + checkMethod( + results[0].ctor(), + "::TestConstructorNoArgs::constructor", + "constructor", + [("TestConstructorNoArgs (Wrapper)", [])], + ) + harness.check( + len(results[0].members), 0, "TestConstructorNoArgs should not have members" + ) + checkMethod( + results[1].ctor(), + "::TestConstructorWithArgs::constructor", + "constructor", + [ + ( + "TestConstructorWithArgs (Wrapper)", + [ + ( + "::TestConstructorWithArgs::constructor::name", + "name", + "String", + False, + False, + ) + ], + ) + ], + ) + harness.check( + len(results[1].members), + 0, + "TestConstructorWithArgs should not have members", + ) + checkMethod( + results[2].ctor(), + "::TestConstructorOverloads::constructor", + "constructor", + [ + ( + "TestConstructorOverloads (Wrapper)", + [ + ( + "::TestConstructorOverloads::constructor::foo", + "foo", + "Object", + False, + False, + ) + ], + ), + ( + "TestConstructorOverloads (Wrapper)", + [ + ( + "::TestConstructorOverloads::constructor::bar", + "bar", + "Boolean", + False, + False, + ) + ], + ), + ], + ) + harness.check( + len(results[2].members), + 0, + "TestConstructorOverloads should not have members", + ) + + parser.parse( + """ interface TestConstructorNoArgs { constructor(); }; @@ -87,111 +195,146 @@ def WebIDLTest(parser, harness): constructor(object foo); constructor(boolean bar); }; - """) + """ + ) results = parser.finish() checkResults(results) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestPrefConstructor { [Pref="dom.webidl.test1"] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - checkMethod(results[0].ctor(), "::TestPrefConstructor::constructor", - "constructor", [("TestPrefConstructor (Wrapper)", [])], - pref=["dom.webidl.test1"]) + checkMethod( + results[0].ctor(), + "::TestPrefConstructor::constructor", + "constructor", + [("TestPrefConstructor (Wrapper)", [])], + pref=["dom.webidl.test1"], + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestChromeOnlyConstructor { [ChromeOnly] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - checkMethod(results[0].ctor(), "::TestChromeOnlyConstructor::constructor", - "constructor", [("TestChromeOnlyConstructor (Wrapper)", [])], - chromeOnly=True) + checkMethod( + results[0].ctor(), + "::TestChromeOnlyConstructor::constructor", + "constructor", + [("TestChromeOnlyConstructor (Wrapper)", [])], + chromeOnly=True, + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestSCConstructor { [SecureContext] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - checkMethod(results[0].ctor(), "::TestSCConstructor::constructor", - "constructor", [("TestSCConstructor (Wrapper)", [])], - secureContext=True) + checkMethod( + results[0].ctor(), + "::TestSCConstructor::constructor", + "constructor", + [("TestSCConstructor (Wrapper)", [])], + secureContext=True, + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestFuncConstructor { [Func="Document::IsWebAnimationsEnabled"] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - checkMethod(results[0].ctor(), "::TestFuncConstructor::constructor", - "constructor", [("TestFuncConstructor (Wrapper)", [])], - func=["Document::IsWebAnimationsEnabled"]) + checkMethod( + results[0].ctor(), + "::TestFuncConstructor::constructor", + "constructor", + [("TestFuncConstructor (Wrapper)", [])], + func=["Document::IsWebAnimationsEnabled"], + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestPrefChromeOnlySCFuncConstructor { [ChromeOnly, Pref="dom.webidl.test1", SecureContext, Func="Document::IsWebAnimationsEnabled"] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") - - checkMethod(results[0].ctor(), "::TestPrefChromeOnlySCFuncConstructor::constructor", - "constructor", [("TestPrefChromeOnlySCFuncConstructor (Wrapper)", [])], - func=["Document::IsWebAnimationsEnabled"], pref=["dom.webidl.test1"], - chromeOnly=True, secureContext=True) + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") + + checkMethod( + results[0].ctor(), + "::TestPrefChromeOnlySCFuncConstructor::constructor", + "constructor", + [("TestPrefChromeOnlySCFuncConstructor (Wrapper)", [])], + func=["Document::IsWebAnimationsEnabled"], + pref=["dom.webidl.test1"], + chromeOnly=True, + secureContext=True, + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructor { [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - checkMethod(results[0].ctor(), "::TestHTMLConstructor::constructor", - "constructor", [("TestHTMLConstructor (Wrapper)", [])], - htmlConstructor=True) + checkMethod( + results[0].ctor(), + "::TestHTMLConstructor::constructor", + "constructor", + [("TestHTMLConstructor (Wrapper)", [])], + htmlConstructor=True, + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestChromeOnlyConstructor { constructor() [ChromeOnly] constructor(DOMString a); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -202,11 +345,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorWithArgs { [HTMLConstructor] constructor(DOMString a); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -217,11 +362,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ callback interface TestHTMLConstructorOnCallbackInterface { [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -232,12 +379,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { constructor(); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -247,165 +396,187 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [Throws] constructor(); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a throwing constructor and a HTMLConstructor") + harness.ok(threw, "Can't have both a throwing constructor and a HTMLConstructor") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { constructor(DOMString a); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a HTMLConstructor and a constructor operation") + harness.ok(threw, "Can't have both a HTMLConstructor and a constructor operation") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [Throws] constructor(DOMString a); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a HTMLConstructor and a throwing constructor " - "operation") + harness.ok( + threw, + "Can't have both a HTMLConstructor and a throwing constructor " "operation", + ) # Test HTMLConstructor and [ChromeOnly] constructor operation parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [ChromeOnly] constructor(); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a ChromeOnly constructor and a HTMLConstructor") + harness.ok(threw, "Can't have both a ChromeOnly constructor and a HTMLConstructor") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [Throws, ChromeOnly] constructor(); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a throwing chromeonly constructor and a " - "HTMLConstructor") + harness.ok( + threw, + "Can't have both a throwing chromeonly constructor and a " "HTMLConstructor", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [ChromeOnly] constructor(DOMString a); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a HTMLConstructor and a chromeonly constructor " - "operation") + harness.ok( + threw, + "Can't have both a HTMLConstructor and a chromeonly constructor " "operation", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestHTMLConstructorAndConstructor { [Throws, ChromeOnly] constructor(DOMString a); [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have both a HTMLConstructor and a throwing chromeonly " - "constructor operation") + harness.ok( + threw, + "Can't have both a HTMLConstructor and a throwing chromeonly " + "constructor operation", + ) parser = parser.reset() threw = False try: - parser.parse(""" - [NoInterfaceObject] + parser.parse( + """ + [LegacyNoInterfaceObject] interface InterfaceWithoutInterfaceObject { constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have a constructor operation on a [NoInterfaceObject] " - "interface") + harness.ok( + threw, + "Can't have a constructor operation on a [LegacyNoInterfaceObject] " + "interface", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface InterfaceWithPartial { }; partial interface InterfaceWithPartial { constructor(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have a constructor operation on a partial interface") + harness.ok(threw, "Can't have a constructor operation on a partial interface") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface InterfaceWithMixin { }; @@ -414,11 +585,10 @@ def WebIDLTest(parser, harness): }; InterfaceWithMixin includes Mixin - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Can't have a constructor operation on a mixin") - + harness.ok(threw, "Can't have a constructor operation on a mixin") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py index b7eabb1e35b..5f3663602e4 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py @@ -1,14 +1,17 @@ import traceback + def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=TestConstructorGlobal] interface TestConstructorGlobal { constructor(); }; - """) + """ + ) results = parser.finish() except: @@ -19,12 +22,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" - [Global, Exposed=TestNamedConstructorGlobal, - NamedConstructor=FooBar] - interface TestNamedConstructorGlobal { + parser.parse( + """ + [Global, Exposed=TestLegacyFactoryFunctionGlobal, + LegacyFactoryFunction=FooBar] + interface TestLegacyFactoryFunctionGlobal { }; - """) + """ + ) results = parser.finish() except: threw = True @@ -34,12 +39,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" - [NamedConstructor=FooBar, Global, - Exposed=TestNamedConstructorGlobal] - interface TestNamedConstructorGlobal { + parser.parse( + """ + [LegacyFactoryFunction=FooBar, Global, + Exposed=TestLegacyFactoryFunctionGlobal] + interface TestLegacyFactoryFunctionGlobal { }; - """) + """ + ) results = parser.finish() except: threw = True @@ -49,12 +56,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=TestHTMLConstructorGlobal] interface TestHTMLConstructorGlobal { [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py index 24cc36066cd..9855352a9d4 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py @@ -1,12 +1,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" - [NoInterfaceObject] - interface TestConstructorNoInterfaceObject { + parser.parse( + """ + [LegacyNoInterfaceObject] + interface TestConstructorLegacyNoInterfaceObject { constructor(); }; - """) + """ + ) results = parser.finish() except: @@ -16,23 +18,27 @@ def WebIDLTest(parser, harness): parser = parser.reset() - parser.parse(""" - [NoInterfaceObject, NamedConstructor=FooBar] - interface TestNamedConstructorNoInterfaceObject { + parser.parse( + """ + [LegacyNoInterfaceObject, LegacyFactoryFunction=FooBar] + interface TestLegacyFactoryFunctionLegacyNoInterfaceObject { }; - """) + """ + ) - # Test HTMLConstructor and NoInterfaceObject + # Test HTMLConstructor and LegacyNoInterfaceObject parser = parser.reset() threw = False try: - parser.parse(""" - [NoInterfaceObject] - interface TestHTMLConstructorNoInterfaceObject { + parser.parse( + """ + [LegacyNoInterfaceObject] + interface TestHTMLConstructorLegacyNoInterfaceObject { [HTMLConstructor] constructor(); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py b/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py index 6249d36fb8f..6649f4ec05d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py @@ -1,15 +1,20 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface Foo; interface Bar; interface Foo; - """); + """ + ) results = parser.finish() # There should be no duplicate interfaces in the result. - expectedNames = sorted(['Foo', 'Bar']) + expectedNames = sorted(["Foo", "Bar"]) actualNames = sorted(map(lambda iface: iface.identifier.name, results)) - harness.check(actualNames, expectedNames, "Parser shouldn't output duplicate names.") + harness.check( + actualNames, expectedNames, "Parser shouldn't output duplicate names." + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py b/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py index dcdc43d5c47..e7d04f995a9 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py @@ -1,5 +1,6 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ dictionary Dict2 : Dict1 { long child = 5; Dict1 aaandAnother; @@ -8,27 +9,33 @@ def WebIDLTest(parser, harness): long parent; double otherParent; }; - """) + """ + ) results = parser.finish() - dict1 = results[1]; - dict2 = results[0]; + dict1 = results[1] + dict2 = results[0] harness.check(len(dict1.members), 2, "Dict1 has two members") harness.check(len(dict2.members), 2, "Dict2 has four members") - harness.check(dict1.members[0].identifier.name, "otherParent", - "'o' comes before 'p'") - harness.check(dict1.members[1].identifier.name, "parent", - "'o' really comes before 'p'") - harness.check(dict2.members[0].identifier.name, "aaandAnother", - "'a' comes before 'c'") - harness.check(dict2.members[1].identifier.name, "child", - "'a' really comes before 'c'") + harness.check( + dict1.members[0].identifier.name, "otherParent", "'o' comes before 'p'" + ) + harness.check( + dict1.members[1].identifier.name, "parent", "'o' really comes before 'p'" + ) + harness.check( + dict2.members[0].identifier.name, "aaandAnother", "'a' comes before 'c'" + ) + harness.check( + dict2.members[1].identifier.name, "child", "'a' really comes before 'c'" + ) # Test partial dictionary. - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ dictionary A { long c; long g; @@ -37,30 +44,29 @@ def WebIDLTest(parser, harness): long h; long d; }; - """) + """ + ) results = parser.finish() - dict1 = results[0]; + dict1 = results[0] harness.check(len(dict1.members), 4, "Dict1 has four members") - harness.check(dict1.members[0].identifier.name, "c", - "c should be first") - harness.check(dict1.members[1].identifier.name, "d", - "d should come after c") - harness.check(dict1.members[2].identifier.name, "g", - "g should come after d") - harness.check(dict1.members[3].identifier.name, "h", - "h should be last") + harness.check(dict1.members[0].identifier.name, "c", "c should be first") + harness.check(dict1.members[1].identifier.name, "d", "d should come after c") + harness.check(dict1.members[2].identifier.name, "g", "g should come after d") + harness.check(dict1.members[3].identifier.name, "h", "h should be last") # Now reset our parser parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Dict { long prop = 5; long prop; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -68,28 +74,33 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should not allow name duplication in a dictionary") # Test no name duplication across normal and partial dictionary. - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { long prop = 5; }; partial dictionary A { long prop; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow name duplication across normal and partial dictionary") + harness.ok( + threw, "Should not allow name duplication across normal and partial dictionary" + ) # Now reset our parser again parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Dict1 : Dict2 { long prop = 5; }; @@ -99,24 +110,28 @@ def WebIDLTest(parser, harness): dictionary Dict3 { double prop; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow name duplication in a dictionary and " - "its ancestor") + harness.ok( + threw, "Should not allow name duplication in a dictionary and " "its ancestor" + ) # More reset parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Iface {}; dictionary Dict : Iface { long prop; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -127,10 +142,12 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A : B {}; dictionary B : A {}; - """) + """ + ) results = parser.finish() except: threw = True @@ -140,27 +157,33 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { - [TreatNullAs=EmptyString] DOMString foo; + [LegacyNullToEmptyString] DOMString foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow [TreatNullAs] on dictionary members"); + harness.ok( + threw, "Should not allow [LegacyNullToEmptyString] on dictionary members" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(A arg); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -170,13 +193,15 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional A arg); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -186,47 +211,53 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo((A or DOMString) arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Trailing union arg containing a dictionary must be optional") + harness.ok(threw, "Trailing union arg containing a dictionary must be optional") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or DOMString) arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Trailing union arg containing a dictionary must have a default value") + harness.ok( + threw, "Trailing union arg containing a dictionary must have a default value" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(A arg1, optional long arg2); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -236,13 +267,15 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional A arg1, optional long arg2); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -252,245 +285,289 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(A arg1, optional long arg2, long arg3); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(not threw, - "Dictionary arg followed by non-optional arg doesn't have to be optional") + harness.ok( + not threw, + "Dictionary arg followed by non-optional arg doesn't have to be optional", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo((A or DOMString) arg1, optional long arg2); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Union arg containing dictionary followed by optional arg must " - "be optional") + harness.ok( + threw, + "Union arg containing dictionary followed by optional arg must " "be optional", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or DOMString) arg1, optional long arg2); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Union arg containing dictionary followed by optional arg must " - "have a default value") + harness.ok( + threw, + "Union arg containing dictionary followed by optional arg must " + "have a default value", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(A arg1, long arg2); }; - """) + """ + ) results = parser.finish() harness.ok(True, "Dictionary arg followed by required arg can be required") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional A? arg1 = {}); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = x harness.ok(threw, "Optional dictionary arg must not be nullable") - harness.ok("nullable" in str(threw), - "Must have the expected exception for optional nullable dictionary arg") + harness.ok( + "nullable" in str(threw), + "Must have the expected exception for optional nullable dictionary arg", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { required long x; }; interface X { undefined doFoo(A? arg1); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = x harness.ok(threw, "Required dictionary arg must not be nullable") - harness.ok("nullable" in str(threw), - "Must have the expected exception for required nullable " - "dictionary arg") + harness.ok( + "nullable" in str(threw), + "Must have the expected exception for required nullable " "dictionary arg", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or long)? arg1 = {}); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = x harness.ok(threw, "Dictionary arg must not be in an optional nullable union") - harness.ok("nullable" in str(threw), - "Must have the expected exception for optional nullable union " - "arg containing dictionary") + harness.ok( + "nullable" in str(threw), + "Must have the expected exception for optional nullable union " + "arg containing dictionary", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { required long x; }; interface X { undefined doFoo((A or long)? arg1); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = x harness.ok(threw, "Dictionary arg must not be in a required nullable union") - harness.ok("nullable" in str(threw), - "Must have the expected exception for required nullable union " - "arg containing dictionary") + harness.ok( + "nullable" in str(threw), + "Must have the expected exception for required nullable union " + "arg containing dictionary", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(sequence<A?> arg1); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(not threw, - "Nullable union should be allowed in a sequence argument") + harness.ok(not threw, "Nullable union should be allowed in a sequence argument") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or long?) arg1); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Dictionary must not be in a union with a nullable type") + harness.ok(threw, "Dictionary must not be in a union with a nullable type") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (long? or A) arg1); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "A nullable type must not be in a union with a dictionary") + harness.ok(threw, "A nullable type must not be in a union with a dictionary") parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { A? doFoo(); }; - """) + """ + ) results = parser.finish() harness.ok(True, "Dictionary return value can be nullable") parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional A arg = {}); }; - """) + """ + ) results = parser.finish() harness.ok(True, "Dictionary arg should actually parse") parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or DOMString) arg = {}); }; - """) + """ + ) results = parser.finish() harness.ok(True, "Union arg containing a dictionary should actually parse") parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary A { }; interface X { undefined doFoo(optional (A or DOMString) arg = "abc"); }; - """) + """ + ) results = parser.finish() - harness.ok(True, "Union arg containing a dictionary with string default should actually parse") + harness.ok( + True, + "Union arg containing a dictionary with string default should actually parse", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { Foo foo; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -500,7 +577,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo3 : Foo { short d; }; @@ -516,78 +594,102 @@ def WebIDLTest(parser, harness): dictionary Foo { Foo1 b; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be a Dictionary that " - "inherits from its Dictionary.") + harness.ok( + threw, + "Member type must not be a Dictionary that " "inherits from its Dictionary.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { (Foo or DOMString)[]? b; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be a Nullable type " - "whose inner type includes its Dictionary.") + harness.ok( + threw, + "Member type must not be a Nullable type " + "whose inner type includes its Dictionary.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { (DOMString or Foo) b; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be a Union type, one of " - "whose member types includes its Dictionary.") + harness.ok( + threw, + "Member type must not be a Union type, one of " + "whose member types includes its Dictionary.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { sequence<sequence<sequence<Foo>>> c; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be a Sequence type " - "whose element type includes its Dictionary.") + harness.ok( + threw, + "Member type must not be a Sequence type " + "whose element type includes its Dictionary.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { (DOMString or Foo)[] d; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be an Array type " - "whose element type includes its Dictionary.") + harness.ok( + threw, + "Member type must not be an Array type " + "whose element type includes its Dictionary.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { Foo1 b; }; @@ -603,34 +705,41 @@ def WebIDLTest(parser, harness): dictionary Foo1 : Foo2 { long a; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Member type must not be a Dictionary, one of whose " - "members or inherited members has a type that includes " - "its Dictionary.") + harness.ok( + threw, + "Member type must not be a Dictionary, one of whose " + "members or inherited members has a type that includes " + "its Dictionary.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { }; dictionary Bar { Foo? d; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Member type must not be a nullable dictionary") - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ dictionary Foo { unrestricted float urFloat = 0; unrestricted float urFloat2 = 1.1; @@ -648,103 +757,117 @@ def WebIDLTest(parser, harness): unrestricted double negativeInfUrDouble = -Infinity; unrestricted double nanUrDouble = NaN; }; - """) + """ + ) results = parser.finish() harness.ok(True, "Parsing default values for unrestricted types succeeded.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { double f = Infinity; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to Infinity") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { double f = -Infinity; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { double f = NaN; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to NaN") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { float f = Infinity; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to Infinity") - - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { float f = -Infinity; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { float f = NaN; }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "Only unrestricted values can be initialized to NaN") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Foo { long module; }; - """) + """ + ) results = parser.finish() except: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py index 1fa12832d7f..e96026c2a09 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py @@ -1,8 +1,13 @@ +import traceback + + def firstArgType(method): return method.signatures()[0][1][0].type + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ // Give our dictionary a required member so we don't need to // mess with optional and default values. dictionary Dict { @@ -17,7 +22,8 @@ def WebIDLTest(parser, harness): undefined passNullableUnion((object? or DOMString) arg); undefined passNullable(Foo? arg); }; - """) + """ + ) results = parser.finish() iface = results[2] @@ -30,31 +36,38 @@ def WebIDLTest(parser, harness): dictType = firstArgType(dictMethod) ifaceType = firstArgType(ifaceMethod) - harness.ok(dictType.isDictionary(), "Should have dictionary type"); - harness.ok(ifaceType.isInterface(), "Should have interface type"); - harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type"); + harness.ok(dictType.isDictionary(), "Should have dictionary type") + harness.ok(ifaceType.isInterface(), "Should have interface type") + harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type") - harness.ok(not dictType.isDistinguishableFrom(ifaceType), - "Dictionary not distinguishable from callback interface") - harness.ok(not ifaceType.isDistinguishableFrom(dictType), - "Callback interface not distinguishable from dictionary") + harness.ok( + not dictType.isDistinguishableFrom(ifaceType), + "Dictionary not distinguishable from callback interface", + ) + harness.ok( + not ifaceType.isDistinguishableFrom(dictType), + "Callback interface not distinguishable from dictionary", + ) nullableUnionType = firstArgType(nullableUnionMethod) nullableIfaceType = firstArgType(nullableIfaceMethod) - harness.ok(nullableUnionType.isUnion(), "Should have union type"); - harness.ok(nullableIfaceType.isInterface(), "Should have interface type"); - harness.ok(nullableIfaceType.nullable(), "Should have nullable type"); + harness.ok(nullableUnionType.isUnion(), "Should have union type") + harness.ok(nullableIfaceType.isInterface(), "Should have interface type") + harness.ok(nullableIfaceType.nullable(), "Should have nullable type") - harness.ok(not nullableUnionType.isDistinguishableFrom(nullableIfaceType), - "Nullable type not distinguishable from union with nullable " - "member type") - harness.ok(not nullableIfaceType.isDistinguishableFrom(nullableUnionType), - "Union with nullable member type not distinguishable from " - "nullable type") + harness.ok( + not nullableUnionType.isDistinguishableFrom(nullableIfaceType), + "Nullable type not distinguishable from union with nullable " "member type", + ) + harness.ok( + not nullableIfaceType.isDistinguishableFrom(nullableUnionType), + "Union with nullable member type not distinguishable from " "nullable type", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestIface { undefined passKid(Kid arg); undefined passParent(Parent arg); @@ -70,7 +83,8 @@ def WebIDLTest(parser, harness): interface Grandparent {}; interface Unrelated1 {}; interface Unrelated2 {}; - """) + """ + ) results = parser.finish() iface = results[0] @@ -80,21 +94,26 @@ def WebIDLTest(parser, harness): for type1 in argTypes: for type2 in argTypes: - distinguishable = (type1 is not type2 and - (type1 in unrelatedTypes or - type2 in unrelatedTypes)) - - harness.check(type1.isDistinguishableFrom(type2), - distinguishable, - "Type %s should %sbe distinguishable from type %s" % - (type1, "" if distinguishable else "not ", type2)) - harness.check(type2.isDistinguishableFrom(type1), - distinguishable, - "Type %s should %sbe distinguishable from type %s" % - (type2, "" if distinguishable else "not ", type1)) + distinguishable = type1 is not type2 and ( + type1 in unrelatedTypes or type2 in unrelatedTypes + ) + + harness.check( + type1.isDistinguishableFrom(type2), + distinguishable, + "Type %s should %sbe distinguishable from type %s" + % (type1, "" if distinguishable else "not ", type2), + ) + harness.check( + type2.isDistinguishableFrom(type1), + distinguishable, + "Type %s should %sbe distinguishable from type %s" + % (type2, "" if distinguishable else "not ", type1), + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface Dummy {}; interface TestIface { undefined method(long arg1, TestIface arg2); @@ -102,17 +121,19 @@ def WebIDLTest(parser, harness): undefined method(long arg1, Dummy arg2); undefined method(DOMString arg1, DOMString arg2, DOMString arg3); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[1].members), 1, - "Should look like we have one method") - harness.check(len(results[1].members[0].signatures()), 4, - "Should have four signatures") + harness.check(len(results[1].members), 1, "Should look like we have one method") + harness.check( + len(results[1].members[0].signatures()), 4, "Should have four signatures" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Dummy {}; interface TestIface { undefined method(long arg1, TestIface arg2); @@ -120,19 +141,23 @@ def WebIDLTest(parser, harness): undefined method(any arg1, Dummy arg2); undefined method(DOMString arg1, DOMString arg2, DOMString arg3); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should throw when args before the distinguishing arg are not " - "all the same type") + harness.ok( + threw, + "Should throw when args before the distinguishing arg are not " + "all the same type", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Dummy {}; interface TestIface { undefined method(long arg1, TestIface arg2); @@ -140,7 +165,8 @@ def WebIDLTest(parser, harness): undefined method(any arg1, DOMString arg2); undefined method(DOMString arg1, DOMString arg2, DOMString arg3); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -148,57 +174,133 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should throw when there is no distinguishing index") # Now let's test our whole distinguishability table - argTypes = [ "long", "short", "long?", "short?", "boolean", - "boolean?", "DOMString", "ByteString", "UTF8String", "Enum", "Enum2", - "Interface", "Interface?", - "AncestorInterface", "UnrelatedInterface", "CallbackInterface", - "CallbackInterface?", "CallbackInterface2", - "object", "Callback", "Callback2", "Dict", - "Dict2", "sequence<long>", "sequence<short>", - "record<DOMString, object>", - "record<USVString, Dict>", - "record<ByteString, long>", - "record<UTF8String, long>", - "any", "Promise<any>", "Promise<any>?", - "USVString", "JSString", "ArrayBuffer", "ArrayBufferView", - "Uint8Array", "Uint16Array", - "(long or Callback)", "(long or Dict)", + argTypes = [ + "long", + "short", + "long?", + "short?", + "boolean", + "boolean?", + "undefined", + "undefined?", + "DOMString", + "ByteString", + "UTF8String", + "Enum", + "Enum2", + "Interface", + "Interface?", + "AncestorInterface", + "UnrelatedInterface", + "CallbackInterface", + "CallbackInterface?", + "CallbackInterface2", + "object", + "Callback", + "Callback2", + "Dict", + "Dict2", + "sequence<long>", + "sequence<short>", + "record<DOMString, object>", + "record<USVString, Dict>", + "record<ByteString, long>", + "record<UTF8String, long>", + "any", + "Promise<any>", + "Promise<any>?", + "USVString", + "JSString", + "ArrayBuffer", + "ArrayBufferView", + "Uint8Array", + "Uint16Array", + "(long or Callback)", + "(long or Dict)", ] # Try to categorize things a bit to keep list lengths down def allBut(list1, list2): - return [a for a in list1 if a not in list2 and - (a != "any" and a != "Promise<any>" and a != "Promise<any>?")] - unions = [ "(long or Callback)", "(long or Dict)" ] - numerics = [ "long", "short", "long?", "short?" ] - booleans = [ "boolean", "boolean?" ] + return [ + a + for a in list1 + if a not in list2 + and (a != "any" and a != "Promise<any>" and a != "Promise<any>?") + ] + + unions = ["(long or Callback)", "(long or Dict)"] + numerics = ["long", "short", "long?", "short?"] + booleans = ["boolean", "boolean?"] + undefineds = ["undefined", "undefined?"] primitives = numerics + booleans nonNumerics = allBut(argTypes, numerics + unions) nonBooleans = allBut(argTypes, booleans) - strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString", "UTF8String" ] + strings = [ + "DOMString", + "ByteString", + "Enum", + "Enum2", + "USVString", + "JSString", + "UTF8String", + ] nonStrings = allBut(argTypes, strings) - nonObjects = primitives + strings - objects = allBut(argTypes, nonObjects ) + nonObjects = undefineds + primitives + strings + objects = allBut(argTypes, nonObjects) bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"] - interfaces = [ "Interface", "Interface?", "AncestorInterface", - "UnrelatedInterface" ] + bufferSourceTypes - nullables = (["long?", "short?", "boolean?", "Interface?", - "CallbackInterface?", "Dict", "Dict2", - "Date?", "any", "Promise<any>?"] + - allBut(unions, [ "(long or Callback)" ])) - sequences = [ "sequence<long>", "sequence<short>" ] + interfaces = [ + "Interface", + "Interface?", + "AncestorInterface", + "UnrelatedInterface", + ] + bufferSourceTypes + nullables = [ + "long?", + "short?", + "boolean?", + "undefined?", + "Interface?", + "CallbackInterface?", + "Dict", + "Dict2", + "Date?", + "any", + "Promise<any>?", + ] + allBut(unions, ["(long or Callback)"]) + sequences = ["sequence<long>", "sequence<short>"] nonUserObjects = nonObjects + interfaces + sequences otherObjects = allBut(argTypes, nonUserObjects + ["object"]) - notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] + - otherObjects + sequences + bufferSourceTypes) - records = [ "record<DOMString, object>", "record<USVString, Dict>", - "record<ByteString, long>", "record<UTF8String, long>" ] # JSString not supported in records + notRelatedInterfaces = ( + nonObjects + + ["UnrelatedInterface"] + + otherObjects + + sequences + + bufferSourceTypes + ) + records = [ + "record<DOMString, object>", + "record<USVString, Dict>", + "record<ByteString, long>", + "record<UTF8String, long>", + ] # JSString not supported in records + dictionaryLike = ( + [ + "Dict", + "Dict2", + "CallbackInterface", + "CallbackInterface?", + "CallbackInterface2", + ] + + records + + allBut(unions, ["(long or Callback)"]) + ) # Build a representation of the distinguishability table as a dict # of dicts, holding True values where needed, holes elsewhere. - data = dict(); + data = dict() for type in argTypes: data[type] = dict() + def setDistinguishable(type, types): for other in types: data[type][other] = True @@ -209,6 +311,10 @@ def WebIDLTest(parser, harness): setDistinguishable("short?", allBut(nonNumerics, nullables)) setDistinguishable("boolean", nonBooleans) setDistinguishable("boolean?", allBut(nonBooleans, nullables)) + setDistinguishable("undefined", allBut(argTypes, undefineds + dictionaryLike)) + setDistinguishable( + "undefined?", allBut(argTypes, undefineds + dictionaryLike + nullables) + ) setDistinguishable("DOMString", nonStrings) setDistinguishable("ByteString", nonStrings) setDistinguishable("UTF8String", nonStrings) @@ -219,36 +325,44 @@ def WebIDLTest(parser, harness): setDistinguishable("Interface", notRelatedInterfaces) setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables)) setDistinguishable("AncestorInterface", notRelatedInterfaces) - setDistinguishable("UnrelatedInterface", - allBut(argTypes, ["object", "UnrelatedInterface"])) - setDistinguishable("CallbackInterface", nonUserObjects) - setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables)) - setDistinguishable("CallbackInterface2", nonUserObjects) + setDistinguishable( + "UnrelatedInterface", allBut(argTypes, ["object", "UnrelatedInterface"]) + ) + setDistinguishable("CallbackInterface", allBut(nonUserObjects, undefineds)) + setDistinguishable( + "CallbackInterface?", allBut(nonUserObjects, nullables + undefineds) + ) + setDistinguishable("CallbackInterface2", allBut(nonUserObjects, undefineds)) setDistinguishable("object", nonObjects) setDistinguishable("Callback", nonUserObjects) setDistinguishable("Callback2", nonUserObjects) - setDistinguishable("Dict", allBut(nonUserObjects, nullables)) - setDistinguishable("Dict2", allBut(nonUserObjects, nullables)) - setDistinguishable("sequence<long>", - allBut(argTypes, sequences + ["object"])) - setDistinguishable("sequence<short>", - allBut(argTypes, sequences + ["object"])) - setDistinguishable("record<DOMString, object>", nonUserObjects) - setDistinguishable("record<USVString, Dict>", nonUserObjects) + setDistinguishable("Dict", allBut(nonUserObjects, nullables + undefineds)) + setDistinguishable("Dict2", allBut(nonUserObjects, nullables + undefineds)) + setDistinguishable("sequence<long>", allBut(argTypes, sequences + ["object"])) + setDistinguishable("sequence<short>", allBut(argTypes, sequences + ["object"])) + setDistinguishable("record<DOMString, object>", allBut(nonUserObjects, undefineds)) + setDistinguishable("record<USVString, Dict>", allBut(nonUserObjects, undefineds)) # JSString not supported in records - setDistinguishable("record<ByteString, long>", nonUserObjects) - setDistinguishable("record<UTF8String, long>", nonUserObjects) + setDistinguishable("record<ByteString, long>", allBut(nonUserObjects, undefineds)) + setDistinguishable("record<UTF8String, long>", allBut(nonUserObjects, undefineds)) setDistinguishable("any", []) setDistinguishable("Promise<any>", []) setDistinguishable("Promise<any>?", []) setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"])) - setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"])) - setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"])) - setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"])) - setDistinguishable("(long or Callback)", - allBut(nonUserObjects, numerics)) - setDistinguishable("(long or Dict)", - allBut(nonUserObjects, numerics + nullables)) + setDistinguishable( + "ArrayBufferView", + allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]), + ) + setDistinguishable( + "Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]) + ) + setDistinguishable( + "Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]) + ) + setDistinguishable("(long or Callback)", allBut(nonUserObjects, numerics)) + setDistinguishable( + "(long or Dict)", allBut(nonUserObjects, numerics + nullables + undefineds) + ) def areDistinguishable(type1, type2): return data[type1].get(type2, False) @@ -271,10 +385,18 @@ def WebIDLTest(parser, harness): interface TestInterface {%s }; """ - methodTemplate = """ - undefined myMethod(%s arg);""" - methods = (methodTemplate % type1) + (methodTemplate % type2) + if type1 in undefineds or type2 in undefineds: + methods = """ + (%s or %s) myMethod();""" % ( + type1, + type2, + ) + else: + methodTemplate = """ + undefined myMethod(%s arg);""" + methods = (methodTemplate % type1) + (methodTemplate % type2) idl = idlTemplate % methods + parser = parser.reset() threw = False try: @@ -284,11 +406,17 @@ def WebIDLTest(parser, harness): threw = True if areDistinguishable(type1, type2): - harness.ok(not threw, - "Should not throw for '%s' and '%s' because they are distinguishable" % (type1, type2)) + harness.ok( + not threw, + "Should not throw for '%s' and '%s' because they are distinguishable" + % (type1, type2), + ) else: - harness.ok(threw, - "Should throw for '%s' and '%s' because they are not distinguishable" % (type1, type2)) + harness.ok( + threw, + "Should throw for '%s' and '%s' because they are not distinguishable" + % (type1, type2), + ) # Enumerate over everything in both orders, since order matters in # terms of our implementation of distinguishability checks diff --git a/components/script/dom/bindings/codegen/parser/tests/test_double_null.py b/components/script/dom/bindings/codegen/parser/tests/test_double_null.py index 700c7eade00..a8876a7fd2d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_double_null.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_double_null.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DoubleNull { attribute byte?? foo; }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py b/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py index 4874b3aafe6..89a4e1acf0b 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DuplicateQualifiers1 { getter getter byte foo(unsigned long index); }; - """) + """ + ) results = parser.finish() except: @@ -15,11 +17,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DuplicateQualifiers2 { setter setter byte foo(unsigned long index, byte value); }; - """) + """ + ) results = parser.finish() except: @@ -29,11 +33,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DuplicateQualifiers4 { deleter deleter byte foo(unsigned long index); }; - """) + """ + ) results = parser.finish() except: @@ -43,11 +49,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface DuplicateQualifiers5 { getter deleter getter byte foo(unsigned long index); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py b/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py index ee0079f06da..09333a659cd 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py @@ -1,11 +1,14 @@ import WebIDL + def WebIDLTest(parser, harness): try: - parser.parse(""" + parser.parse( + """ enum TestEmptyEnum { }; - """) + """ + ) harness.ok(False, "Should have thrown!") except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py b/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py index 5f04c6ae751..21837743523 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py @@ -1,13 +1,16 @@ import WebIDL + def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface X { const sequence<long> foo = []; }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -17,29 +20,35 @@ def WebIDLTest(parser, harness): parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface X { undefined foo(optional sequence<long> arg = []); }; - """) - results = parser.finish(); - - harness.ok(isinstance( - results[0].members[0].signatures()[0][1][0].defaultValue, - WebIDL.IDLEmptySequenceValue), - "Should have IDLEmptySequenceValue as default value of argument") + """ + ) + results = parser.finish() + + harness.ok( + isinstance( + results[0].members[0].signatures()[0][1][0].defaultValue, + WebIDL.IDLEmptySequenceValue, + ), + "Should have IDLEmptySequenceValue as default value of argument", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary X { sequence<long> foo = []; }; - """) - results = parser.finish(); - - harness.ok(isinstance(results[0].members[0].defaultValue, - WebIDL.IDLEmptySequenceValue), - "Should have IDLEmptySequenceValue as default value of " - "dictionary member") - + """ + ) + results = parser.finish() + + harness.ok( + isinstance(results[0].members[0].defaultValue, WebIDL.IDLEmptySequenceValue), + "Should have IDLEmptySequenceValue as default value of " "dictionary member", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_enum.py b/components/script/dom/bindings/codegen/parser/tests/test_enum.py index c5617ead99a..56c6b3f64aa 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_enum.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_enum.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ enum TestEnum { "", "foo", @@ -12,16 +14,15 @@ def WebIDLTest(parser, harness): TestEnum doFoo(boolean arg); readonly attribute TestEnum foo; }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestEnumInterfaces interface parsed without error.") harness.check(len(results), 2, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLEnum), - "Should be an IDLEnum") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLEnum), "Should be an IDLEnum") + harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") enum = results[0] harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName") @@ -30,32 +31,41 @@ def WebIDLTest(parser, harness): iface = results[1] - harness.check(iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName") - harness.check(iface.identifier.name, "TestEnumInterface", "Interface has the right name") + harness.check( + iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName" + ) + harness.check( + iface.identifier.name, "TestEnumInterface", "Interface has the right name" + ) harness.check(iface.parent, None, "Interface has no parent") members = iface.members harness.check(len(members), 2, "Should be one production") - harness.ok(isinstance(members[0], WebIDL.IDLMethod), - "Should be an IDLMethod") + harness.ok(isinstance(members[0], WebIDL.IDLMethod), "Should be an IDLMethod") method = members[0] - harness.check(method.identifier.QName(), "::TestEnumInterface::doFoo", - "Method has correct QName") + harness.check( + method.identifier.QName(), + "::TestEnumInterface::doFoo", + "Method has correct QName", + ) harness.check(method.identifier.name, "doFoo", "Method has correct name") signatures = method.signatures() harness.check(len(signatures), 1, "Expect one signature") (returnType, arguments) = signatures[0] - harness.check(str(returnType), "TestEnum (Wrapper)", "Method type is the correct name") + harness.check( + str(returnType), "TestEnum (Wrapper)", "Method type is the correct name" + ) harness.check(len(arguments), 1, "Method has the right number of arguments") arg = arguments[0] harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument") harness.check(str(arg.type), "Boolean", "Argument has the right type") attr = members[1] - harness.check(attr.identifier.QName(), "::TestEnumInterface::foo", - "Attr has correct QName") + harness.check( + attr.identifier.QName(), "::TestEnumInterface::foo", "Attr has correct QName" + ) harness.check(attr.identifier.name, "foo", "Attr has correct name") harness.check(str(attr.type), "TestEnum (Wrapper)", "Attr type is the correct name") @@ -64,7 +74,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ enum Enum { "a", "b", @@ -73,7 +84,8 @@ def WebIDLTest(parser, harness): interface TestInterface { undefined foo(optional Enum e = "d"); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -82,12 +94,14 @@ def WebIDLTest(parser, harness): # Now reset our parser parser = parser.reset() - parser.parse(""" + parser.parse( + """ enum Enum { "a", "b", "c", }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should allow trailing comma in enum") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py b/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py index 51205d209e7..8969281e1c7 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py @@ -1,13 +1,16 @@ import WebIDL + def WebIDLTest(parser, harness): try: - parser.parse(""" + parser.parse( + """ enum TestEnumDuplicateValue { "", "" }; - """) + """ + ) harness.ok(False, "Should have thrown!") except: harness.ok(True, "Enum TestEnumDuplicateValue should throw") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py b/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py index 7afd15513c6..1c9bb065580 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py @@ -1,20 +1,24 @@ import WebIDL + def WebIDLTest(parser, harness): # Check that error messages put the '^' in the right place. threw = False - input = 'interface ?' + input = "interface ?" try: parser.parse(input) results = parser.finish() except WebIDL.WebIDLError as e: threw = True - lines = str(e).split('\n') + lines = str(e).split("\n") - harness.check(len(lines), 3, 'Expected number of lines in error message') - harness.check(lines[1], input, 'Second line shows error') - harness.check(lines[2], ' ' * (len(input) - 1) + '^', - 'Correct column pointer in error message') + harness.check(len(lines), 3, "Expected number of lines in error message") + harness.check(lines[1], input, "Second line shows error") + harness.check( + lines[2], + " " * (len(input) - 1) + "^", + "Correct column pointer in error message", + ) harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py b/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py index 70bb1883682..0d10e006787 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py @@ -1,5 +1,6 @@ import WebIDL + def WebIDLTest(parser, harness): # Check that error messages put the '^' in the right place. @@ -16,13 +17,22 @@ interface ?""" results = parser.finish() except WebIDL.WebIDLError as e: threw = True - lines = str(e).split('\n') + lines = str(e).split("\n") - harness.check(len(lines), 3, 'Expected number of lines in error message') - harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0]) - harness.check(lines[1], 'interface ?', 'Second line of error message is the line which caused the error.') - harness.check(lines[2], ' ' * (len('interface ?') - 1) + '^', - 'Correct column pointer in error message.') + harness.check(len(lines), 3, "Expected number of lines in error message") + harness.ok( + lines[0].endswith("line 6:10"), + 'First line of error should end with "line 6:10", but was "%s".' % lines[0], + ) + harness.check( + lines[1], + "interface ?", + "Second line of error message is the line which caused the error.", + ) + harness.check( + lines[2], + " " * (len("interface ?") - 1) + "^", + "Correct column pointer in error message.", + ) harness.ok(threw, "Should have thrown.") - diff --git a/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py b/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py index 39993eaeae5..c5ea8e4b88b 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo {}; [Global=(Bar, Bar1,Bar2), Exposed=Bar] interface Bar {}; [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; @@ -18,39 +20,56 @@ def WebIDLTest(parser, harness): partial interface Iface { undefined method2(); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 5, "Should know about five things"); + harness.check(len(results), 5, "Should know about five things") iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should have an interface here"); + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") members = iface.members harness.check(len(members), 3, "Should have three members") - harness.ok(members[0].exposureSet == set(["Foo", "Bar"]), - "method1 should have the right exposure set") - harness.ok(members[0]._exposureGlobalNames == set(["Foo", "Bar1"]), - "method1 should have the right exposure global names") - - harness.ok(members[1].exposureSet == set(["Bar"]), - "attr should have the right exposure set") - harness.ok(members[1]._exposureGlobalNames == set(["Bar1"]), - "attr should have the right exposure global names") - - harness.ok(members[2].exposureSet == set(["Foo"]), - "method2 should have the right exposure set") - harness.ok(members[2]._exposureGlobalNames == set(["Foo"]), - "method2 should have the right exposure global names") - - harness.ok(iface.exposureSet == set(["Foo", "Bar"]), - "Iface should have the right exposure set") - harness.ok(iface._exposureGlobalNames == set(["Foo", "Bar1"]), - "Iface should have the right exposure global names") + harness.ok( + members[0].exposureSet == set(["Foo", "Bar"]), + "method1 should have the right exposure set", + ) + harness.ok( + members[0]._exposureGlobalNames == set(["Foo", "Bar1"]), + "method1 should have the right exposure global names", + ) + + harness.ok( + members[1].exposureSet == set(["Bar"]), + "attr should have the right exposure set", + ) + harness.ok( + members[1]._exposureGlobalNames == set(["Bar1"]), + "attr should have the right exposure global names", + ) + + harness.ok( + members[2].exposureSet == set(["Foo"]), + "method2 should have the right exposure set", + ) + harness.ok( + members[2]._exposureGlobalNames == set(["Foo"]), + "method2 should have the right exposure global names", + ) + + harness.ok( + iface.exposureSet == set(["Foo", "Bar"]), + "Iface should have the right exposure set", + ) + harness.ok( + iface._exposureGlobalNames == set(["Foo", "Bar1"]), + "Iface should have the right exposure global names", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo {}; [Global=(Bar, Bar1, Bar2), Exposed=Bar] interface Bar {}; [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; @@ -59,28 +78,36 @@ def WebIDLTest(parser, harness): interface Iface2 { undefined method3(); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 4, "Should know about four things"); + harness.check(len(results), 4, "Should know about four things") iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should have an interface here"); + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") members = iface.members harness.check(len(members), 1, "Should have one member") - harness.ok(members[0].exposureSet == set(["Foo"]), - "method3 should have the right exposure set") - harness.ok(members[0]._exposureGlobalNames == set(["Foo"]), - "method3 should have the right exposure global names") - - harness.ok(iface.exposureSet == set(["Foo"]), - "Iface2 should have the right exposure set") - harness.ok(iface._exposureGlobalNames == set(["Foo"]), - "Iface2 should have the right exposure global names") + harness.ok( + members[0].exposureSet == set(["Foo"]), + "method3 should have the right exposure set", + ) + harness.ok( + members[0]._exposureGlobalNames == set(["Foo"]), + "method3 should have the right exposure global names", + ) + + harness.ok( + iface.exposureSet == set(["Foo"]), "Iface2 should have the right exposure set" + ) + harness.ok( + iface._exposureGlobalNames == set(["Foo"]), + "Iface2 should have the right exposure global names", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo {}; [Global=(Bar, Bar1, Bar2), Exposed=Bar] interface Bar {}; [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; @@ -96,33 +123,43 @@ def WebIDLTest(parser, harness): }; Iface3 includes Mixin; - """) + """ + ) results = parser.finish() - harness.check(len(results), 6, "Should know about six things"); + harness.check(len(results), 6, "Should know about six things") iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should have an interface here"); + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") members = iface.members harness.check(len(members), 2, "Should have two members") - harness.ok(members[0].exposureSet == set(["Foo"]), - "method4 should have the right exposure set") - harness.ok(members[0]._exposureGlobalNames == set(["Foo"]), - "method4 should have the right exposure global names") - - harness.ok(members[1].exposureSet == set(["Foo", "Bar"]), - "method5 should have the right exposure set") - harness.ok(members[1]._exposureGlobalNames == set(["Foo", "Bar1"]), - "method5 should have the right exposure global names") + harness.ok( + members[0].exposureSet == set(["Foo"]), + "method4 should have the right exposure set", + ) + harness.ok( + members[0]._exposureGlobalNames == set(["Foo"]), + "method4 should have the right exposure global names", + ) + + harness.ok( + members[1].exposureSet == set(["Foo", "Bar"]), + "method5 should have the right exposure set", + ) + harness.ok( + members[1]._exposureGlobalNames == set(["Foo", "Bar1"]), + "method5 should have the right exposure global names", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Exposed=Foo] interface Bar { }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -133,12 +170,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Bar { [Exposed=Foo] readonly attribute bool attr; }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -149,12 +188,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Bar { [Exposed=Foo] undefined operation(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -165,12 +206,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Bar { [Exposed=Foo] const long constant = 5; }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -181,7 +224,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo {}; [Global, Exposed=Bar] interface Bar {}; @@ -190,16 +234,20 @@ def WebIDLTest(parser, harness): [Exposed=Bar] undefined method(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, "Should have thrown on member exposed where its interface is not.") + harness.ok( + threw, "Should have thrown on member exposed where its interface is not." + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo {}; [Global, Exposed=Bar] interface Bar {}; @@ -214,25 +262,122 @@ def WebIDLTest(parser, harness): }; Baz includes Mixin; - """) + """ + ) results = parser.finish() - harness.check(len(results), 5, "Should know about five things"); + harness.check(len(results), 5, "Should know about five things") iface = results[2] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should have an interface here"); + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") members = iface.members harness.check(len(members), 2, "Should have two members") - harness.ok(members[0].exposureSet == set(["Foo"]), - "method should have the right exposure set") - harness.ok(members[0]._exposureGlobalNames == set(["Foo"]), - "method should have the right exposure global names") + harness.ok( + members[0].exposureSet == set(["Foo"]), + "method should have the right exposure set", + ) + harness.ok( + members[0]._exposureGlobalNames == set(["Foo"]), + "method should have the right exposure global names", + ) + + harness.ok( + members[1].exposureSet == set(["Bar"]), + "otherMethod should have the right exposure set", + ) + harness.ok( + members[1]._exposureGlobalNames == set(["Bar"]), + "otherMethod should have the right exposure global names", + ) + + parser = parser.reset() + parser.parse( + """ + [Global, Exposed=Foo] interface Foo {}; + [Global, Exposed=Bar] interface Bar {}; + + [Exposed=*] + interface Baz { + undefined methodWild(); + }; + + [Exposed=Bar] + interface mixin Mixin { + undefined methodNotWild(); + }; + + Baz includes Mixin; + """ + ) + + results = parser.finish() + + harness.check(len(results), 5, "Should know about five things") + iface = results[2] + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") + members = iface.members + harness.check(len(members), 2, "Should have two members") + + harness.ok( + members[0].exposureSet == set(["Foo", "Bar"]), + "methodWild should have the right exposure set", + ) + harness.ok( + members[0]._exposureGlobalNames == set(["Foo", "Bar"]), + "methodWild should have the right exposure global names", + ) + + harness.ok( + members[1].exposureSet == set(["Bar"]), + "methodNotWild should have the right exposure set", + ) + harness.ok( + members[1]._exposureGlobalNames == set(["Bar"]), + "methodNotWild should have the right exposure global names", + ) + + parser = parser.reset() + threw = False + try: + parser.parse( + """ + [Global, Exposed=Foo] interface Foo {}; + [Global, Exposed=Bar] interface Bar {}; + + [Exposed=Foo] + interface Baz { + [Exposed=*] + undefined method(); + }; + """ + ) + + results = parser.finish() + except Exception as x: + threw = True - harness.ok(members[1].exposureSet == set(["Bar"]), - "otherMethod should have the right exposure set") - harness.ok(members[1]._exposureGlobalNames == set(["Bar"]), - "otherMethod should have the right exposure global names") + harness.ok( + threw, "Should have thrown on member exposed where its interface is not." + ) + parser = parser.reset() + threw = False + try: + parser.parse( + """ + [Global, Exposed=Foo] interface Foo {}; + [Global, Exposed=Bar] interface Bar {}; + + [Exposed=(Foo,*)] + interface Baz { + undefined method(); + }; + """ + ) + + results = parser.finish() + except Exception as x: + threw = True + harness.ok(threw, "Should have thrown on a wildcard in an identifier list.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py b/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py index 66909f322c2..423a67540c7 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py @@ -1,74 +1,91 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" - [NoInterfaceObject] + parser.parse( + """ + [LegacyNoInterfaceObject] interface TestExtendedAttr { - [Unforgeable] readonly attribute byte b; + [LegacyUnforgeable] readonly attribute byte b; }; - """) + """ + ) results = parser.finish() parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Pref="foo.bar",Pref=flop] interface TestExtendedAttr { [Pref="foo.bar"] attribute byte b; }; - """) + """ + ) results = parser.finish() parser = parser.reset() - parser.parse(""" - interface TestLenientThis { - [LenientThis] attribute byte b; + parser.parse( + """ + interface TestLegacyLenientThis { + [LegacyLenientThis] attribute byte b; }; - """) + """ + ) results = parser.finish() - harness.ok(results[0].members[0].hasLenientThis(), - "Should have a lenient this") + harness.ok( + results[0].members[0].hasLegacyLenientThis(), "Should have a lenient this" + ) parser = parser.reset() threw = False try: - parser.parse(""" - interface TestLenientThis2 { - [LenientThis=something] attribute byte b; + parser.parse( + """ + interface TestLegacyLenientThis2 { + [LegacyLenientThis=something] attribute byte b; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "[LenientThis] must take no arguments") + harness.ok(threw, "[LegacyLenientThis] must take no arguments") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestClamp { undefined testClamp([Clamp] long foo); undefined testNotClamp(long foo); }; - """) + """ + ) results = parser.finish() # Pull out the first argument out of the arglist of the first (and # only) signature. - harness.ok(results[0].members[0].signatures()[0][1][0].type.hasClamp(), - "Should be clamped") - harness.ok(not results[0].members[1].signatures()[0][1][0].type.hasClamp(), - "Should not be clamped") + harness.ok( + results[0].members[0].signatures()[0][1][0].type.hasClamp(), "Should be clamped" + ) + harness.ok( + not results[0].members[1].signatures()[0][1][0].type.hasClamp(), + "Should not be clamped", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestClamp2 { undefined testClamp([Clamp=something] long foo); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -76,32 +93,39 @@ def WebIDLTest(parser, harness): harness.ok(threw, "[Clamp] must take no arguments") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestEnforceRange { undefined testEnforceRange([EnforceRange] long foo); undefined testNotEnforceRange(long foo); }; - """) + """ + ) results = parser.finish() # Pull out the first argument out of the arglist of the first (and # only) signature. - harness.ok(results[0].members[0].signatures()[0][1][0].type.hasEnforceRange(), - "Should be enforceRange") - harness.ok(not results[0].members[1].signatures()[0][1][0].type.hasEnforceRange(), - "Should not be enforceRange") + harness.ok( + results[0].members[0].signatures()[0][1][0].type.hasEnforceRange(), + "Should be enforceRange", + ) + harness.ok( + not results[0].members[1].signatures()[0][1][0].type.hasEnforceRange(), + "Should not be enforceRange", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestEnforceRange2 { undefined testEnforceRange([EnforceRange=something] long foo); }; - """) + """ + ) results = parser.finish() except: threw = True harness.ok(threw, "[EnforceRange] must take no arguments") - diff --git a/components/script/dom/bindings/codegen/parser/tests/test_float_types.py b/components/script/dom/bindings/codegen/parser/tests/test_float_types.py index 8fbe9394042..d37443819d8 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_float_types.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_float_types.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ typedef float myFloat; typedef unrestricted float myUnrestrictedFloat; interface FloatTypes { @@ -15,14 +17,14 @@ def WebIDLTest(parser, harness): attribute double ld; undefined m1(float arg1, double arg2, float? arg3, double? arg4, - myFloat arg5, unrestricted float arg6, - unrestricted double arg7, unrestricted float? arg8, - unrestricted double? arg9, myUnrestrictedFloat arg10); + myFloat arg5, unrestricted float arg6, + unrestricted double arg7, unrestricted float? arg8, + unrestricted double? arg9, myUnrestrictedFloat arg10); [LenientFloat] undefined m2(float arg1, double arg2, float? arg3, double? arg4, - myFloat arg5, unrestricted float arg6, - unrestricted double arg7, unrestricted float? arg8, - unrestricted double? arg9, myUnrestrictedFloat arg10); + myFloat arg5, unrestricted float arg6, + unrestricted double arg7, unrestricted float? arg8, + unrestricted double? arg9, myUnrestrictedFloat arg10); [LenientFloat] undefined m3(float arg); [LenientFloat] @@ -32,14 +34,14 @@ def WebIDLTest(parser, harness): [LenientFloat] undefined m6(sequence<float> arg); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 3, "Should be two typedefs and one interface.") iface = results[2] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") types = [a.type for a in iface.members if a.isAttr()] harness.ok(types[0].isFloat(), "'float' is a float") harness.ok(not types[0].isUnrestricted(), "'float' is not unrestricted") @@ -55,71 +57,89 @@ def WebIDLTest(parser, harness): argtypes = [a.type for a in method.signatures()[0][1]] for (idx, type) in enumerate(argtypes): harness.ok(type.isFloat(), "Type %d should be float" % idx) - harness.check(type.isUnrestricted(), idx >= 5, - "Type %d should %sbe unrestricted" % ( - idx, "" if idx >= 4 else "not ")) + harness.check( + type.isUnrestricted(), + idx >= 5, + "Type %d should %sbe unrestricted" % (idx, "" if idx >= 4 else "not "), + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface FloatTypes { [LenientFloat] long m(float arg); }; - """) + """ + ) except Exception as x: threw = True - harness.ok(threw, "[LenientFloat] only allowed on undefined-retuning methods") + harness.ok(threw, "[LenientFloat] only allowed on methods returning undefined") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface FloatTypes { [LenientFloat] undefined m(unrestricted float arg); }; - """) + """ + ) except Exception as x: threw = True - harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args") + harness.ok( + threw, "[LenientFloat] only allowed on methods with unrestricted float args" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface FloatTypes { [LenientFloat] undefined m(sequence<unrestricted float> arg); }; - """) + """ + ) except Exception as x: threw = True - harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)") + harness.ok( + threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface FloatTypes { [LenientFloat] undefined m((unrestricted float or FloatTypes) arg); }; - """) + """ + ) except Exception as x: threw = True - harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)") + harness.ok( + threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface FloatTypes { [LenientFloat] readonly attribute float foo; }; - """) + """ + ) except Exception as x: threw = True harness.ok(threw, "[LenientFloat] only allowed on writable attributes") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py b/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py index cac24c832cc..1c81718400a 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py @@ -1,14 +1,17 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface ForwardDeclared; interface ForwardDeclared; interface TestForwardDecl { attribute ForwardDeclared foo; }; - """) + """ + ) results = parser.finish() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py index 3958f8ce104..9ee27efbc8d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py @@ -1,106 +1,129 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo : Bar { getter any(DOMString name); }; [Exposed=Foo] interface Bar {}; - """) + """ + ) results = parser.finish() - harness.ok(results[0].isOnGlobalProtoChain(), - "[Global] interface should be on global's proto chain") - harness.ok(results[1].isOnGlobalProtoChain(), - "[Global] interface should be on global's proto chain") + harness.ok( + results[0].isOnGlobalProtoChain(), + "[Global] interface should be on global's proto chain", + ) + harness.ok( + results[1].isOnGlobalProtoChain(), + "[Global] interface should be on global's proto chain", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo { getter any(DOMString name); setter undefined(DOMString name, any arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [Global] used on an interface with a " - "named setter") + harness.ok( + threw, + "Should have thrown for [Global] used on an interface with a " "named setter", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo { getter any(DOMString name); deleter undefined(DOMString name); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [Global] used on an interface with a " - "named deleter") + harness.ok( + threw, + "Should have thrown for [Global] used on an interface with a " "named deleter", + ) parser = parser.reset() threw = False try: - parser.parse(""" - [Global, OverrideBuiltins, Exposed=Foo] + parser.parse( + """ + [Global, LegacyOverrideBuiltIns, Exposed=Foo] interface Foo { }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [Global] used on an interface with a " - "[OverrideBuiltins]") + harness.ok( + threw, + "Should have thrown for [Global] used on an interface with a " + "[LegacyOverrideBuiltIns]", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo : Bar { }; - [OverrideBuiltins, Exposed=Foo] + [LegacyOverrideBuiltIns, Exposed=Foo] interface Bar { }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [Global] used on an interface with an " - "[OverrideBuiltins] ancestor") + harness.ok( + threw, + "Should have thrown for [Global] used on an interface with an " + "[LegacyOverrideBuiltIns] ancestor", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Foo] interface Foo { }; [Exposed=Foo] interface Bar : Foo { }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown for [Global] used on an interface with a " - "descendant") + harness.ok( + threw, + "Should have thrown for [Global] used on an interface with a " "descendant", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py b/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py index 0e9a6654aa7..7404c86f944 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py @@ -1,39 +1,49 @@ # Import the WebIDL module, so we can do isinstance checks and whatnot import WebIDL + def WebIDLTest(parser, harness): try: - parser.parse(""" + parser.parse( + """ enum Foo { "a" }; interface Foo; - """) + """ + ) results = parser.finish() harness.ok(False, "Should fail to parse") except Exception as e: - harness.ok("Name collision" in e.message, - "Should have name collision for interface") + harness.ok( + "Name collision" in str(e), "Should have name collision for interface" + ) parser = parser.reset() try: - parser.parse(""" + parser.parse( + """ dictionary Foo { long x; }; enum Foo { "a" }; - """) + """ + ) results = parser.finish() harness.ok(False, "Should fail to parse") except Exception as e: - harness.ok("Name collision" in e.message, - "Should have name collision for dictionary") + harness.ok( + "Name collision" in str(e), "Should have name collision for dictionary" + ) parser = parser.reset() try: - parser.parse(""" + parser.parse( + """ enum Foo { "a" }; enum Foo { "b" }; - """) + """ + ) results = parser.finish() harness.ok(False, "Should fail to parse") except Exception as e: - harness.ok("Multiple unresolvable definitions" in e.message, - "Should have name collision for dictionary") - + harness.ok( + "Multiple unresolvable definitions" in str(e), + "Should have name collision for dictionary", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py index 8f30c212d7b..ed476b8ed4c 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestIncompleteParent : NotYetDefined { undefined foo(); }; @@ -11,7 +13,8 @@ def WebIDLTest(parser, harness): interface EvenHigherOnTheChain { }; - """) + """ + ) parser.finish() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py index fdc39604070..0d54f708bba 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestIncompleteTypes { attribute FooInterface attr1; @@ -10,35 +12,50 @@ def WebIDLTest(parser, harness): interface FooInterface { }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestIncompleteTypes interface parsed without error.") harness.check(len(results), 2, "Should be two productions.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestIncompleteTypes", "Interface has the right QName") - harness.check(iface.identifier.name, "TestIncompleteTypes", "Interface has the right name") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), + "::TestIncompleteTypes", + "Interface has the right QName", + ) + harness.check( + iface.identifier.name, "TestIncompleteTypes", "Interface has the right name" + ) harness.check(len(iface.members), 2, "Expect 2 members") attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), - "Should be an IDLAttribute") + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") method = iface.members[1] - harness.ok(isinstance(method, WebIDL.IDLMethod), - "Should be an IDLMethod") - - harness.check(attr.identifier.QName(), "::TestIncompleteTypes::attr1", - "Attribute has the right QName") - harness.check(attr.type.name, "FooInterface", - "Previously unresolved type has the right name") - - harness.check(method.identifier.QName(), "::TestIncompleteTypes::method1", - "Attribute has the right QName") + harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") + + harness.check( + attr.identifier.QName(), + "::TestIncompleteTypes::attr1", + "Attribute has the right QName", + ) + harness.check( + attr.type.name, "FooInterface", "Previously unresolved type has the right name" + ) + + harness.check( + method.identifier.QName(), + "::TestIncompleteTypes::method1", + "Attribute has the right QName", + ) (returnType, args) = method.signatures()[0] - harness.check(returnType.name, "FooInterface", - "Previously unresolved type has the right name") - harness.check(args[0].type.name, "FooInterface", - "Previously unresolved type has the right name") + harness.check( + returnType.name, "FooInterface", "Previously unresolved type has the right name" + ) + harness.check( + args[0].type.name, + "FooInterface", + "Previously unresolved type has the right name", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_interface.py index a10bcd9863d..85748848e1b 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_interface.py @@ -1,12 +1,12 @@ import WebIDL + def WebIDLTest(parser, harness): parser.parse("interface Foo { };") results = parser.finish() harness.ok(True, "Empty interface parsed without error.") harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") iface = results[0] harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName") harness.check(iface.identifier.name, "Foo", "Interface has the right name") @@ -16,16 +16,15 @@ def WebIDLTest(parser, harness): results = parser.finish() harness.ok(True, "Empty interface parsed without error.") harness.check(len(results), 2, "Should be two productions") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") iface = results[1] harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName") harness.check(iface.identifier.name, "Bar", "Interface has the right name") - harness.ok(isinstance(iface.parent, WebIDL.IDLInterface), - "Interface has a parent") + harness.ok(isinstance(iface.parent, WebIDL.IDLInterface), "Interface has a parent") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface QNameBase { attribute long foo; }; @@ -34,32 +33,42 @@ def WebIDLTest(parser, harness): attribute long long foo; attribute byte bar; }; - """) + """ + ) results = parser.finish() harness.check(len(results), 2, "Should be two productions") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") + harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") harness.check(results[1].parent, results[0], "Inheritance chain is right") harness.check(len(results[0].members), 1, "Expect 1 productions") harness.check(len(results[1].members), 2, "Expect 2 productions") base = results[0] derived = results[1] - harness.check(base.members[0].identifier.QName(), "::QNameBase::foo", - "Member has the right QName") - harness.check(derived.members[0].identifier.QName(), "::QNameDerived::foo", - "Member has the right QName") - harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar", - "Member has the right QName") + harness.check( + base.members[0].identifier.QName(), + "::QNameBase::foo", + "Member has the right QName", + ) + harness.check( + derived.members[0].identifier.QName(), + "::QNameDerived::foo", + "Member has the right QName", + ) + harness.check( + derived.members[1].identifier.QName(), + "::QNameDerived::bar", + "Member has the right QName", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A : B {}; interface B : A {}; - """) + """ + ) results = parser.finish() except: threw = True @@ -69,32 +78,42 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A : C {}; interface C : B {}; interface B : A {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains") + harness.ok( + threw, "Should not allow indirect cycles in interface inheritance chains" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A; interface B : A {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow inheriting from an interface that is only forward declared") + harness.ok( + threw, + "Should not allow inheriting from an interface that is only forward declared", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface A { constructor(); constructor(long arg); @@ -105,26 +124,43 @@ def WebIDLTest(parser, harness): readonly attribute boolean y; undefined foo(long arg); }; - """); - results = parser.finish(); - harness.check(len(results), 2, - "Should have two results with partial interface") + """ + ) + results = parser.finish() + harness.check(len(results), 2, "Should have two results with partial interface") iface = results[0] - harness.check(len(iface.members), 3, - "Should have three members with partial interface") - harness.check(iface.members[0].identifier.name, "x", - "First member should be x with partial interface") - harness.check(iface.members[1].identifier.name, "foo", - "Second member should be foo with partial interface") - harness.check(len(iface.members[1].signatures()), 2, - "Should have two foo signatures with partial interface") - harness.check(iface.members[2].identifier.name, "y", - "Third member should be y with partial interface") - harness.check(len(iface.ctor().signatures()), 2, - "Should have two constructors with partial interface") + harness.check( + len(iface.members), 3, "Should have three members with partial interface" + ) + harness.check( + iface.members[0].identifier.name, + "x", + "First member should be x with partial interface", + ) + harness.check( + iface.members[1].identifier.name, + "foo", + "Second member should be foo with partial interface", + ) + harness.check( + len(iface.members[1].signatures()), + 2, + "Should have two foo signatures with partial interface", + ) + harness.check( + iface.members[2].identifier.name, + "y", + "Third member should be y with partial interface", + ) + harness.check( + len(iface.ctor().signatures()), + 2, + "Should have two constructors with partial interface", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ partial interface A { readonly attribute boolean y; undefined foo(long arg); @@ -135,236 +171,289 @@ def WebIDLTest(parser, harness): readonly attribute boolean x; undefined foo(); }; - """); - results = parser.finish(); - harness.check(len(results), 2, - "Should have two results with reversed partial interface") + """ + ) + results = parser.finish() + harness.check( + len(results), 2, "Should have two results with reversed partial interface" + ) iface = results[1] - harness.check(len(iface.members), 3, - "Should have three members with reversed partial interface") - harness.check(iface.members[0].identifier.name, "x", - "First member should be x with reversed partial interface") - harness.check(iface.members[1].identifier.name, "foo", - "Second member should be foo with reversed partial interface") - harness.check(len(iface.members[1].signatures()), 2, - "Should have two foo signatures with reversed partial interface") - harness.check(iface.members[2].identifier.name, "y", - "Third member should be y with reversed partial interface") - harness.check(len(iface.ctor().signatures()), 2, - "Should have two constructors with reversed partial interface") + harness.check( + len(iface.members), + 3, + "Should have three members with reversed partial interface", + ) + harness.check( + iface.members[0].identifier.name, + "x", + "First member should be x with reversed partial interface", + ) + harness.check( + iface.members[1].identifier.name, + "foo", + "Second member should be foo with reversed partial interface", + ) + harness.check( + len(iface.members[1].signatures()), + 2, + "Should have two foo signatures with reversed partial interface", + ) + harness.check( + iface.members[2].identifier.name, + "y", + "Third member should be y with reversed partial interface", + ) + harness.check( + len(iface.ctor().signatures()), + 2, + "Should have two constructors with reversed partial interface", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { readonly attribute boolean x; }; interface A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow two non-partial interfaces with the same name") + harness.ok(threw, "Should not allow two non-partial interfaces with the same name") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ partial interface A { readonly attribute boolean x; }; partial interface A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Must have a non-partial interface for a given name") + harness.ok(threw, "Must have a non-partial interface for a given name") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { boolean x; }; partial interface A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between partial interface " - "and other object") + harness.ok( + threw, + "Should not allow a name collision between partial interface " + "and other object", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { boolean x; }; interface A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between interface " - "and other object") + harness.ok( + threw, "Should not allow a name collision between interface " "and other object" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { boolean x; }; interface A; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between external interface " - "and other object") + harness.ok( + threw, + "Should not allow a name collision between external interface " + "and other object", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { readonly attribute boolean x; }; interface A; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between external interface " - "and interface") + harness.ok( + threw, + "Should not allow a name collision between external interface " "and interface", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface A; interface A; - """) + """ + ) results = parser.finish() - harness.ok(len(results) == 1 and - isinstance(results[0], WebIDL.IDLExternalInterface), - "Should allow name collisions between external interface " - "declarations") + harness.ok( + len(results) == 1 and isinstance(results[0], WebIDL.IDLExternalInterface), + "Should allow name collisions between external interface " "declarations", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SomeRandomAnnotation] interface A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow unknown extended attributes on interfaces") + harness.ok(threw, "Should not allow unknown extended attributes on interfaces") parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Exposed=Window, LegacyWindowAlias=A] interface B {}; [Exposed=Window, LegacyWindowAlias=(C, D)] interface E {}; - """); - results = parser.finish(); - harness.check(results[1].legacyWindowAliases, ["A"], - "Should support a single identifier") - harness.check(results[2].legacyWindowAliases, ["C", "D"], - "Should support an identifier list") + """ + ) + results = parser.finish() + harness.check( + results[1].legacyWindowAliases, ["A"], "Should support a single identifier" + ) + harness.check( + results[2].legacyWindowAliases, ["C", "D"], "Should support an identifier list" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [LegacyWindowAlias] interface A {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LegacyWindowAlias] with no value") + harness.ok(threw, "Should not allow [LegacyWindowAlias] with no value") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Exposed=Worker, LegacyWindowAlias=B] interface A {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LegacyWindowAlias] without Window exposure") + harness.ok(threw, "Should not allow [LegacyWindowAlias] without Window exposure") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Exposed=Window] interface A {}; [Exposed=Window, LegacyWindowAlias=A] interface B {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LegacyWindowAlias] to conflict with other identifiers") + harness.ok( + threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Exposed=Window, LegacyWindowAlias=A] interface B {}; [Exposed=Window] interface A {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LegacyWindowAlias] to conflict with other identifiers") + harness.ok( + threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Exposed=Window, LegacyWindowAlias=A] interface B {}; [Exposed=Window, LegacyWindowAlias=A] interface C {}; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LegacyWindowAlias] to conflict with other identifiers") + harness.ok( + threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py index db944e7aaf7..5750f87a6fc 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py @@ -1,12 +1,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface IdentifierConflict { const byte thing1 = 1; const unsigned long thing1 = 1; }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py index 1a73fb917ed..c1a544ce718 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py @@ -1,12 +1,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface IdentifierConflictAcrossMembers1 { const byte thing1 = 1; readonly attribute long thing1; }; - """) + """ + ) results = parser.finish() except: @@ -16,12 +18,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface IdentifierConflictAcrossMembers2 { readonly attribute long thing1; const byte thing1 = 1; }; - """) + """ + ) results = parser.finish() except: @@ -31,12 +35,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface IdentifierConflictAcrossMembers3 { getter boolean thing1(DOMString name); readonly attribute long thing1; }; - """) + """ + ) results = parser.finish() except: @@ -46,12 +52,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface IdentifierConflictAcrossMembers1 { const byte thing1 = 1; long thing1(); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py index 835212d2965..18c6023dd3b 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py @@ -1,33 +1,42 @@ import WebIDL import traceback -def WebIDLTest(parser, harness): + +def WebIDLTest(parser, harness): def shouldPass(prefix, iface, expectedMembers, numProductions=1): p = parser.reset() p.parse(iface) results = p.finish() - harness.check(len(results), numProductions, - "%s - Should have production count %d" % (prefix, numProductions)) - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "%s - Should be an IDLInterface" % (prefix)) + harness.check( + len(results), + numProductions, + "%s - Should have production count %d" % (prefix, numProductions), + ) + harness.ok( + isinstance(results[0], WebIDL.IDLInterface), + "%s - Should be an IDLInterface" % (prefix), + ) # Make a copy, since we plan to modify it expectedMembers = list(expectedMembers) for m in results[0].members: name = m.identifier.name if (name, type(m)) in expectedMembers: - harness.ok(True, "%s - %s - Should be a %s" % (prefix, name, - type(m))) + harness.ok(True, "%s - %s - Should be a %s" % (prefix, name, type(m))) expectedMembers.remove((name, type(m))) else: - harness.ok(False, "%s - %s - Unknown symbol of type %s" % - (prefix, name, type(m))) + harness.ok( + False, + "%s - %s - Unknown symbol of type %s" % (prefix, name, type(m)), + ) # A bit of a hoop because we can't generate the error string if we pass if len(expectedMembers) == 0: harness.ok(True, "Found all the members") else: - harness.ok(False, - "Expected member not found: %s of type %s" % - (expectedMembers[0][0], expectedMembers[0][1])) + harness.ok( + False, + "Expected member not found: %s of type %s" + % (expectedMembers[0][0], expectedMembers[0][1]), + ) return results def shouldFail(prefix, iface): @@ -35,68 +44,81 @@ def WebIDLTest(parser, harness): p = parser.reset() p.parse(iface) p.finish() - harness.ok(False, - prefix + " - Interface passed when should've failed") + harness.ok(False, prefix + " - Interface passed when should've failed") except WebIDL.WebIDLError as e: - harness.ok(True, - prefix + " - Interface failed as expected") + harness.ok(True, prefix + " - Interface failed as expected") except Exception as e: - harness.ok(False, - prefix + " - Interface failed but not as a WebIDLError exception: %s" % e) - - iterableMembers = [(x, WebIDL.IDLMethod) for x in ["entries", "keys", - "values", "forEach"]] - setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has"]] + - [("__setlike", WebIDL.IDLMaplikeOrSetlike)] + - iterableMembers) + harness.ok( + False, + prefix + + " - Interface failed but not as a WebIDLError exception: %s" % e, + ) + + iterableMembers = [ + (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values", "forEach"] + ] + setROMembers = ( + [(x, WebIDL.IDLMethod) for x in ["has"]] + + [("__setlike", WebIDL.IDLMaplikeOrSetlike)] + + iterableMembers + ) setROMembers.extend([("size", WebIDL.IDLAttribute)]) - setRWMembers = ([(x, WebIDL.IDLMethod) for x in ["add", - "clear", - "delete"]] + - setROMembers) - setROChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__add", - "__clear", - "__delete"]] + - setROMembers) - setRWChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__add", - "__clear", - "__delete"]] + - setRWMembers) - mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has"]] + - [("__maplike", WebIDL.IDLMaplikeOrSetlike)] + - iterableMembers) + setRWMembers = [ + (x, WebIDL.IDLMethod) for x in ["add", "clear", "delete"] + ] + setROMembers + setROChromeMembers = [ + (x, WebIDL.IDLMethod) for x in ["__add", "__clear", "__delete"] + ] + setROMembers + setRWChromeMembers = [ + (x, WebIDL.IDLMethod) for x in ["__add", "__clear", "__delete"] + ] + setRWMembers + mapROMembers = ( + [(x, WebIDL.IDLMethod) for x in ["get", "has"]] + + [("__maplike", WebIDL.IDLMaplikeOrSetlike)] + + iterableMembers + ) mapROMembers.extend([("size", WebIDL.IDLAttribute)]) - mapRWMembers = ([(x, WebIDL.IDLMethod) for x in ["set", - "clear", - "delete"]] + mapROMembers) - mapRWChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__set", - "__clear", - "__delete"]] + - mapRWMembers) + mapRWMembers = [ + (x, WebIDL.IDLMethod) for x in ["set", "clear", "delete"] + ] + mapROMembers + mapRWChromeMembers = [ + (x, WebIDL.IDLMethod) for x in ["__set", "__clear", "__delete"] + ] + mapRWMembers # OK, now that we've used iterableMembers to set up the above, append # __iterable to it for the iterable<> case. iterableMembers.append(("__iterable", WebIDL.IDLIterable)) + asyncIterableMembers = [ + (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values"] + ] + asyncIterableMembers.append(("__iterable", WebIDL.IDLAsyncIterable)) + valueIterableMembers = [("__iterable", WebIDL.IDLIterable)] valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod)) valueIterableMembers.append(("length", WebIDL.IDLAttribute)) + valueAsyncIterableMembers = [("__iterable", WebIDL.IDLAsyncIterable)] + valueAsyncIterableMembers.append(("values", WebIDL.IDLMethod)) + disallowedIterableNames = ["keys", "entries", "values"] disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames mapDisallowedMemberNames = ["get"] + disallowedMemberNames disallowedNonMethodNames = ["clear", "delete"] mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames setDisallowedNonMethodNames = ["add"] + disallowedNonMethodNames - unrelatedMembers = [("unrelatedAttribute", WebIDL.IDLAttribute), - ("unrelatedMethod", WebIDL.IDLMethod)] + unrelatedMembers = [ + ("unrelatedAttribute", WebIDL.IDLAttribute), + ("unrelatedMethod", WebIDL.IDLMethod), + ] # # Simple Usage Tests # - shouldPass("Iterable (key only)", - """ + shouldPass( + "Iterable (key only)", + """ interface Foo1 { iterable<long>; readonly attribute unsigned long length; @@ -104,10 +126,13 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, valueIterableMembers + unrelatedMembers) + """, + valueIterableMembers + unrelatedMembers, + ) - shouldPass("Iterable (key only) inheriting from parent", - """ + shouldPass( + "Iterable (key only) inheriting from parent", + """ interface Foo1 : Foo2 { iterable<long>; readonly attribute unsigned long length; @@ -117,21 +142,28 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, valueIterableMembers, numProductions=2) + """, + valueIterableMembers, + numProductions=2, + ) - shouldPass("Iterable (key and value)", - """ + shouldPass( + "Iterable (key and value)", + """ interface Foo1 { iterable<long, long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, iterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2) + """, + iterableMembers + unrelatedMembers, + # numProductions == 2 because of the generated iterator iface, + numProductions=2, + ) - shouldPass("Iterable (key and value) inheriting from parent", - """ + shouldPass( + "Iterable (key and value) inheriting from parent", + """ interface Foo1 : Foo2 { iterable<long, long>; }; @@ -139,21 +171,115 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, iterableMembers, - # numProductions == 3 because of the generated iterator iface, - numProductions=3) + """, + iterableMembers, + # numProductions == 3 because of the generated iterator iface, + numProductions=3, + ) + + shouldPass( + "Async iterable (key only)", + """ + interface Foo1 { + async iterable<long>; + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + valueAsyncIterableMembers + unrelatedMembers, + # numProductions == 2 because of the generated iterator iface, + numProductions=2, + ) + + shouldPass( + "Async iterable (key only) inheriting from parent", + """ + interface Foo1 : Foo2 { + async iterable<long>; + }; + interface Foo2 { + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + valueAsyncIterableMembers, + # numProductions == 3 because of the generated iterator iface, + numProductions=3, + ) + + shouldPass( + "Async iterable with argument (key only)", + """ + interface Foo1 { + async iterable<long>(optional long foo); + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + valueAsyncIterableMembers + unrelatedMembers, + # numProductions == 2 because of the generated iterator iface, + numProductions=2, + ) + + shouldPass( + "Async iterable (key and value)", + """ + interface Foo1 { + async iterable<long, long>; + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + asyncIterableMembers + unrelatedMembers, + # numProductions == 2 because of the generated iterator iface, + numProductions=2, + ) + + shouldPass( + "Async iterable (key and value) inheriting from parent", + """ + interface Foo1 : Foo2 { + async iterable<long, long>; + }; + interface Foo2 { + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + asyncIterableMembers, + # numProductions == 3 because of the generated iterator iface, + numProductions=3, + ) + + shouldPass( + "Async iterable with argument (key and value)", + """ + interface Foo1 { + async iterable<long, long>(optional long foo); + attribute long unrelatedAttribute; + long unrelatedMethod(); + }; + """, + asyncIterableMembers + unrelatedMembers, + # numProductions == 2 because of the generated iterator iface, + numProductions=2, + ) - shouldPass("Maplike (readwrite)", - """ + shouldPass( + "Maplike (readwrite)", + """ interface Foo1 { maplike<long, long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapRWMembers + unrelatedMembers) + """, + mapRWMembers + unrelatedMembers, + ) - shouldPass("Maplike (readwrite) inheriting from parent", - """ + shouldPass( + "Maplike (readwrite) inheriting from parent", + """ interface Foo1 : Foo2 { maplike<long, long>; }; @@ -161,19 +287,26 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldPass("Maplike (readwrite)", - """ + shouldPass( + "Maplike (readwrite)", + """ interface Foo1 { maplike<long, long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapRWMembers + unrelatedMembers) + """, + mapRWMembers + unrelatedMembers, + ) - shouldPass("Maplike (readwrite) inheriting from parent", - """ + shouldPass( + "Maplike (readwrite) inheriting from parent", + """ interface Foo1 : Foo2 { maplike<long, long>; }; @@ -181,19 +314,26 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldPass("Maplike (readonly)", - """ + shouldPass( + "Maplike (readonly)", + """ interface Foo1 { readonly maplike<long, long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapROMembers + unrelatedMembers) + """, + mapROMembers + unrelatedMembers, + ) - shouldPass("Maplike (readonly) inheriting from parent", - """ + shouldPass( + "Maplike (readonly) inheriting from parent", + """ interface Foo1 : Foo2 { readonly maplike<long, long>; }; @@ -201,19 +341,26 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, mapROMembers, numProductions=2) + """, + mapROMembers, + numProductions=2, + ) - shouldPass("Setlike (readwrite)", - """ + shouldPass( + "Setlike (readwrite)", + """ interface Foo1 { setlike<long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, setRWMembers + unrelatedMembers) + """, + setRWMembers + unrelatedMembers, + ) - shouldPass("Setlike (readwrite) inheriting from parent", - """ + shouldPass( + "Setlike (readwrite) inheriting from parent", + """ interface Foo1 : Foo2 { setlike<long>; }; @@ -221,19 +368,26 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, setRWMembers, numProductions=2) + """, + setRWMembers, + numProductions=2, + ) - shouldPass("Setlike (readonly)", - """ + shouldPass( + "Setlike (readonly)", + """ interface Foo1 { readonly setlike<long>; attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, setROMembers + unrelatedMembers) + """, + setROMembers + unrelatedMembers, + ) - shouldPass("Setlike (readonly) inheriting from parent", - """ + shouldPass( + "Setlike (readonly) inheriting from parent", + """ interface Foo1 : Foo2 { readonly setlike<long>; }; @@ -241,95 +395,166 @@ def WebIDLTest(parser, harness): attribute long unrelatedAttribute; long unrelatedMethod(); }; - """, setROMembers, numProductions=2) + """, + setROMembers, + numProductions=2, + ) - shouldPass("Inheritance of maplike/setlike", - """ + shouldPass( + "Inheritance of maplike/setlike", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldPass("JS Implemented maplike interface", - """ + shouldFail( + "JS Implemented maplike interface", + """ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] interface Foo1 { constructor(); setlike<long>; }; - """, setRWChromeMembers) + """, + ) - shouldPass("JS Implemented maplike interface", - """ + shouldFail( + "JS Implemented maplike interface", + """ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] interface Foo1 { constructor(); maplike<long, long>; }; - """, mapRWChromeMembers) + """, + ) # # Multiple maplike/setlike tests # - shouldFail("Two maplike/setlikes on same interface", - """ + shouldFail( + "Two maplike/setlikes on same interface", + """ interface Foo1 { setlike<long>; maplike<long, long>; }; - """) + """, + ) - shouldFail("Two iterable/setlikes on same interface", - """ + shouldFail( + "Two iterable/setlikes on same interface", + """ interface Foo1 { iterable<long>; maplike<long, long>; }; - """) + """, + ) - shouldFail("Two iterables on same interface", - """ + shouldFail( + "Two iterables on same interface", + """ interface Foo1 { iterable<long>; iterable<long, long>; }; - """) + """, + ) + + shouldFail( + "Two iterables on same interface", + """ + interface Foo1 { + iterable<long>; + async iterable<long>; + }; + """, + ) + + shouldFail( + "Two iterables on same interface", + """ + interface Foo1 { + async iterable<long>; + async iterable<long, long>; + }; + """, + ) + + shouldFail( + "Async iterable with non-optional arguments", + """ + interface Foo1 { + async iterable<long>(long foo); + }; + """, + ) + + shouldFail( + "Async iterable with non-optional arguments", + """ + interface Foo1 { + async iterable<long>(optional long foo, long bar); + }; + """, + ) + + shouldFail( + "Async iterable with non-optional arguments", + """ + interface Foo1 { + async iterable<long, long>(long foo); + }; + """, + ) - shouldFail("Two maplike/setlikes in partials", - """ + shouldFail( + "Two maplike/setlikes in partials", + """ interface Foo1 { maplike<long, long>; }; partial interface Foo1 { setlike<long>; }; - """) + """, + ) - shouldFail("Conflicting maplike/setlikes across inheritance", - """ + shouldFail( + "Conflicting maplike/setlikes across inheritance", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { setlike<long>; }; - """) + """, + ) - shouldFail("Conflicting maplike/iterable across inheritance", - """ + shouldFail( + "Conflicting maplike/iterable across inheritance", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { iterable<long>; }; - """) + """, + ) - shouldFail("Conflicting maplike/setlikes across multistep inheritance", - """ + shouldFail( + "Conflicting maplike/setlikes across multistep inheritance", + """ interface Foo1 { maplike<long, long>; }; @@ -338,7 +563,8 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { setlike<long>; }; - """) + """, + ) # # Member name collision tests @@ -353,61 +579,83 @@ def WebIDLTest(parser, harness): """ if methodPasses: - shouldPass("Conflicting method: %s and %s" % (likeMember, conflictName), - """ + shouldPass( + "Conflicting method: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s; [Throws] undefined %s(long test1, double test2, double test3); }; - """ % (likeMember, conflictName), expectedMembers) - else: - shouldFail("Conflicting method: %s and %s" % (likeMember, conflictName), """ + % (likeMember, conflictName), + expectedMembers, + ) + else: + shouldFail( + "Conflicting method: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s; [Throws] undefined %s(long test1, double test2, double test3); }; - """ % (likeMember, conflictName)) + """ + % (likeMember, conflictName), + ) # Inherited conflicting methods should ALWAYS fail - shouldFail("Conflicting inherited method: %s and %s" % (likeMember, conflictName), - """ + shouldFail( + "Conflicting inherited method: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { undefined %s(long test1, double test2, double test3); }; interface Foo2 : Foo1 { %s; }; - """ % (conflictName, likeMember)) - shouldFail("Conflicting static method: %s and %s" % (likeMember, conflictName), """ + % (conflictName, likeMember), + ) + shouldFail( + "Conflicting static method: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s; static undefined %s(long test1, double test2, double test3); }; - """ % (likeMember, conflictName)) - shouldFail("Conflicting attribute: %s and %s" % (likeMember, conflictName), """ + % (likeMember, conflictName), + ) + shouldFail( + "Conflicting attribute: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s attribute double %s; }; - """ % (likeMember, conflictName)) - shouldFail("Conflicting const: %s and %s" % (likeMember, conflictName), """ + % (likeMember, conflictName), + ) + shouldFail( + "Conflicting const: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s; const double %s = 0; }; - """ % (likeMember, conflictName)) - shouldFail("Conflicting static attribute: %s and %s" % (likeMember, conflictName), """ + % (likeMember, conflictName), + ) + shouldFail( + "Conflicting static attribute: %s and %s" % (likeMember, conflictName), + """ interface Foo1 { %s; static attribute long %s; }; - """ % (likeMember, conflictName)) + """ + % (likeMember, conflictName), + ) for member in disallowedIterableNames: testConflictingMembers("iterable<long, long>", member, iterableMembers, False) @@ -420,18 +668,23 @@ def WebIDLTest(parser, harness): for member in setDisallowedNonMethodNames: testConflictingMembers("setlike<long>", member, setRWMembers, True) - shouldPass("Inheritance of maplike/setlike with child member collision", - """ + shouldPass( + "Inheritance of maplike/setlike with child member collision", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { undefined entries(); }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldPass("Inheritance of multi-level maplike/setlike with child member collision", - """ + shouldPass( + "Inheritance of multi-level maplike/setlike with child member collision", + """ interface Foo1 { maplike<long, long>; }; @@ -440,10 +693,14 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { undefined entries(); }; - """, mapRWMembers, numProductions=3) + """, + mapRWMembers, + numProductions=3, + ) - shouldFail("Maplike interface with mixin member collision", - """ + shouldFail( + "Maplike interface with mixin member collision", + """ interface Foo1 { maplike<long, long>; }; @@ -451,10 +708,12 @@ def WebIDLTest(parser, harness): undefined entries(); }; Foo1 includes Foo2; - """) + """, + ) - shouldPass("Inherited Maplike interface with consequential interface member collision", - """ + shouldPass( + "Inherited Maplike interface with consequential interface member collision", + """ interface Foo1 { maplike<long, long>; }; @@ -464,20 +723,26 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo1 { }; Foo3 includes Foo2; - """, mapRWMembers, numProductions=4) + """, + mapRWMembers, + numProductions=4, + ) - shouldFail("Inheritance of name collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of name collision with child maplike/setlike", + """ interface Foo1 { undefined entries(); }; interface Foo2 : Foo1 { maplike<long, long>; }; - """) + """, + ) - shouldFail("Inheritance of multi-level name collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of multi-level name collision with child maplike/setlike", + """ interface Foo1 { undefined entries(); }; @@ -486,20 +751,26 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { maplike<long, long>; }; - """) + """, + ) - shouldPass("Inheritance of attribute collision with parent maplike/setlike", - """ + shouldPass( + "Inheritance of attribute collision with parent maplike/setlike", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { attribute double size; }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldPass("Inheritance of multi-level attribute collision with parent maplike/setlike", - """ + shouldPass( + "Inheritance of multi-level attribute collision with parent maplike/setlike", + """ interface Foo1 { maplike<long, long>; }; @@ -508,20 +779,26 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { attribute double size; }; - """, mapRWMembers, numProductions=3) + """, + mapRWMembers, + numProductions=3, + ) - shouldFail("Inheritance of attribute collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of attribute collision with child maplike/setlike", + """ interface Foo1 { attribute double size; }; interface Foo2 : Foo1 { maplike<long, long>; }; - """) + """, + ) - shouldFail("Inheritance of multi-level attribute collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of multi-level attribute collision with child maplike/setlike", + """ interface Foo1 { attribute double size; }; @@ -530,53 +807,65 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { maplike<long, long>; }; - """) + """, + ) - shouldFail("Inheritance of attribute/rw function collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of attribute/rw function collision with child maplike/setlike", + """ interface Foo1 { attribute double set; }; interface Foo2 : Foo1 { maplike<long, long>; }; - """) + """, + ) - shouldFail("Inheritance of const/rw function collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of const/rw function collision with child maplike/setlike", + """ interface Foo1 { const double set = 0; }; interface Foo2 : Foo1 { maplike<long, long>; }; - """) + """, + ) - shouldPass("Inheritance of rw function with same name in child maplike/setlike", - """ + shouldPass( + "Inheritance of rw function with same name in child maplike/setlike", + """ interface Foo1 { maplike<long, long>; }; interface Foo2 : Foo1 { undefined clear(); }; - """, mapRWMembers, numProductions=2) + """, + mapRWMembers, + numProductions=2, + ) - shouldFail("Inheritance of unforgeable attribute collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of unforgeable attribute collision with child maplike/setlike", + """ interface Foo1 { - [Unforgeable] + [LegacyUnforgeable] attribute double size; }; interface Foo2 : Foo1 { maplike<long, long>; }; - """) + """, + ) - shouldFail("Inheritance of multi-level unforgeable attribute collision with child maplike/setlike", - """ + shouldFail( + "Inheritance of multi-level unforgeable attribute collision with child maplike/setlike", + """ interface Foo1 { - [Unforgeable] + [LegacyUnforgeable] attribute double size; }; interface Foo2 : Foo1 { @@ -584,49 +873,40 @@ def WebIDLTest(parser, harness): interface Foo3 : Foo2 { maplike<long, long>; }; - """) - - shouldPass("Interface with readonly allowable overrides", - """ - interface Foo1 { - readonly setlike<long>; - readonly attribute boolean clear; - }; - """, setROMembers + [("clear", WebIDL.IDLAttribute)]) + """, + ) - shouldPass("JS Implemented read-only interface with readonly allowable overrides", - """ - [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] + shouldPass( + "Interface with readonly allowable overrides", + """ interface Foo1 { - constructor(); readonly setlike<long>; readonly attribute boolean clear; }; - """, setROChromeMembers + [("clear", WebIDL.IDLAttribute)]) - - shouldFail("JS Implemented read-write interface with non-readwrite allowable overrides", - """ - [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] - interface Foo1 { - constructor(); - setlike<long>; - readonly attribute boolean clear; - }; - """) + """, + setROMembers + [("clear", WebIDL.IDLAttribute)], + ) - r = shouldPass("Check proper override of clear/delete/set", - """ + r = shouldPass( + "Check proper override of clear/delete/set", + """ interface Foo1 { maplike<long, long>; long clear(long a, long b, double c, double d); long set(long a, long b, double c, double d); long delete(long a, long b, double c, double d); }; - """, mapRWMembers) + """, + mapRWMembers, + ) for m in r[0].members: if m.identifier.name in ["clear", "set", "delete"]: harness.ok(m.isMethod(), "%s should be a method" % m.identifier.name) - harness.check(m.maxArgCount, 4, "%s should have 4 arguments" % m.identifier.name) - harness.ok(not m.isMaplikeOrSetlikeOrIterableMethod(), - "%s should not be a maplike/setlike function" % m.identifier.name) + harness.check( + m.maxArgCount, 4, "%s should have 4 arguments" % m.identifier.name + ) + harness.ok( + not m.isMaplikeOrSetlikeOrIterableMethod(), + "%s should not be a maplike/setlike function" % m.identifier.name, + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py b/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py index 79cf1f6780d..b3c8573fa59 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py @@ -1,33 +1,46 @@ import WebIDL + def WebIDLTest(parser, harness): parser.parse("interface mixin Foo { };") results = parser.finish() harness.ok(True, "Empty interface mixin parsed without error.") harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterfaceMixin), - "Should be an IDLInterfaceMixin") + harness.ok( + isinstance(results[0], WebIDL.IDLInterfaceMixin), + "Should be an IDLInterfaceMixin", + ) mixin = results[0] - harness.check(mixin.identifier.QName(), "::Foo", "Interface mixin has the right QName") + harness.check( + mixin.identifier.QName(), "::Foo", "Interface mixin has the right QName" + ) harness.check(mixin.identifier.name, "Foo", "Interface mixin has the right name") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface mixin QNameBase { const long foo = 3; }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should be one productions") - harness.ok(isinstance(results[0], WebIDL.IDLInterfaceMixin), - "Should be an IDLInterfaceMixin") + harness.ok( + isinstance(results[0], WebIDL.IDLInterfaceMixin), + "Should be an IDLInterfaceMixin", + ) harness.check(len(results[0].members), 1, "Expect 1 productions") mixin = results[0] - harness.check(mixin.members[0].identifier.QName(), "::QNameBase::foo", - "Member has the right QName") + harness.check( + mixin.members[0].identifier.QName(), + "::QNameBase::foo", + "Member has the right QName", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface mixin A { readonly attribute boolean x; undefined foo(); @@ -36,24 +49,40 @@ def WebIDLTest(parser, harness): readonly attribute boolean y; undefined foo(long arg); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should have two results with partial interface mixin") + harness.check( + len(results), 2, "Should have two results with partial interface mixin" + ) mixin = results[0] - harness.check(len(mixin.members), 3, - "Should have three members with partial interface mixin") - harness.check(mixin.members[0].identifier.name, "x", - "First member should be x with partial interface mixin") - harness.check(mixin.members[1].identifier.name, "foo", - "Second member should be foo with partial interface mixin") - harness.check(len(mixin.members[1].signatures()), 2, - "Should have two foo signatures with partial interface mixin") - harness.check(mixin.members[2].identifier.name, "y", - "Third member should be y with partial interface mixin") + harness.check( + len(mixin.members), 3, "Should have three members with partial interface mixin" + ) + harness.check( + mixin.members[0].identifier.name, + "x", + "First member should be x with partial interface mixin", + ) + harness.check( + mixin.members[1].identifier.name, + "foo", + "Second member should be foo with partial interface mixin", + ) + harness.check( + len(mixin.members[1].signatures()), + 2, + "Should have two foo signatures with partial interface mixin", + ) + harness.check( + mixin.members[2].identifier.name, + "y", + "Third member should be y with partial interface mixin", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ partial interface mixin A { readonly attribute boolean y; undefined foo(long arg); @@ -62,285 +91,334 @@ def WebIDLTest(parser, harness): readonly attribute boolean x; undefined foo(); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should have two results with reversed partial interface mixin") + harness.check( + len(results), 2, "Should have two results with reversed partial interface mixin" + ) mixin = results[1] - harness.check(len(mixin.members), 3, - "Should have three members with reversed partial interface mixin") - harness.check(mixin.members[0].identifier.name, "x", - "First member should be x with reversed partial interface mixin") - harness.check(mixin.members[1].identifier.name, "foo", - "Second member should be foo with reversed partial interface mixin") - harness.check(len(mixin.members[1].signatures()), 2, - "Should have two foo signatures with reversed partial interface mixin") - harness.check(mixin.members[2].identifier.name, "y", - "Third member should be y with reversed partial interface mixin") + harness.check( + len(mixin.members), + 3, + "Should have three members with reversed partial interface mixin", + ) + harness.check( + mixin.members[0].identifier.name, + "x", + "First member should be x with reversed partial interface mixin", + ) + harness.check( + mixin.members[1].identifier.name, + "foo", + "Second member should be foo with reversed partial interface mixin", + ) + harness.check( + len(mixin.members[1].signatures()), + 2, + "Should have two foo signatures with reversed partial interface mixin", + ) + harness.check( + mixin.members[2].identifier.name, + "y", + "Third member should be y with reversed partial interface mixin", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface Interface {}; interface mixin Mixin { attribute short x; }; Interface includes Mixin; - """) + """ + ) results = parser.finish() iface = results[0] harness.check(len(iface.members), 1, "Should merge members from mixins") - harness.check(iface.members[0].identifier.name, "x", - "Should merge members from mixins") + harness.check( + iface.members[0].identifier.name, "x", "Should merge members from mixins" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { readonly attribute boolean x; }; interface mixin A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow two non-partial interface mixins with the same name") + harness.ok( + threw, "Should not allow two non-partial interface mixins with the same name" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ partial interface mixin A { readonly attribute boolean x; }; partial interface mixin A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Must have a non-partial interface mixin for a given name") + harness.ok(threw, "Must have a non-partial interface mixin for a given name") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { boolean x; }; partial interface mixin A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between partial interface " - "mixin and other object") + harness.ok( + threw, + "Should not allow a name collision between partial interface " + "mixin and other object", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary A { boolean x; }; interface mixin A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between interface mixin " - "and other object") + harness.ok( + threw, + "Should not allow a name collision between interface mixin " "and other object", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { readonly attribute boolean x; }; interface A; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow a name collision between external interface " - "and interface mixin") + harness.ok( + threw, + "Should not allow a name collision between external interface " + "and interface mixin", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SomeRandomAnnotation] interface mixin A { readonly attribute boolean y; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow unknown extended attributes on interface mixins") + harness.ok( + threw, "Should not allow unknown extended attributes on interface mixins" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { getter double (DOMString propertyName); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow getters on interface mixins") + harness.ok(threw, "Should not allow getters on interface mixins") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { setter undefined (DOMString propertyName, double propertyValue); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow setters on interface mixins") + harness.ok(threw, "Should not allow setters on interface mixins") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { deleter undefined (DOMString propertyName); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow deleters on interface mixins") + harness.ok(threw, "Should not allow deleters on interface mixins") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { legacycaller double compute(double x); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow legacycallers on interface mixins") + harness.ok(threw, "Should not allow legacycallers on interface mixins") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin A { inherit attribute x; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow inherited attribute on interface mixins") + harness.ok(threw, "Should not allow inherited attribute on interface mixins") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Interface {}; interface NotMixin { attribute short x; }; Interface includes NotMixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if the right side does not point an interface mixin") + harness.ok(threw, "Should fail if the right side does not point an interface mixin") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin NotInterface {}; interface mixin Mixin { attribute short x; }; NotInterface includes Mixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if the left side does not point an interface") + harness.ok(threw, "Should fail if the left side does not point an interface") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin Mixin { iterable<DOMString>; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if an interface mixin includes iterable") + harness.ok(threw, "Should fail if an interface mixin includes iterable") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin Mixin { setlike<DOMString>; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if an interface mixin includes setlike") + harness.ok(threw, "Should fail if an interface mixin includes setlike") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface mixin Mixin { maplike<DOMString, DOMString>; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if an interface mixin includes maplike") + harness.ok(threw, "Should fail if an interface mixin includes maplike") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Interface { attribute short attr; }; @@ -348,17 +426,20 @@ def WebIDLTest(parser, harness): attribute short attr; }; Interface includes Mixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if the included mixin interface has duplicated member") + harness.ok( + threw, "Should fail if the included mixin interface has duplicated member" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Interface {}; interface mixin Mixin1 { attribute short attr; @@ -368,15 +449,18 @@ def WebIDLTest(parser, harness): }; Interface includes Mixin1; Interface includes Mixin2; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should fail if the included mixin interfaces have duplicated member") + harness.ok( + threw, "Should fail if the included mixin interfaces have duplicated member" + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Global, Exposed=Worker] interface Worker {}; [Exposed=Window] @@ -385,15 +469,20 @@ def WebIDLTest(parser, harness): Base returnSelf(); }; Base includes Mixin; - """) + """ + ) results = parser.finish() base = results[2] attr = base.members[0] - harness.check(attr.exposureSet, set(["Window"]), - "Should expose on globals where the base interfaces are exposed") + harness.check( + attr.exposureSet, + set(["Window"]), + "Should expose on globals where the base interfaces are exposed", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Global, Exposed=Worker] interface Worker {}; [Exposed=Window] @@ -403,15 +492,18 @@ def WebIDLTest(parser, harness): attribute short a; }; Base includes Mixin; - """) + """ + ) results = parser.finish() base = results[2] attr = base.members[0] - harness.check(attr.exposureSet, set(["Window"]), - "Should follow [Exposed] on interface mixin") + harness.check( + attr.exposureSet, set(["Window"]), "Should follow [Exposed] on interface mixin" + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ [Global, Exposed=Window] interface Window {}; [Global, Exposed=Worker] interface Worker {}; [Exposed=Window] @@ -423,15 +515,20 @@ def WebIDLTest(parser, harness): }; Base1 includes Mixin; Base2 includes Mixin; - """) + """ + ) results = parser.finish() base = results[2] attr = base.members[0] - harness.check(attr.exposureSet, set(["Window", "Worker"]), - "Should expose on all globals where including interfaces are " - "exposed") + harness.check( + attr.exposureSet, + set(["Window", "Worker"]), + "Should expose on all globals where including interfaces are " "exposed", + ) base = results[3] attr = base.members[0] - harness.check(attr.exposureSet, set(["Window", "Worker"]), - "Should expose on all globals where including interfaces are " - "exposed") + harness.check( + attr.exposureSet, + set(["Window", "Worker"]), + "Should expose on all globals where including interfaces are " "exposed", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py b/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py index 78a9ffe9eaa..9d2230c3bec 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py @@ -2,8 +2,9 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. + def should_throw(parser, harness, message, code): - parser = parser.reset(); + parser = parser.reset() threw = False try: parser.parse(code) @@ -15,44 +16,69 @@ def should_throw(parser, harness, message, code): def WebIDLTest(parser, harness): - # The [LenientSetter] extended attribute MUST take no arguments. - should_throw(parser, harness, "no arguments", """ + # The [LegacyLenientSetter] extended attribute MUST take no arguments. + should_throw( + parser, + harness, + "no arguments", + """ interface I { - [LenientSetter=X] readonly attribute long A; + [LegacyLenientSetter=X] readonly attribute long A; }; - """) + """, + ) - # An attribute with the [LenientSetter] extended attribute MUST NOT + # An attribute with the [LegacyLenientSetter] extended attribute MUST NOT # also be declared with the [PutForwards] extended attribute. - should_throw(parser, harness, "PutForwards", """ + should_throw( + parser, + harness, + "PutForwards", + """ interface I { - [PutForwards=B, LenientSetter] readonly attribute J A; + [PutForwards=B, LegacyLenientSetter] readonly attribute J A; }; interface J { attribute long B; }; - """) + """, + ) - # An attribute with the [LenientSetter] extended attribute MUST NOT + # An attribute with the [LegacyLenientSetter] extended attribute MUST NOT # also be declared with the [Replaceable] extended attribute. - should_throw(parser, harness, "Replaceable", """ + should_throw( + parser, + harness, + "Replaceable", + """ interface I { - [Replaceable, LenientSetter] readonly attribute J A; + [Replaceable, LegacyLenientSetter] readonly attribute J A; }; - """) + """, + ) - # The [LenientSetter] extended attribute MUST NOT be used on an + # The [LegacyLenientSetter] extended attribute MUST NOT be used on an # attribute that is not read only. - should_throw(parser, harness, "writable attribute", """ + should_throw( + parser, + harness, + "writable attribute", + """ interface I { - [LenientSetter] attribute long A; + [LegacyLenientSetter] attribute long A; }; - """) + """, + ) - # The [LenientSetter] extended attribute MUST NOT be used on a + # The [LegacyLenientSetter] extended attribute MUST NOT be used on a # static attribute. - should_throw(parser, harness, "static attribute", """ + should_throw( + parser, + harness, + "static attribute", + """ interface I { - [LenientSetter] static readonly attribute long A; + [LegacyLenientSetter] static readonly attribute long A; }; - """) + """, + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_method.py b/components/script/dom/bindings/codegen/parser/tests/test_method.py index ff1f087c861..0ddfada28ac 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_method.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_method.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestMethods { undefined basic(); static undefined basicStatic(); @@ -16,35 +18,50 @@ def WebIDLTest(parser, harness): undefined setAny(any arg1); float doFloats(float arg1); }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestMethods interface parsed without error.") harness.check(len(results), 1, "Should be one production.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestMethods", "Interface has the right QName" + ) harness.check(iface.identifier.name, "TestMethods", "Interface has the right name") harness.check(len(iface.members), 12, "Expect 12 members") methods = iface.members def checkArgument(argument, QName, name, type, optional, variadic): - harness.ok(isinstance(argument, WebIDL.IDLArgument), - "Should be an IDLArgument") - harness.check(argument.identifier.QName(), QName, "Argument has the right QName") + harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") + harness.check( + argument.identifier.QName(), QName, "Argument has the right QName" + ) harness.check(argument.identifier.name, name, "Argument has the right name") harness.check(str(argument.type), type, "Argument has the right return type") - harness.check(argument.optional, optional, "Argument has the right optional value") - harness.check(argument.variadic, variadic, "Argument has the right variadic value") + harness.check( + argument.optional, optional, "Argument has the right optional value" + ) + harness.check( + argument.variadic, variadic, "Argument has the right variadic value" + ) - def checkMethod(method, QName, name, signatures, - static=False, getter=False, setter=False, - deleter=False, legacycaller=False, stringifier=False): - harness.ok(isinstance(method, WebIDL.IDLMethod), - "Should be an IDLMethod") + def checkMethod( + method, + QName, + name, + signatures, + static=False, + getter=False, + setter=False, + deleter=False, + legacycaller=False, + stringifier=False, + ): + harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") harness.ok(method.isMethod(), "Method is a method") harness.ok(not method.isAttr(), "Method is not an attr") harness.ok(not method.isConst(), "Method is not a const") @@ -53,72 +70,202 @@ def WebIDLTest(parser, harness): harness.check(method.isStatic(), static, "Method has the correct static value") harness.check(method.isGetter(), getter, "Method has the correct getter value") harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check(method.isDeleter(), deleter, "Method has the correct deleter value") - harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value") - harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") - harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") + harness.check( + method.isDeleter(), deleter, "Method has the correct deleter value" + ) + harness.check( + method.isLegacycaller(), + legacycaller, + "Method has the correct legacycaller value", + ) + harness.check( + method.isStringifier(), + stringifier, + "Method has the correct stringifier value", + ) + harness.check( + len(method.signatures()), + len(signatures), + "Method has the correct number of signatures", + ) sigpairs = zip(method.signatures(), signatures) for (gotSignature, expectedSignature) in sigpairs: (gotRetType, gotArgs) = gotSignature (expectedRetType, expectedArgs) = expectedSignature - harness.check(str(gotRetType), expectedRetType, - "Method has the expected return type.") + harness.check( + str(gotRetType), expectedRetType, "Method has the expected return type." + ) for i in range(0, len(gotArgs)): (QName, name, type, optional, variadic) = expectedArgs[i] checkArgument(gotArgs[i], QName, name, type, optional, variadic) checkMethod(methods[0], "::TestMethods::basic", "basic", [("Undefined", [])]) - checkMethod(methods[1], "::TestMethods::basicStatic", "basicStatic", - [("Undefined", [])], static=True) - checkMethod(methods[2], "::TestMethods::basicWithSimpleArgs", - "basicWithSimpleArgs", - [("Undefined", - [("::TestMethods::basicWithSimpleArgs::arg1", "arg1", "Boolean", False, False), - ("::TestMethods::basicWithSimpleArgs::arg2", "arg2", "Byte", False, False), - ("::TestMethods::basicWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])]) - checkMethod(methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])]) - checkMethod(methods[4], "::TestMethods::basicStaticBoolean", "basicStaticBoolean", [("Boolean", [])], static=True) - checkMethod(methods[5], "::TestMethods::basicBooleanWithSimpleArgs", - "basicBooleanWithSimpleArgs", - [("Boolean", - [("::TestMethods::basicBooleanWithSimpleArgs::arg1", "arg1", "Boolean", False, False), - ("::TestMethods::basicBooleanWithSimpleArgs::arg2", "arg2", "Byte", False, False), - ("::TestMethods::basicBooleanWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])]) - checkMethod(methods[6], "::TestMethods::optionalArg", - "optionalArg", - [("Undefined", - [("::TestMethods::optionalArg::arg1", "arg1", "ByteOrNull", True, False), - ("::TestMethods::optionalArg::arg2", "arg2", "ByteSequence", True, False)])]) - checkMethod(methods[7], "::TestMethods::variadicArg", - "variadicArg", - [("Undefined", - [("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])]) - checkMethod(methods[8], "::TestMethods::getObject", - "getObject", [("Object", [])]) - checkMethod(methods[9], "::TestMethods::setObject", - "setObject", - [("Undefined", - [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])]) - checkMethod(methods[10], "::TestMethods::setAny", - "setAny", - [("Undefined", - [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])]) - checkMethod(methods[11], "::TestMethods::doFloats", - "doFloats", - [("Float", - [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])]) + checkMethod( + methods[1], + "::TestMethods::basicStatic", + "basicStatic", + [("Undefined", [])], + static=True, + ) + checkMethod( + methods[2], + "::TestMethods::basicWithSimpleArgs", + "basicWithSimpleArgs", + [ + ( + "Undefined", + [ + ( + "::TestMethods::basicWithSimpleArgs::arg1", + "arg1", + "Boolean", + False, + False, + ), + ( + "::TestMethods::basicWithSimpleArgs::arg2", + "arg2", + "Byte", + False, + False, + ), + ( + "::TestMethods::basicWithSimpleArgs::arg3", + "arg3", + "UnsignedLong", + False, + False, + ), + ], + ) + ], + ) + checkMethod( + methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])] + ) + checkMethod( + methods[4], + "::TestMethods::basicStaticBoolean", + "basicStaticBoolean", + [("Boolean", [])], + static=True, + ) + checkMethod( + methods[5], + "::TestMethods::basicBooleanWithSimpleArgs", + "basicBooleanWithSimpleArgs", + [ + ( + "Boolean", + [ + ( + "::TestMethods::basicBooleanWithSimpleArgs::arg1", + "arg1", + "Boolean", + False, + False, + ), + ( + "::TestMethods::basicBooleanWithSimpleArgs::arg2", + "arg2", + "Byte", + False, + False, + ), + ( + "::TestMethods::basicBooleanWithSimpleArgs::arg3", + "arg3", + "UnsignedLong", + False, + False, + ), + ], + ) + ], + ) + checkMethod( + methods[6], + "::TestMethods::optionalArg", + "optionalArg", + [ + ( + "Undefined", + [ + ( + "::TestMethods::optionalArg::arg1", + "arg1", + "ByteOrNull", + True, + False, + ), + ( + "::TestMethods::optionalArg::arg2", + "arg2", + "ByteSequence", + True, + False, + ), + ], + ) + ], + ) + checkMethod( + methods[7], + "::TestMethods::variadicArg", + "variadicArg", + [ + ( + "Undefined", + [ + ( + "::TestMethods::variadicArg::arg1", + "arg1", + "ByteOrNull", + True, + True, + ) + ], + ) + ], + ) + checkMethod(methods[8], "::TestMethods::getObject", "getObject", [("Object", [])]) + checkMethod( + methods[9], + "::TestMethods::setObject", + "setObject", + [ + ( + "Undefined", + [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)], + ) + ], + ) + checkMethod( + methods[10], + "::TestMethods::setAny", + "setAny", + [("Undefined", [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])], + ) + checkMethod( + methods[11], + "::TestMethods::doFloats", + "doFloats", + [("Float", [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])], + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { undefined foo(optional float bar = 1); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -127,11 +274,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [GetterThrows] undefined foo(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -140,11 +289,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [SetterThrows] undefined foo(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -153,11 +304,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throw] undefined foo(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -166,11 +319,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { undefined __noSuchMethod__(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True @@ -179,77 +334,96 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throws, LenientFloat] undefined foo(float myFloat); [Throws] undefined foo(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True harness.ok(not threw, "Should allow LenientFloat to be only in a specific overload") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface A { [Throws] undefined foo(); [Throws, LenientFloat] undefined foo(float myFloat); }; - """) + """ + ) results = parser.finish() iface = results[0] methods = iface.members lenientFloat = methods[0].getExtendedAttribute("LenientFloat") - harness.ok(lenientFloat is not None, "LenientFloat in overloads must be added to the method") + harness.ok( + lenientFloat is not None, + "LenientFloat in overloads must be added to the method", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throws, LenientFloat] undefined foo(float myFloat); [Throws] undefined foo(float myFloat, float yourFloat); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, "Should prevent overloads from getting different restricted float behavior") + harness.ok( + threw, + "Should prevent overloads from getting different restricted float behavior", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throws] undefined foo(float myFloat, float yourFloat); [Throws, LenientFloat] undefined foo(float myFloat); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, "Should prevent overloads from getting different restricted float behavior (2)") + harness.ok( + threw, + "Should prevent overloads from getting different restricted float behavior (2)", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Throws, LenientFloat] undefined foo(float myFloat); [Throws, LenientFloat] undefined foo(short myShort); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_namespace.py b/components/script/dom/bindings/codegen/parser/tests/test_namespace.py index 62edb270c63..247c5b22232 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_namespace.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_namespace.py @@ -5,13 +5,13 @@ def WebIDLTest(parser, harness): attribute any foo; any bar(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 1, "Should have a thing.") - harness.ok(results[0].isNamespace(), "Our thing should be a namespace"); - harness.check(len(results[0].members), 2, - "Should have two things in our namespace") + harness.ok(results[0].isNamespace(), "Our thing should be a namespace") + harness.check(len(results[0].members), 2, "Should have two things in our namespace") harness.ok(results[0].members[0].isAttr(), "First member is attribute") harness.ok(results[0].members[0].isStatic(), "Attribute should be static") harness.ok(results[0].members[1].isMethod(), "Second member is method") @@ -26,17 +26,17 @@ def WebIDLTest(parser, harness): partial namespace MyNamespace { any bar(); }; - """) + """ + ) results = parser.finish() harness.check(len(results), 2, "Should have things.") - harness.ok(results[0].isNamespace(), "Our thing should be a namespace"); - harness.check(len(results[0].members), 2, - "Should have two things in our namespace") + harness.ok(results[0].isNamespace(), "Our thing should be a namespace") + harness.check(len(results[0].members), 2, "Should have two things in our namespace") harness.ok(results[0].members[0].isAttr(), "First member is attribute") - harness.ok(results[0].members[0].isStatic(), "Attribute should be static"); + harness.ok(results[0].members[0].isStatic(), "Attribute should be static") harness.ok(results[0].members[1].isMethod(), "Second member is method") - harness.ok(results[0].members[1].isStatic(), "Operation should be static"); + harness.ok(results[0].members[1].isStatic(), "Operation should be static") parser = parser.reset() parser.parse( @@ -47,17 +47,17 @@ def WebIDLTest(parser, harness): namespace MyNamespace { attribute any foo; }; - """) + """ + ) results = parser.finish() harness.check(len(results), 2, "Should have things.") - harness.ok(results[1].isNamespace(), "Our thing should be a namespace"); - harness.check(len(results[1].members), 2, - "Should have two things in our namespace") + harness.ok(results[1].isNamespace(), "Our thing should be a namespace") + harness.check(len(results[1].members), 2, "Should have two things in our namespace") harness.ok(results[1].members[0].isAttr(), "First member is attribute") - harness.ok(results[1].members[0].isStatic(), "Attribute should be static"); + harness.ok(results[1].members[0].isStatic(), "Attribute should be static") harness.ok(results[1].members[1].isMethod(), "Second member is method") - harness.ok(results[1].members[1].isStatic(), "Operation should be static"); + harness.ok(results[1].members[1].isStatic(), "Operation should be static") parser = parser.reset() threw = False @@ -67,7 +67,8 @@ def WebIDLTest(parser, harness): namespace MyNamespace { static attribute any foo; }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -82,7 +83,8 @@ def WebIDLTest(parser, harness): namespace MyNamespace { static any bar(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -101,7 +103,8 @@ def WebIDLTest(parser, harness): interface MyNamespace { any baz(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -120,7 +123,8 @@ def WebIDLTest(parser, harness): namespace MyNamespace { any bar(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -139,7 +143,8 @@ def WebIDLTest(parser, harness): namespace MyNamespace { any bar(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -158,7 +163,8 @@ def WebIDLTest(parser, harness): interface MyNamespace { any bar(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -177,7 +183,8 @@ def WebIDLTest(parser, harness): partial interface MyNamespace { any baz(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -196,7 +203,8 @@ def WebIDLTest(parser, harness): namespace MyNamespace { any bar(); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -215,7 +223,8 @@ def WebIDLTest(parser, harness): partial namespace MyNamespace { any baz(); }; - """) + """ + ) results = parser.finish() except Exception as x: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_newobject.py b/components/script/dom/bindings/codegen/parser/tests/test_newobject.py index 26785c6a270..c12995a0e86 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_newobject.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_newobject.py @@ -1,6 +1,7 @@ # Import the WebIDL module, so we can do isinstance checks and whatnot import WebIDL + def WebIDLTest(parser, harness): # Basic functionality parser.parse( @@ -9,7 +10,8 @@ def WebIDLTest(parser, harness): [NewObject] readonly attribute Iface attr; [NewObject] Iface method(); }; - """) + """ + ) results = parser.finish() harness.ok(results, "Should not have thrown on basic [NewObject] usage") @@ -21,7 +23,8 @@ def WebIDLTest(parser, harness): interface Iface { [Pure, NewObject] readonly attribute Iface attr; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -35,7 +38,8 @@ def WebIDLTest(parser, harness): interface Iface { [Pure, NewObject] Iface method(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -49,7 +53,8 @@ def WebIDLTest(parser, harness): interface Iface { [Cached, NewObject, Affects=Nothing] readonly attribute Iface attr; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -63,7 +68,8 @@ def WebIDLTest(parser, harness): interface Iface { [StoreInSlot, NewObject, Affects=Nothing] readonly attribute Iface attr; }; - """) + """ + ) results = parser.finish() except: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py index 8ba6771677a..012c5fcff7c 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestNullableEquivalency1 { attribute long a; attribute long? b; @@ -53,22 +55,24 @@ def WebIDLTest(parser, harness): attribute object a; attribute object? b; }; - """) + """ + ) for decl in parser.finish(): if decl.isInterface(): checkEquivalent(decl, harness) + def checkEquivalent(iface, harness): type1 = iface.members[0].type type2 = iface.members[1].type - harness.check(type1.nullable(), False, 'attr1 should not be nullable') - harness.check(type2.nullable(), True, 'attr2 should be nullable') + harness.check(type1.nullable(), False, "attr1 should not be nullable") + harness.check(type2.nullable(), True, "attr2 should be nullable") # We don't know about type1, but type2, the nullable type, definitely # shouldn't be builtin. - harness.check(type2.builtin, False, 'attr2 should not be builtin') + harness.check(type2.builtin, False, "attr2 should not be builtin") # Ensure that all attributes of type2 match those in type1, except for: # - names on an ignore list, @@ -78,10 +82,22 @@ def checkEquivalent(iface, harness): # # Yes, this is an ugly, fragile hack. But it finds bugs... for attr in dir(type1): - if attr.startswith('_') or \ - attr in ['nullable', 'builtin', 'filename', 'location', - 'inner', 'QName', 'getDeps', 'name', 'prettyName'] or \ - (hasattr(type(type1), attr) and not callable(getattr(type1, attr))): + if ( + attr.startswith("_") + or attr + in [ + "nullable", + "builtin", + "filename", + "location", + "inner", + "QName", + "getDeps", + "name", + "prettyName", + ] + or (hasattr(type(type1), attr) and not callable(getattr(type1, attr))) + ): continue a1 = getattr(type1, attr) @@ -96,20 +112,30 @@ def checkEquivalent(iface, harness): try: a2 = getattr(type2, attr) except: - harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface)) + harness.ok( + False, + "Missing %s attribute on type %s in %s" % (attr, type2, iface), + ) continue if not callable(a2): - harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface)) + harness.ok( + False, + "%s attribute on type %s in %s wasn't callable" + % (attr, type2, iface), + ) continue v2 = a2() - harness.check(v2, v1, '%s method return value' % attr) + harness.check(v2, v1, "%s method return value" % attr) else: try: a2 = getattr(type2, attr) except: - harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface)) + harness.ok( + False, + "Missing %s attribute on type %s in %s" % (attr, type2, iface), + ) continue - harness.check(a2, a1, '%s attribute should match' % attr) + harness.check(a2, a1, "%s attribute should match" % attr) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py b/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py deleted file mode 100644 index ebf841a5205..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_nullable_void.py +++ /dev/null @@ -1,14 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse(""" - interface NullableUndefined { - undefined? foo(); - }; - """) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py b/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py new file mode 100644 index 00000000000..601f626bcf4 --- /dev/null +++ b/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py @@ -0,0 +1,288 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +def WebIDLTest(parser, harness): + + # Test dictionary as inner type + harness.should_throw( + parser, + """ + dictionary A { + boolean member; + }; + interface B { + attribute ObservableArray<A> foo; + }; + """, + "use dictionary as inner type", + ) + + # Test sequence as inner type + harness.should_throw( + parser, + """ + interface A { + attribute ObservableArray<sequence<boolean>> foo; + }; + """, + "use sequence as inner type", + ) + + # Test sequence<dictionary> as inner type + harness.should_throw( + parser, + """ + dictionary A { + boolean member; + }; + interface B { + attribute ObservableArray<sequence<A>> foo; + }; + """, + "use sequence<dictionary> as inner type", + ) + + # Test record as inner type + harness.should_throw( + parser, + """ + interface A { + attribute ObservableArray<record<DOMString, boolean>> foo; + }; + """, + "use record as inner type", + ) + + # Test record<dictionary> as inner type + harness.should_throw( + parser, + """ + dictionary A { + boolean member; + }; + interface B { + attribute ObservableArray<record<DOMString, A>> foo; + }; + """, + "use record<dictionary> as inner type", + ) + + # Test observable array as inner type + harness.should_throw( + parser, + """ + interface A { + attribute ObservableArray<ObservableArray<boolean>> foo; + }; + """, + "use ObservableArray as inner type", + ) + + # Test nullable attribute + harness.should_throw( + parser, + """ + interface A { + attribute ObservableArray<boolean>? foo; + }; + """, + "nullable", + ) + + # Test sequence + harness.should_throw( + parser, + """ + interface A { + undefined foo(sequence<ObservableArray<boolean>> foo); + }; + """, + "used in sequence", + ) + + # Test record + harness.should_throw( + parser, + """ + interface A { + undefined foo(record<DOMString, ObservableArray<boolean>> foo); + }; + """, + "used in record", + ) + + # Test promise + harness.should_throw( + parser, + """ + interface A { + Promise<ObservableArray<boolean>> foo(); + }; + """, + "used in promise", + ) + + # Test union + harness.should_throw( + parser, + """ + interface A { + attribute (DOMString or ObservableArray<boolean>>) foo; + }; + """, + "used in union", + ) + + # Test dictionary member + harness.should_throw( + parser, + """ + dictionary A { + ObservableArray<boolean> foo; + }; + """, + "used on dictionary member type", + ) + + # Test argument + harness.should_throw( + parser, + """ + interface A { + undefined foo(ObservableArray<boolean> foo); + }; + """, + "used on argument", + ) + + # Test static attribute + harness.should_throw( + parser, + """ + interface A { + static attribute ObservableArray<boolean> foo; + }; + """, + "used on static attribute type", + ) + + # Test iterable + harness.should_throw( + parser, + """ + interface A { + iterable<ObservableArray<boolean>>; + }; + """, + "used in iterable", + ) + + # Test maplike + harness.should_throw( + parser, + """ + interface A { + maplike<long, ObservableArray<boolean>>; + }; + """, + "used in maplike", + ) + + # Test setlike + harness.should_throw( + parser, + """ + interface A { + setlike<ObservableArray<boolean>>; + }; + """, + "used in setlike", + ) + + # Test JS implemented interface + harness.should_throw( + parser, + """ + [JSImplementation="@mozilla.org/dom/test-interface-js;1"] + interface A { + readonly attribute ObservableArray<boolean> foo; + }; + """, + "used in JS implemented interface", + ) + + # Test namespace + harness.should_throw( + parser, + """ + namespace A { + readonly attribute ObservableArray<boolean> foo; + }; + """, + "used in namespaces", + ) + + # Test [Cached] extended attribute + harness.should_throw( + parser, + """ + interface A { + [Cached, Pure] + readonly attribute ObservableArray<boolean> foo; + }; + """, + "have Cached extended attribute", + ) + + # Test [StoreInSlot] extended attribute + harness.should_throw( + parser, + """ + interface A { + [StoreInSlot, Pure] + readonly attribute ObservableArray<boolean> foo; + }; + """, + "have StoreInSlot extended attribute", + ) + + # Test regular attribute + parser = parser.reset() + parser.parse( + """ + interface A { + readonly attribute ObservableArray<boolean> foo; + attribute ObservableArray<[Clamp] octet> bar; + attribute ObservableArray<long?> baz; + attribute ObservableArray<(boolean or long)> qux; + }; + """ + ) + results = parser.finish() + A = results[0] + foo = A.members[0] + harness.ok(foo.readonly, "A.foo is readonly attribute") + harness.ok(foo.type.isObservableArray(), "A.foo is ObservableArray type") + harness.check( + foo.slotIndices[A.identifier.name], 0, "A.foo should be stored in slot" + ) + bar = A.members[1] + harness.ok(bar.type.isObservableArray(), "A.bar is ObservableArray type") + harness.check( + bar.slotIndices[A.identifier.name], 1, "A.bar should be stored in slot" + ) + harness.ok(bar.type.inner.hasClamp(), "A.bar's inner type should be clamped") + baz = A.members[2] + harness.ok(baz.type.isObservableArray(), "A.baz is ObservableArray type") + harness.check( + baz.slotIndices[A.identifier.name], 2, "A.baz should be stored in slot" + ) + harness.ok(baz.type.inner.nullable(), "A.baz's inner type should be nullable") + qux = A.members[3] + harness.ok(qux.type.isObservableArray(), "A.qux is ObservableArray type") + harness.check( + qux.slotIndices[A.identifier.name], 3, "A.qux should be stored in slot" + ) + harness.ok(qux.type.inner.isUnion(), "A.qux's inner type should be union") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py b/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py index ad012b633d5..2044c6362c3 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py @@ -1,30 +1,35 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface OptionalConstraints1 { undefined foo(optional byte arg1, byte arg2); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(not threw, - "Should not have thrown on non-optional argument following " - "optional argument.") + harness.ok( + not threw, + "Should not have thrown on non-optional argument following " + "optional argument.", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface OptionalConstraints2 { undefined foo(optional byte arg1 = 1, optional byte arg2 = 2, - optional byte arg3, optional byte arg4 = 4, - optional byte arg5, optional byte arg6 = 9); + optional byte arg3, optional byte arg4 = 4, + optional byte arg5, optional byte arg6 = 9); }; - """) + """ + ) results = parser.finish() args = results[0].members[0].signatures()[0][1] harness.check(len(args), 6, "Should have 6 arguments") - harness.check(args[5].defaultValue.value, 9, - "Should have correct default value") + harness.check(args[5].defaultValue.value, 9, "Should have correct default value") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_overload.py b/components/script/dom/bindings/codegen/parser/tests/test_overload.py index 8e02f64d6c9..7816276aa6d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_overload.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_overload.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestOverloads { undefined basic(); undefined basic(long arg1); @@ -14,21 +16,29 @@ def WebIDLTest(parser, harness): undefined optionalTest(); undefined optionalTest(optional long num1, long num2); }; - """) + """ + ) results = parser.finish() harness.ok(True, "TestOverloads interface parsed without error.") harness.check(len(results), 1, "Should be one production.") iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), - "Should be an IDLInterface") - harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName") - harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name") + harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") + harness.check( + iface.identifier.QName(), "::TestOverloads", "Interface has the right QName" + ) + harness.check( + iface.identifier.name, "TestOverloads", "Interface has the right name" + ) harness.check(len(iface.members), 4, "Expect %s members" % 4) member = iface.members[0] - harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName") + harness.check( + member.identifier.QName(), + "::TestOverloads::basic", + "Method has the right QName", + ) harness.check(member.identifier.name, "basic", "Method has the right name") harness.check(member.hasOverloads(), True, "Method has overloads") @@ -37,24 +47,28 @@ def WebIDLTest(parser, harness): (retval, argumentSet) = signatures[0] - harness.check(str(retval), "Undefined", "Expect a undefined retval") + harness.check(str(retval), "Undefined", "Expect an undefined retval") harness.check(len(argumentSet), 0, "Expect an empty argument set") (retval, argumentSet) = signatures[1] - harness.check(str(retval), "Undefined", "Expect a undefined retval") + harness.check(str(retval), "Undefined", "Expect an undefined retval") harness.check(len(argumentSet), 1, "Expect an argument set with one argument") argument = argumentSet[0] - harness.ok(isinstance(argument, WebIDL.IDLArgument), - "Should be an IDLArgument") - harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName") + harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") + harness.check( + argument.identifier.QName(), + "::TestOverloads::basic::arg1", + "Argument has the right QName", + ) harness.check(argument.identifier.name, "arg1", "Argument has the right name") harness.check(str(argument.type), "Long", "Argument has the right type") member = iface.members[3] - harness.check(len(member.overloadsForArgCount(0)), 1, - "Only one overload for no args") - harness.check(len(member.overloadsForArgCount(1)), 0, - "No overloads for one arg") - harness.check(len(member.overloadsForArgCount(2)), 1, - "Only one overload for two args") + harness.check( + len(member.overloadsForArgCount(0)), 1, "Only one overload for no args" + ) + harness.check(len(member.overloadsForArgCount(1)), 0, "No overloads for one arg") + harness.check( + len(member.overloadsForArgCount(2)), 1, "Only one overload for two args" + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_promise.py b/components/script/dom/bindings/codegen/parser/tests/test_promise.py index ef44a216d10..9b418d51afe 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_promise.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_promise.py @@ -1,157 +1,177 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface A { legacycaller Promise<any> foo(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow Promise return values for legacycaller.") + harness.ok(threw, "Should not allow Promise return values for legacycaller.") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { Promise<any> foo(); long foo(long arg); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow overloads which have both Promise and " - "non-Promise return types.") + harness.ok( + threw, + "Should not allow overloads which have both Promise and " + "non-Promise return types.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { long foo(long arg); Promise<any> foo(); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow overloads which have both Promise and " - "non-Promise return types.") + harness.ok( + threw, + "Should not allow overloads which have both Promise and " + "non-Promise return types.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { Promise<any>? foo(); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow nullable Promise return values.") + harness.ok(threw, "Should not allow nullable Promise return values.") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { undefined foo(Promise<any>? arg); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow nullable Promise arguments.") + harness.ok(threw, "Should not allow nullable Promise arguments.") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface A { Promise<any> foo(); Promise<any> foo(long arg); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() - harness.ok(True, - "Should allow overloads which only have Promise and return " - "types.") + harness.ok( + True, "Should allow overloads which only have Promise and return " "types." + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { attribute Promise<any> attr; }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow writable Promise-typed attributes.") + harness.ok(threw, "Should not allow writable Promise-typed attributes.") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { - [LenientSetter] readonly attribute Promise<any> attr; + [LegacyLenientSetter] readonly attribute Promise<any> attr; }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [LenientSetter] Promise-typed attributes.") + harness.ok( + threw, "Should not allow [LegacyLenientSetter] Promise-typed attributes." + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [PutForwards=bar] readonly attribute Promise<any> attr; }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [PutForwards] Promise-typed attributes.") + harness.ok(threw, "Should not allow [PutForwards] Promise-typed attributes.") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [Replaceable] readonly attribute Promise<any> attr; }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [Replaceable] Promise-typed attributes.") + harness.ok(threw, "Should not allow [Replaceable] Promise-typed attributes.") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface A { [SameObject] readonly attribute Promise<any> attr; }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should not allow [SameObject] Promise-typed attributes.") + harness.ok(threw, "Should not allow [SameObject] Promise-typed attributes.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py b/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py index d3932b54f8b..5a806bf2a2d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface TestIface { static attribute boolean prototype; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -15,11 +17,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestIface { static boolean prototype(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -29,11 +33,13 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestIface { const boolean prototype = true; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -42,39 +48,60 @@ def WebIDLTest(parser, harness): # Make sure that we can parse non-static attributes with 'prototype' as identifier. parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestIface { attribute boolean prototype; }; - """) + """ + ) results = parser.finish() - testIface = results[0]; - harness.check(testIface.members[0].isStatic(), False, "Attribute should not be static") - harness.check(testIface.members[0].identifier.name, "prototype", "Attribute identifier should be 'prototype'") + testIface = results[0] + harness.check( + testIface.members[0].isStatic(), False, "Attribute should not be static" + ) + harness.check( + testIface.members[0].identifier.name, + "prototype", + "Attribute identifier should be 'prototype'", + ) # Make sure that we can parse non-static operations with 'prototype' as identifier. parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestIface { boolean prototype(); }; - """) + """ + ) results = parser.finish() - testIface = results[0]; - harness.check(testIface.members[0].isStatic(), False, "Operation should not be static") - harness.check(testIface.members[0].identifier.name, "prototype", "Operation identifier should be 'prototype'") + testIface = results[0] + harness.check( + testIface.members[0].isStatic(), False, "Operation should not be static" + ) + harness.check( + testIface.members[0].identifier.name, + "prototype", + "Operation identifier should be 'prototype'", + ) # Make sure that we can parse dictionary members with 'prototype' as identifier. parser = parser.reset() - parser.parse(""" + parser.parse( + """ dictionary TestDict { boolean prototype; }; - """) + """ + ) results = parser.finish() - testDict = results[0]; - harness.check(testDict.members[0].identifier.name, "prototype", "Dictionary member should be 'prototype'") - + testDict = results[0] + harness.check( + testDict.members[0].identifier.name, + "prototype", + "Dictionary member should be 'prototype'", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py b/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py index 86a1bf115b6..5ec4dde280e 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface I { [PutForwards=B] readonly attribute long A; }; - """) + """ + ) results = parser.finish() except: @@ -13,16 +15,18 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should have thrown.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface I { [PutForwards=B] readonly attribute J A; }; interface J { }; - """) + """ + ) results = parser.finish() except: @@ -30,17 +34,19 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should have thrown.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface I { [PutForwards=B] attribute J A; }; interface J { attribute long B; }; - """) + """ + ) results = parser.finish() except: @@ -48,17 +54,19 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should have thrown.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface I { [PutForwards=B] static readonly attribute J A; }; interface J { attribute long B; }; - """) + """ + ) results = parser.finish() except: @@ -66,17 +74,19 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should have thrown.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ callback interface I { [PutForwards=B] readonly attribute J A; }; interface J { attribute long B; }; - """) + """ + ) results = parser.finish() except: @@ -84,10 +94,11 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should have thrown.") - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface I { [PutForwards=C] readonly attribute J A; [PutForwards=C] readonly attribute J B; @@ -98,7 +109,8 @@ def WebIDLTest(parser, harness): interface K { [PutForwards=A] readonly attribute I D; }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_record.py b/components/script/dom/bindings/codegen/parser/tests/test_record.py index 3d83e249be8..3a31d721b27 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_record.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_record.py @@ -1,18 +1,22 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ dictionary Dict {}; interface RecordArg { undefined foo(record<DOMString, Dict> arg); }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, "Should know about two things"); - harness.ok(isinstance(results[1], WebIDL.IDLInterface), - "Should have an interface here"); + harness.check(len(results), 2, "Should know about two things") + harness.ok( + isinstance(results[1], WebIDL.IDLInterface), "Should have an interface here" + ) members = results[1].members harness.check(len(members), 1, "Should have one member") harness.ok(members[0].isMethod(), "Should have method") @@ -20,34 +24,38 @@ def WebIDLTest(parser, harness): args = signature[1] harness.check(len(args), 1, "Should have one arg") harness.ok(args[0].type.isRecord(), "Should have a record type here") - harness.ok(args[0].type.inner.isDictionary(), - "Should have a dictionary inner type") + harness.ok(args[0].type.inner.isDictionary(), "Should have a dictionary inner type") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface RecordUndefinedArg { undefined foo(record<DOMString, undefined> arg); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, "Should have thrown because record can't have undefined as value type.") + harness.ok( + threw, "Should have thrown because record can't have undefined as value type." + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ dictionary Dict { record<DOMString, Dict> val; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, - "Should have thrown on dictionary containing itself via record.") + harness.ok(threw, "Should have thrown on dictionary containing itself via record.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py b/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py index 93ee42ed919..06ea6a47239 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py @@ -2,8 +2,9 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. + def should_throw(parser, harness, message, code): - parser = parser.reset(); + parser = parser.reset() threw = False try: parser.parse(code) @@ -16,43 +17,68 @@ def should_throw(parser, harness, message, code): def WebIDLTest(parser, harness): # The [Replaceable] extended attribute MUST take no arguments. - should_throw(parser, harness, "no arguments", """ + should_throw( + parser, + harness, + "no arguments", + """ interface I { [Replaceable=X] readonly attribute long A; }; - """) + """, + ) # An attribute with the [Replaceable] extended attribute MUST NOT also be # declared with the [PutForwards] extended attribute. - should_throw(parser, harness, "PutForwards", """ + should_throw( + parser, + harness, + "PutForwards", + """ interface I { [PutForwards=B, Replaceable] readonly attribute J A; }; interface J { attribute long B; }; - """) + """, + ) # The [Replaceable] extended attribute MUST NOT be used on an attribute # that is not read only. - should_throw(parser, harness, "writable attribute", """ + should_throw( + parser, + harness, + "writable attribute", + """ interface I { [Replaceable] attribute long A; }; - """) + """, + ) # The [Replaceable] extended attribute MUST NOT be used on a static # attribute. - should_throw(parser, harness, "static attribute", """ + should_throw( + parser, + harness, + "static attribute", + """ interface I { [Replaceable] static readonly attribute long A; }; - """) + """, + ) # The [Replaceable] extended attribute MUST NOT be used on an attribute # declared on a callback interface. - should_throw(parser, harness, "callback interface", """ + should_throw( + parser, + harness, + "callback interface", + """ callback interface I { [Replaceable] readonly attribute long A; }; - """) + """, + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py b/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py index 5af0c22803c..e0e967dd420 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ [SecureContext] interface TestSecureContextOnInterface { const octet TEST_CONSTANT = 0; @@ -13,27 +15,47 @@ def WebIDLTest(parser, harness): readonly attribute byte testAttribute2; undefined testMethod2(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 6, "TestSecureContextOnInterface should have six members") - harness.ok(results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members") - harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members") - harness.ok(results[0].members[2].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members") - harness.ok(results[0].members[3].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members from partial interface") - harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members from partial interface") - harness.ok(results[0].members[5].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members from partial interface") + harness.check( + len(results[0].members), + 6, + "TestSecureContextOnInterface should have six members", + ) + harness.ok( + results[0].getExtendedAttribute("SecureContext"), + "Interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to constant members", + ) + harness.ok( + results[0].members[1].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to attribute members", + ) + harness.ok( + results[0].members[2].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to method members", + ) + harness.ok( + results[0].members[3].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to constant members from partial interface", + ) + harness.ok( + results[0].members[4].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to attribute members from partial interface", + ) + harness.ok( + results[0].members[5].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to method members from partial interface", + ) # Same thing, but with the partial interface specified first: parser = parser.reset() - parser.parse(""" + parser.parse( + """ partial interface TestSecureContextOnInterfaceAfterPartialInterface { const octet TEST_CONSTANT_2 = 0; readonly attribute byte testAttribute2; @@ -45,26 +67,46 @@ def WebIDLTest(parser, harness): readonly attribute byte testAttribute; undefined testMethod(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[1].members), 6, "TestSecureContextOnInterfaceAfterPartialInterface should have six members") - harness.ok(results[1].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute") - harness.ok(results[1].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members") - harness.ok(results[1].members[1].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members") - harness.ok(results[1].members[2].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members") - harness.ok(results[1].members[3].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members from partial interface") - harness.ok(results[1].members[4].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members from partial interface") - harness.ok(results[1].members[5].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members from partial interface") + harness.check( + len(results[1].members), + 6, + "TestSecureContextOnInterfaceAfterPartialInterface should have six members", + ) + harness.ok( + results[1].getExtendedAttribute("SecureContext"), + "Interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[1].members[0].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to constant members", + ) + harness.ok( + results[1].members[1].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to attribute members", + ) + harness.ok( + results[1].members[2].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to method members", + ) + harness.ok( + results[1].members[3].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to constant members from partial interface", + ) + harness.ok( + results[1].members[4].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to attribute members from partial interface", + ) + harness.ok( + results[1].members[5].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to method members from partial interface", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestSecureContextOnPartialInterface { const octet TEST_CONSTANT = 0; readonly attribute byte testAttribute; @@ -76,26 +118,46 @@ def WebIDLTest(parser, harness): readonly attribute byte testAttribute2; undefined testMethod2(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 6, "TestSecureContextOnPartialInterface should have six members") - harness.ok(results[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's constant members") - harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's attribute members") - harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's method members") - harness.ok(results[0].members[3].getExtendedAttribute("SecureContext"), - "Constant members from [SecureContext] partial interface should be [SecureContext]") - harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute members from [SecureContext] partial interface should be [SecureContext]") - harness.ok(results[0].members[5].getExtendedAttribute("SecureContext"), - "Method members from [SecureContext] partial interface should be [SecureContext]") + harness.check( + len(results[0].members), + 6, + "TestSecureContextOnPartialInterface should have six members", + ) + harness.ok( + results[0].getExtendedAttribute("SecureContext") is None, + "[SecureContext] should not propagate from a partial interface to the interface", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext") is None, + "[SecureContext] should not propagate from a partial interface to the interface's constant members", + ) + harness.ok( + results[0].members[1].getExtendedAttribute("SecureContext") is None, + "[SecureContext] should not propagate from a partial interface to the interface's attribute members", + ) + harness.ok( + results[0].members[2].getExtendedAttribute("SecureContext") is None, + "[SecureContext] should not propagate from a partial interface to the interface's method members", + ) + harness.ok( + results[0].members[3].getExtendedAttribute("SecureContext"), + "Constant members from [SecureContext] partial interface should be [SecureContext]", + ) + harness.ok( + results[0].members[4].getExtendedAttribute("SecureContext"), + "Attribute members from [SecureContext] partial interface should be [SecureContext]", + ) + harness.ok( + results[0].members[5].getExtendedAttribute("SecureContext"), + "Method members from [SecureContext] partial interface should be [SecureContext]", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestSecureContextOnInterfaceMembers { const octet TEST_NON_SECURE_CONSTANT_1 = 0; [SecureContext] @@ -110,32 +172,58 @@ def WebIDLTest(parser, harness): undefined testSecureMethod(byte foo); undefined testNonSecureMethod2(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 9, "TestSecureContextOnInterfaceMembers should have nine members") - harness.ok(results[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] on members should not propagate up to the interface") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, - "Constant should not have [SecureContext] extended attribute") - harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), - "Constant should have [SecureContext] extended attribute") - harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Constant should not have [SecureContext] extended attribute") - harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Attribute should not have [SecureContext] extended attribute") - harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute should have [SecureContext] extended attribute") - harness.ok(results[0].members[5].getExtendedAttribute("SecureContext") is None, - "Attribute should not have [SecureContext] extended attribute") - harness.ok(results[0].members[6].getExtendedAttribute("SecureContext") is None, - "Method should not have [SecureContext] extended attribute") - harness.ok(results[0].members[7].getExtendedAttribute("SecureContext"), - "Method should have [SecureContext] extended attribute") - harness.ok(results[0].members[8].getExtendedAttribute("SecureContext") is None, - "Method should not have [SecureContext] extended attribute") + harness.check( + len(results[0].members), + 9, + "TestSecureContextOnInterfaceMembers should have nine members", + ) + harness.ok( + results[0].getExtendedAttribute("SecureContext") is None, + "[SecureContext] on members should not propagate up to the interface", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext") is None, + "Constant should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[1].getExtendedAttribute("SecureContext"), + "Constant should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[2].getExtendedAttribute("SecureContext") is None, + "Constant should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[3].getExtendedAttribute("SecureContext") is None, + "Attribute should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[4].getExtendedAttribute("SecureContext"), + "Attribute should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[5].getExtendedAttribute("SecureContext") is None, + "Attribute should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[6].getExtendedAttribute("SecureContext") is None, + "Method should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[7].getExtendedAttribute("SecureContext"), + "Method should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[8].getExtendedAttribute("SecureContext") is None, + "Method should not have [SecureContext] extended attribute", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestSecureContextOnPartialInterfaceMembers { }; partial interface TestSecureContextOnPartialInterfaceMembers { @@ -152,37 +240,62 @@ def WebIDLTest(parser, harness): undefined testSecureMethod(byte foo); undefined testNonSecureMethod2(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 9, "TestSecureContextOnPartialInterfaceMembers should have nine members") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, - "Constant from partial interface should not have [SecureContext] extended attribute") - harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), - "Constant from partial interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Constant from partial interface should not have [SecureContext] extended attribute") - harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Attribute from partial interface should not have [SecureContext] extended attribute") - harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute from partial interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[5].getExtendedAttribute("SecureContext") is None, - "Attribute from partial interface should not have [SecureContext] extended attribute") - harness.ok(results[0].members[6].getExtendedAttribute("SecureContext") is None, - "Method from partial interface should not have [SecureContext] extended attribute") - harness.ok(results[0].members[7].getExtendedAttribute("SecureContext"), - "Method from partial interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[8].getExtendedAttribute("SecureContext") is None, - "Method from partial interface should not have [SecureContext] extended attribute") + harness.check( + len(results[0].members), + 9, + "TestSecureContextOnPartialInterfaceMembers should have nine members", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext") is None, + "Constant from partial interface should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[1].getExtendedAttribute("SecureContext"), + "Constant from partial interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[2].getExtendedAttribute("SecureContext") is None, + "Constant from partial interface should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[3].getExtendedAttribute("SecureContext") is None, + "Attribute from partial interface should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[4].getExtendedAttribute("SecureContext"), + "Attribute from partial interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[5].getExtendedAttribute("SecureContext") is None, + "Attribute from partial interface should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[6].getExtendedAttribute("SecureContext") is None, + "Method from partial interface should not have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[7].getExtendedAttribute("SecureContext"), + "Method from partial interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[8].getExtendedAttribute("SecureContext") is None, + "Method from partial interface should not have [SecureContext] extended attribute", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SecureContext=something] interface TestSecureContextTakesNoValue1 { const octet TEST_SECURE_CONSTANT = 0; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -191,7 +304,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestSecureContextForOverloads1 { [SecureContext] undefined testSecureMethod(byte foo); @@ -199,16 +313,21 @@ def WebIDLTest(parser, harness): partial interface TestSecureContextForOverloads1 { undefined testSecureMethod(byte foo, byte bar); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "If [SecureContext] appears on an overloaded operation, then it MUST appear on all overloads") + harness.ok( + threw, + "If [SecureContext] appears on an overloaded operation, then it MUST appear on all overloads", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestSecureContextForOverloads2 { [SecureContext] undefined testSecureMethod(byte foo); @@ -217,31 +336,40 @@ def WebIDLTest(parser, harness): [SecureContext] undefined testSecureMethod(byte foo, byte bar); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(not threw, "[SecureContext] can appear on an overloaded operation if it appears on all overloads") + harness.ok( + not threw, + "[SecureContext] can appear on an overloaded operation if it appears on all overloads", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SecureContext] interface TestSecureContextOnInterfaceAndMember { [SecureContext] undefined testSecureMethod(byte foo); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "[SecureContext] must not appear on an interface and interface member") + harness.ok( + threw, "[SecureContext] must not appear on an interface and interface member" + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestSecureContextOnPartialInterfaceAndMember { }; [SecureContext] @@ -249,16 +377,21 @@ def WebIDLTest(parser, harness): [SecureContext] undefined testSecureMethod(byte foo); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "[SecureContext] must not appear on a partial interface and one of the partial interface's member's") + harness.ok( + threw, + "[SecureContext] must not appear on a partial interface and one of the partial interface's member's", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SecureContext] interface TestSecureContextOnInterfaceAndPartialInterfaceMember { }; @@ -266,31 +399,41 @@ def WebIDLTest(parser, harness): [SecureContext] undefined testSecureMethod(byte foo); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "[SecureContext] must not appear on an interface and one of its partial interface's member's") + harness.ok( + threw, + "[SecureContext] must not appear on an interface and one of its partial interface's member's", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [SecureContext] interface TestSecureContextOnInheritedInterface { }; interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface { undefined testSecureMethod(byte foo); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "[SecureContext] must appear on interfaces that inherit from another [SecureContext] interface") + harness.ok( + threw, + "[SecureContext] must appear on interfaces that inherit from another [SecureContext] interface", + ) # Test 'includes'. parser = parser.reset() - parser.parse(""" + parser.parse( + """ [SecureContext] interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin { const octet TEST_CONSTANT = 0; @@ -301,31 +444,56 @@ def WebIDLTest(parser, harness): undefined testMethod2(byte foo); }; TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 4, "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four members") - harness.ok(results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface") - harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None, - "Constants copied from non-[SecureContext] mixin should not be [SecureContext]") - harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]") - harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Methods copied from non-[SecureContext] mixin should not be [SecureContext]") + harness.check( + len(results[0].members), + 4, + "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four members", + ) + harness.ok( + results[0].getExtendedAttribute("SecureContext"), + "Interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext"), + "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface", + ) + harness.ok( + results[0].members[1].getExtendedAttribute("SecureContext") is None, + "Constants copied from non-[SecureContext] mixin should not be [SecureContext]", + ) + harness.ok( + results[0].members[2].getExtendedAttribute("SecureContext") is None, + "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]", + ) + harness.ok( + results[0].members[3].getExtendedAttribute("SecureContext") is None, + "Methods copied from non-[SecureContext] mixin should not be [SecureContext]", + ) - # Test SecureContext and NoInterfaceObject + # Test SecureContext and LegacyNoInterfaceObject parser = parser.reset() - parser.parse(""" - [NoInterfaceObject, SecureContext] - interface TestSecureContextNoInterfaceObject { + parser.parse( + """ + [LegacyNoInterfaceObject, SecureContext] + interface TestSecureContextLegacyNoInterfaceObject { undefined testSecureMethod(byte foo); }; - """) + """ + ) results = parser.finish() - harness.check(len(results[0].members), 1, "TestSecureContextNoInterfaceObject should have only one member") - harness.ok(results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute") - harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), - "Interface member should have [SecureContext] extended attribute") + harness.check( + len(results[0].members), + 1, + "TestSecureContextLegacyNoInterfaceObject should have only one member", + ) + harness.ok( + results[0].getExtendedAttribute("SecureContext"), + "Interface should have [SecureContext] extended attribute", + ) + harness.ok( + results[0].members[0].getExtendedAttribute("SecureContext"), + "Interface member should have [SecureContext] extended attribute", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py b/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py index b209c850d6b..a11860b3728 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch1 { getter long long foo(long index); }; - """) + """ + ) results = parser.finish() except: @@ -15,11 +17,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch2 { getter undefined foo(unsigned long index); }; - """) + """ + ) results = parser.finish() except: @@ -29,11 +33,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch3 { getter boolean foo(unsigned long index, boolean extraArg); }; - """) + """ + ) results = parser.finish() except: @@ -43,11 +49,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch4 { getter boolean foo(unsigned long... index); }; - """) + """ + ) results = parser.finish() except: @@ -57,11 +65,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch5 { getter boolean foo(optional unsigned long index); }; - """) + """ + ) results = parser.finish() except: @@ -71,11 +81,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch6 { getter boolean foo(); }; - """) + """ + ) results = parser.finish() except: @@ -85,11 +97,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch7 { deleter long long foo(long index); }; - """) + """ + ) results = parser.finish() except: @@ -99,11 +113,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch9 { deleter boolean foo(unsigned long index, boolean extraArg); }; - """) + """ + ) results = parser.finish() except: @@ -113,11 +129,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch10 { deleter boolean foo(unsigned long... index); }; - """) + """ + ) results = parser.finish() except: @@ -127,11 +145,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch11 { deleter boolean foo(optional unsigned long index); }; - """) + """ + ) results = parser.finish() except: @@ -141,11 +161,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch12 { deleter boolean foo(); }; - """) + """ + ) results = parser.finish() except: @@ -155,11 +177,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch13 { setter long long foo(long index, long long value); }; - """) + """ + ) results = parser.finish() except: @@ -169,11 +193,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch15 { setter boolean foo(unsigned long index, boolean value, long long extraArg); }; - """) + """ + ) results = parser.finish() except: @@ -183,11 +209,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch16 { setter boolean foo(unsigned long index, boolean... value); }; - """) + """ + ) results = parser.finish() except: @@ -197,11 +225,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch17 { setter boolean foo(unsigned long index, optional boolean value); }; - """) + """ + ) results = parser.finish() except: @@ -211,11 +241,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodSignatureMismatch18 { setter boolean foo(); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py b/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py index c657c9c797d..9601a0a968f 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py @@ -1,7 +1,9 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface SpecialMethods { getter long long (unsigned long index); setter long long (unsigned long index, long long value); @@ -14,47 +16,90 @@ def WebIDLTest(parser, harness): interface SpecialMethodsCombination { getter deleter boolean (DOMString name); }; - """) + """ + ) results = parser.finish() - def checkMethod(method, QName, name, - static=False, getter=False, setter=False, - deleter=False, legacycaller=False, stringifier=False): - harness.ok(isinstance(method, WebIDL.IDLMethod), - "Should be an IDLMethod") + def checkMethod( + method, + QName, + name, + static=False, + getter=False, + setter=False, + deleter=False, + legacycaller=False, + stringifier=False, + ): + harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") harness.check(method.identifier.QName(), QName, "Method has the right QName") harness.check(method.identifier.name, name, "Method has the right name") harness.check(method.isStatic(), static, "Method has the correct static value") harness.check(method.isGetter(), getter, "Method has the correct getter value") harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check(method.isDeleter(), deleter, "Method has the correct deleter value") - harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value") - harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") + harness.check( + method.isDeleter(), deleter, "Method has the correct deleter value" + ) + harness.check( + method.isLegacycaller(), + legacycaller, + "Method has the correct legacycaller value", + ) + harness.check( + method.isStringifier(), + stringifier, + "Method has the correct stringifier value", + ) harness.check(len(results), 2, "Expect 2 interfaces") iface = results[0] harness.check(len(iface.members), 6, "Expect 6 members") - checkMethod(iface.members[0], "::SpecialMethods::__indexedgetter", "__indexedgetter", - getter=True) - checkMethod(iface.members[1], "::SpecialMethods::__indexedsetter", "__indexedsetter", - setter=True) - checkMethod(iface.members[2], "::SpecialMethods::__namedgetter", "__namedgetter", - getter=True) - checkMethod(iface.members[3], "::SpecialMethods::__namedsetter", "__namedsetter", - setter=True) - checkMethod(iface.members[4], "::SpecialMethods::__nameddeleter", "__nameddeleter", - deleter=True) + checkMethod( + iface.members[0], + "::SpecialMethods::__indexedgetter", + "__indexedgetter", + getter=True, + ) + checkMethod( + iface.members[1], + "::SpecialMethods::__indexedsetter", + "__indexedsetter", + setter=True, + ) + checkMethod( + iface.members[2], + "::SpecialMethods::__namedgetter", + "__namedgetter", + getter=True, + ) + checkMethod( + iface.members[3], + "::SpecialMethods::__namedsetter", + "__namedsetter", + setter=True, + ) + checkMethod( + iface.members[4], + "::SpecialMethods::__nameddeleter", + "__nameddeleter", + deleter=True, + ) iface = results[1] harness.check(len(iface.members), 1, "Expect 1 member") - checkMethod(iface.members[0], "::SpecialMethodsCombination::__namedgetterdeleter", - "__namedgetterdeleter", getter=True, deleter=True) + checkMethod( + iface.members[0], + "::SpecialMethodsCombination::__namedgetterdeleter", + "__namedgetterdeleter", + getter=True, + deleter=True, + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: @@ -63,11 +108,10 @@ def WebIDLTest(parser, harness): interface IndexedDeleter { deleter undefined(unsigned long index); }; - """) + """ + ) parser.finish() except: threw = True harness.ok(threw, "There are no indexed deleters") - - diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py b/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py index 9bf3d903463..014737e8168 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py @@ -1,14 +1,17 @@ import WebIDL + def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodUniqueness1 { getter deleter boolean (DOMString name); getter boolean (DOMString name); }; - """) + """ + ) results = parser.finish() except: @@ -18,12 +21,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodUniqueness1 { deleter boolean (DOMString name); getter deleter boolean (DOMString name); }; - """) + """ + ) results = parser.finish() except: @@ -33,12 +38,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface SpecialMethodUniqueness1 { setter boolean (DOMString name); setter boolean (DOMString name); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py b/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py index deabdc5ec81..948be71e4dd 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py @@ -1,27 +1,34 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier; }; - """) + """ + ) results = parser.finish() - harness.ok(isinstance(results[0].members[0], WebIDL.IDLMethod), - "Stringifer should be method") + harness.ok( + isinstance(results[0].members[0], WebIDL.IDLMethod), + "Stringifer should be method", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier; stringifier; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -32,12 +39,14 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier; stringifier DOMString foo(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -45,70 +54,107 @@ def WebIDLTest(parser, harness): harness.ok(threw, "Should not allow a 'stringifier;' and a 'stringifier()'") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier attribute DOMString foo; }; - """) + """ + ) results = parser.finish() - harness.ok(isinstance(results[0].members[0], WebIDL.IDLAttribute), - "Stringifier attribute should be an attribute") + harness.ok( + isinstance(results[0].members[0], WebIDL.IDLAttribute), + "Stringifier attribute should be an attribute", + ) stringifier = results[0].members[1] - harness.ok(isinstance(stringifier, WebIDL.IDLMethod), - "Stringifier attribute should insert a method") - harness.ok(stringifier.isStringifier(), - "Inserted method should be a stringifier") + harness.ok( + isinstance(stringifier, WebIDL.IDLMethod), + "Stringifier attribute should insert a method", + ) + harness.ok(stringifier.isStringifier(), "Inserted method should be a stringifier") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestStringifier {}; interface mixin TestStringifierMixin { stringifier attribute DOMString foo; }; TestStringifier includes TestStringifierMixin; - """) + """ + ) results = parser.finish() - harness.ok(isinstance(results[0].members[0], WebIDL.IDLAttribute), - "Stringifier attribute should be an attribute") + harness.ok( + isinstance(results[0].members[0], WebIDL.IDLAttribute), + "Stringifier attribute should be an attribute", + ) stringifier = results[0].members[1] - harness.ok(isinstance(stringifier, WebIDL.IDLMethod), - "Stringifier attribute should insert a method") - harness.ok(stringifier.isStringifier(), - "Inserted method should be a stringifier") + harness.ok( + isinstance(stringifier, WebIDL.IDLMethod), + "Stringifier attribute should insert a method", + ) + harness.ok(stringifier.isStringifier(), "Inserted method should be a stringifier") parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier attribute USVString foo; }; - """) + """ + ) results = parser.finish() stringifier = results[0].members[1] - harness.ok(stringifier.signatures()[0][0].isUSVString(), - "Stringifier attributes should allow USVString") + harness.ok( + stringifier.signatures()[0][0].isUSVString(), + "Stringifier attributes should allow USVString", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface TestStringifier { [Throws, NeedsSubjectPrincipal] stringifier attribute USVString foo; }; - """) + """ + ) + results = parser.finish() + stringifier = results[0].members[1] + harness.ok( + stringifier.getExtendedAttribute("Throws"), + "Stringifier attributes should support [Throws]", + ) + harness.ok( + stringifier.getExtendedAttribute("NeedsSubjectPrincipal"), + "Stringifier attributes should support [NeedsSubjectPrincipal]", + ) + + parser = parser.reset() + parser.parse( + """ + interface TestStringifier { + stringifier attribute UTF8String foo; + }; + """ + ) results = parser.finish() stringifier = results[0].members[1] - harness.ok(stringifier.getExtendedAttribute("Throws"), - "Stringifier attributes should support [Throws]") - harness.ok(stringifier.getExtendedAttribute("NeedsSubjectPrincipal"), - "Stringifier attributes should support [NeedsSubjectPrincipal]") + harness.ok( + stringifier.signatures()[0][0].isUTF8String(), + "Stringifier attributes should allow UTF8String", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier attribute ByteString foo; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -118,12 +164,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier; stringifier attribute DOMString foo; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -133,12 +181,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface TestStringifier { stringifier attribute DOMString foo; stringifier attribute DOMString bar; }; - """) + """ + ) results = parser.finish() except: threw = True diff --git a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py b/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py index ad01330e65a..f312667ec4d 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py @@ -6,7 +6,8 @@ def WebIDLTest(parser, harness): interface Test { object toJSON(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -21,7 +22,8 @@ def WebIDLTest(parser, harness): object toJSON(object arg); object toJSON(long arg); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -35,7 +37,8 @@ def WebIDLTest(parser, harness): interface Test { object toJSON(object arg); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -49,7 +52,8 @@ def WebIDLTest(parser, harness): interface Test { long toJSON(); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -63,11 +67,14 @@ def WebIDLTest(parser, harness): interface Test { [Default] object toJSON(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(not threw, "Should allow a default toJSON method with 'object' as return type.") + harness.ok( + not threw, "Should allow a default toJSON method with 'object' as return type." + ) parser = parser.reset() threw = False @@ -77,119 +84,226 @@ def WebIDLTest(parser, harness): interface Test { [Default] long toJSON(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should not allow a default toJSON method with non-'object' as return type.") - - JsonTypes = [ "byte", "octet", "short", "unsigned short", "long", "unsigned long", "long long", - "unsigned long long", "float", "unrestricted float", "double", "unrestricted double", "boolean", - "DOMString", "ByteString", "UTF8String", "USVString", "Enum", "InterfaceWithToJSON", "object" ] - - nonJsonTypes = [ "InterfaceWithoutToJSON", "any", "Int8Array", "Int16Array", "Int32Array","Uint8Array", - "Uint16Array", "Uint32Array", "Uint8ClampedArray", "Float32Array", "Float64Array", "ArrayBuffer" ] + harness.ok( + threw, + "Should not allow a default toJSON method with non-'object' as return type.", + ) + + JsonTypes = [ + "byte", + "octet", + "short", + "unsigned short", + "long", + "unsigned long", + "long long", + "unsigned long long", + "float", + "unrestricted float", + "double", + "unrestricted double", + "boolean", + "DOMString", + "ByteString", + "UTF8String", + "USVString", + "Enum", + "InterfaceWithToJSON", + "object", + ] + + nonJsonTypes = [ + "InterfaceWithoutToJSON", + "any", + "Int8Array", + "Int16Array", + "Int32Array", + "Uint8Array", + "Uint16Array", + "Uint32Array", + "Uint8ClampedArray", + "Float32Array", + "Float64Array", + "ArrayBuffer", + ] def doTest(testIDL, shouldThrow, description): p = parser.reset() threw = False try: - p.parse(testIDL + - """ + p.parse( + testIDL + + """ enum Enum { "a", "b", "c" }; interface InterfaceWithToJSON { long toJSON(); }; interface InterfaceWithoutToJSON {}; - """); - p.finish(); + """ + ) + p.finish() except Exception as x: threw = True harness.ok(x.message == "toJSON method has non-JSON return type", x) harness.check(threw, shouldThrow, description) - for type in JsonTypes: - doTest("interface Test { %s toJSON(); };" % type, False, - "%s should be a JSON type" % type) - - doTest("interface Test { sequence<%s> toJSON(); };" % type, False, - "sequence<%s> should be a JSON type" % type) - - doTest("dictionary Foo { %s foo; }; " - "interface Test { Foo toJSON(); }; " % type, False, - "dictionary containing only JSON type (%s) should be a JSON type" % type) - - doTest("dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " - "interface Test { Bar toJSON(); }; " % type, False, - "dictionary whose ancestors only contain JSON types should be a JSON type") - - doTest("dictionary Foo { any foo; }; dictionary Bar : Foo { %s bar; };" - "interface Test { Bar toJSON(); };" % type, True, - "dictionary whose ancestors contain non-JSON types should not be a JSON type") - - doTest("interface Test { record<DOMString, %s> toJSON(); };" % type, False, - "record<DOMString, %s> should be a JSON type" % type) - - doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, False, - "record<ByteString, %s> should be a JSON type" % type) - - doTest("interface Test { record<UTF8String, %s> toJSON(); };" % type, False, - "record<UTF8String, %s> should be a JSON type" % type) - - doTest("interface Test { record<USVString, %s> toJSON(); };" % type, False, - "record<USVString, %s> should be a JSON type" % type) + doTest( + "interface Test { %s toJSON(); };" % type, + False, + "%s should be a JSON type" % type, + ) + + doTest( + "interface Test { sequence<%s> toJSON(); };" % type, + False, + "sequence<%s> should be a JSON type" % type, + ) + + doTest( + "dictionary Foo { %s foo; }; " "interface Test { Foo toJSON(); }; " % type, + False, + "dictionary containing only JSON type (%s) should be a JSON type" % type, + ) + + doTest( + "dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " + "interface Test { Bar toJSON(); }; " % type, + False, + "dictionary whose ancestors only contain JSON types should be a JSON type", + ) + + doTest( + "dictionary Foo { any foo; }; dictionary Bar : Foo { %s bar; };" + "interface Test { Bar toJSON(); };" % type, + True, + "dictionary whose ancestors contain non-JSON types should not be a JSON type", + ) + + doTest( + "interface Test { record<DOMString, %s> toJSON(); };" % type, + False, + "record<DOMString, %s> should be a JSON type" % type, + ) + + doTest( + "interface Test { record<ByteString, %s> toJSON(); };" % type, + False, + "record<ByteString, %s> should be a JSON type" % type, + ) + + doTest( + "interface Test { record<UTF8String, %s> toJSON(); };" % type, + False, + "record<UTF8String, %s> should be a JSON type" % type, + ) + + doTest( + "interface Test { record<USVString, %s> toJSON(); };" % type, + False, + "record<USVString, %s> should be a JSON type" % type, + ) otherUnionType = "Foo" if type != "object" else "long" - doTest("interface Foo { object toJSON(); };" - "interface Test { (%s or %s) toJSON(); };" % (otherUnionType, type), False, - "union containing only JSON types (%s or %s) should be a JSON type" %(otherUnionType, type)) - - doTest("interface test { %s? toJSON(); };" % type, False, - "Nullable type (%s) should be a JSON type" % type) - - doTest("interface Foo : InterfaceWithoutToJSON { %s toJSON(); };" - "interface Test { Foo toJSON(); };" % type, False, - "interface with toJSON should be a JSON type") - - doTest("interface Foo : InterfaceWithToJSON { };" - "interface Test { Foo toJSON(); };", False, - "inherited interface with toJSON should be a JSON type") + doTest( + "interface Foo { object toJSON(); };" + "interface Test { (%s or %s) toJSON(); };" % (otherUnionType, type), + False, + "union containing only JSON types (%s or %s) should be a JSON type" + % (otherUnionType, type), + ) + + doTest( + "interface test { %s? toJSON(); };" % type, + False, + "Nullable type (%s) should be a JSON type" % type, + ) + + doTest( + "interface Foo : InterfaceWithoutToJSON { %s toJSON(); };" + "interface Test { Foo toJSON(); };" % type, + False, + "interface with toJSON should be a JSON type", + ) + + doTest( + "interface Foo : InterfaceWithToJSON { };" "interface Test { Foo toJSON(); };", + False, + "inherited interface with toJSON should be a JSON type", + ) for type in nonJsonTypes: - doTest("interface Test { %s toJSON(); };" % type, True, - "%s should not be a JSON type" % type) - - doTest("interface Test { sequence<%s> toJSON(); };" % type, True, - "sequence<%s> should not be a JSON type" % type) - - doTest("dictionary Foo { %s foo; }; " - "interface Test { Foo toJSON(); }; " % type, True, - "Dictionary containing a non-JSON type (%s) should not be a JSON type" % type) - - doTest("dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " - "interface Test { Bar toJSON(); }; " % type, True, - "dictionary whose ancestors only contain non-JSON types should not be a JSON type") - - doTest("interface Test { record<DOMString, %s> toJSON(); };" % type, True, - "record<DOMString, %s> should not be a JSON type" % type) - - doTest("interface Test { record<ByteString, %s> toJSON(); };" % type, True, - "record<ByteString, %s> should not be a JSON type" % type) - - doTest("interface Test { record<USVString, %s> toJSON(); };" % type, True, - "record<USVString, %s> should not be a JSON type" % type) + doTest( + "interface Test { %s toJSON(); };" % type, + True, + "%s should not be a JSON type" % type, + ) + + doTest( + "interface Test { sequence<%s> toJSON(); };" % type, + True, + "sequence<%s> should not be a JSON type" % type, + ) + + doTest( + "dictionary Foo { %s foo; }; " "interface Test { Foo toJSON(); }; " % type, + True, + "Dictionary containing a non-JSON type (%s) should not be a JSON type" + % type, + ) + + doTest( + "dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " + "interface Test { Bar toJSON(); }; " % type, + True, + "dictionary whose ancestors only contain non-JSON types should not be a JSON type", + ) + + doTest( + "interface Test { record<DOMString, %s> toJSON(); };" % type, + True, + "record<DOMString, %s> should not be a JSON type" % type, + ) + + doTest( + "interface Test { record<ByteString, %s> toJSON(); };" % type, + True, + "record<ByteString, %s> should not be a JSON type" % type, + ) + + doTest( + "interface Test { record<USVString, %s> toJSON(); };" % type, + True, + "record<USVString, %s> should not be a JSON type" % type, + ) if type != "any": - doTest("interface Foo { object toJSON(); }; " - "interface Test { (Foo or %s) toJSON(); };" % type, True, - "union containing a non-JSON type (%s) should not be a JSON type" % type) - - doTest("interface test { %s? toJSON(); };" % type, True, - "Nullable type (%s) should not be a JSON type" % type) - - doTest("dictionary Foo { long foo; any bar; };" - "interface Test { Foo toJSON(); };", True, - "dictionary containing a non-JSON type should not be a JSON type") - - doTest("interface Foo : InterfaceWithoutToJSON { }; " - "interface Test { Foo toJSON(); };", True, - "interface without toJSON should not be a JSON type") + doTest( + "interface Foo { object toJSON(); }; " + "interface Test { (Foo or %s) toJSON(); };" % type, + True, + "union containing a non-JSON type (%s) should not be a JSON type" + % type, + ) + + doTest( + "interface test { %s? toJSON(); };" % type, + True, + "Nullable type (%s) should not be a JSON type" % type, + ) + + doTest( + "dictionary Foo { long foo; any bar; };" "interface Test { Foo toJSON(); };", + True, + "dictionary containing a non-JSON type should not be a JSON type", + ) + + doTest( + "interface Foo : InterfaceWithoutToJSON { }; " + "interface Test { Foo toJSON(); };", + True, + "interface without toJSON should not be a JSON type", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py b/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py index 7a0bde8a6dc..7becfdca1f3 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py @@ -1,14 +1,17 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ [TreatNonCallableAsNull] callback Function = any(any... arguments); interface TestTreatNonCallableAsNull1 { attribute Function? onfoo; attribute Function onbar; }; - """) + """ + ) results = parser.finish() @@ -22,13 +25,15 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ callback Function = any(any... arguments); interface TestTreatNonCallableAsNull2 { [TreatNonCallableAsNull] attribute Function onfoo; }; - """) + """ + ) results = parser.finish() except: @@ -40,14 +45,16 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ callback Function = any(any... arguments); [TreatNonCallableAsNull] interface TestTreatNonCallableAsNull3 { attribute Function onfoo; }; - """) + """ + ) results = parser.finish() except: @@ -59,10 +66,12 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" - [TreatNonCallableAsNull, TreatNonObjectAsNull] + parser.parse( + """ + [TreatNonCallableAsNull, LegacyTreatNonObjectAsNull] callback Function = any(any... arguments); - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_typedef.py b/components/script/dom/bindings/codegen/parser/tests/test_typedef.py index d98088380ba..c19d064efff 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_typedef.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_typedef.py @@ -1,5 +1,6 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ typedef long mylong; typedef long? mynullablelong; interface Foo { @@ -8,22 +9,28 @@ def WebIDLTest(parser, harness): undefined bar(optional mynullablelong arg = null); undefined baz(mylong arg); }; - """) + """ + ) results = parser.finish() - harness.check(results[2].members[1].signatures()[0][1][0].type.name, "LongOrNull", - "Should expand typedefs") + harness.check( + results[2].members[1].signatures()[0][1][0].type.name, + "LongOrNull", + "Should expand typedefs", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef long? mynullablelong; interface Foo { undefined foo(mynullablelong? Y); }; - """) + """ + ) results = parser.finish() except: threw = True @@ -33,12 +40,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ typedef long? mynullablelong; interface Foo { const mynullablelong? X = 5; }; - """) + """ + ) results = parser.finish() except: threw = True @@ -48,29 +57,38 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Foo { const mynullablelong? X = 5; }; typedef long? mynullablelong; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown on nullable inside nullable const typedef " - "after interface.") + harness.ok( + threw, + "Should have thrown on nullable inside nullable const typedef " + "after interface.", + ) parser = parser.reset() - parser.parse(""" + parser.parse( + """ interface Foo { const mylong X = 5; }; typedef long mylong; - """) + """ + ) results = parser.finish() - harness.check(results[0].members[0].type.name, "Long", - "Should expand typedefs that come before interface") + harness.check( + results[0].members[0].type.name, + "Long", + "Should expand typedefs that come before interface", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py b/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py index 0ea38ce437b..2aab3a8a91f 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py @@ -5,12 +5,15 @@ def WebIDLTest(parser, harness): """ typedef long foo; typedef long foo; - """) + """ + ) results = parser.finish() except Exception as e: exception = e harness.ok(exception, "Should have thrown.") - harness.ok("Multiple unresolvable definitions of identifier 'foo'" in str(exception), - "Should have a sane exception message") + harness.ok( + "Multiple unresolvable definitions of identifier 'foo'" in str(exception), + "Should have a sane exception message", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_undefined.py b/components/script/dom/bindings/codegen/parser/tests/test_undefined.py new file mode 100644 index 00000000000..4731ee1bcd7 --- /dev/null +++ b/components/script/dom/bindings/codegen/parser/tests/test_undefined.py @@ -0,0 +1,246 @@ +import WebIDL + + +def WebIDLTest(parser, harness): + try: + parser.parse( + """ + dictionary Dict { + undefined undefinedMember; + double bar; + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "undefined must not be used as the type of a dictionary member") + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + dictionary Dict { + (undefined or double) undefinedMemberOfUnionInDict; + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of a dictionary member, " + "whether directly or in a union", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + double bar(undefined foo); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a regular operation)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + getter double(undefined name); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a getter)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + setter undefined(DOMString name, undefined value); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a setter)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + deleter undefined (undefined name); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a deleter)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + constructor (undefined foo); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a constructor)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + callback Callback = undefined (undefined foo); + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a callback)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + async iterable(undefined name); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of an async iterable " + "iterator)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + static double bar(undefined foo); + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined must not be used as the type of an argument in any " + "circumstance (so not as the argument of a static operation)", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + const undefined FOO = undefined; + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined is not a valid type for a constant", + ) + + parser = parser.reset() + threw = False + + try: + parser.parse( + """ + interface Foo { + const any FOO = undefined; + }; + """ + ) + results = parser.finish() + except: + threw = True + + harness.ok( + threw, + "undefined is not a valid value for a constant", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py b/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py index d28cc1ec052..b024d317492 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py @@ -10,18 +10,21 @@ def WebIDLTest(parser, harness): interface Baz : Bar { getter long(DOMString name); }; - """); - results = parser.finish(); + """ + ) + results = parser.finish() harness.check(len(results), 3, "Should have three interfaces") parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [LegacyUnenumerableNamedProperties] interface NoNamedGetter { }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -31,12 +34,14 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [LegacyUnenumerableNamedProperties=Foo] interface ShouldNotHaveArg { getter long(DOMString name); }; - """) + """ + ) results = parser.finish() except Exception as x: @@ -46,7 +51,8 @@ def WebIDLTest(parser, harness): parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ [LegacyUnenumerableNamedProperties] interface Foo { getter long(DOMString name); @@ -56,7 +62,8 @@ def WebIDLTest(parser, harness): interface Baz : Bar { getter long(DOMString name); }; - """) + """ + ) results = parser.finish() except Exception as x: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py b/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py index e72548f637f..500d123ddb2 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py @@ -1,253 +1,311 @@ def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface Child : Parent { }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should be able to inherit from an interface with " - "[Unforgeable] properties.") + harness.check( + len(results), + 2, + "Should be able to inherit from an interface with " + "[LegacyUnforgeable] properties.", + ) - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ interface Child : Parent { const short foo = 10; }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should be able to inherit from an interface with " - "[Unforgeable] properties even if we have a constant with " - "the same name.") + harness.check( + len(results), + 2, + "Should be able to inherit from an interface with " + "[LegacyUnforgeable] properties even if we have a constant with " + "the same name.", + ) - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ interface Child : Parent { static attribute short foo; }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should be able to inherit from an interface with " - "[Unforgeable] properties even if we have a static attribute " - "with the same name.") + harness.check( + len(results), + 2, + "Should be able to inherit from an interface with " + "[LegacyUnforgeable] properties even if we have a static attribute " + "with the same name.", + ) - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ interface Child : Parent { static undefined foo(); }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 2, - "Should be able to inherit from an interface with " - "[Unforgeable] properties even if we have a static operation " - "with the same name.") + harness.check( + len(results), + 2, + "Should be able to inherit from an interface with " + "[LegacyUnforgeable] properties even if we have a static operation " + "with the same name.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { undefined foo(); }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown when shadowing unforgeable attribute on " - "parent with operation.") + harness.ok( + threw, + "Should have thrown when shadowing unforgeable attribute on " + "parent with operation.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { undefined foo(); }; interface Parent { - [Unforgeable] undefined foo(); + [LegacyUnforgeable] undefined foo(); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown when shadowing unforgeable operation on " - "parent with operation.") + harness.ok( + threw, + "Should have thrown when shadowing unforgeable operation on " + "parent with operation.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { attribute short foo; }; interface Parent { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, - "Should have thrown when shadowing unforgeable attribute on " - "parent with attribute.") + harness.ok( + threw, + "Should have thrown when shadowing unforgeable attribute on " + "parent with attribute.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { attribute short foo; }; interface Parent { - [Unforgeable] undefined foo(); + [LegacyUnforgeable] undefined foo(); }; - """) + """ + ) results = parser.finish() except Exception as x: threw = True - harness.ok(threw, - "Should have thrown when shadowing unforgeable operation on " - "parent with attribute.") + harness.ok( + threw, + "Should have thrown when shadowing unforgeable operation on " + "parent with attribute.", + ) - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ interface Child : Parent { }; interface Parent {}; interface mixin Mixin { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; Parent includes Mixin; - """) + """ + ) results = parser.finish() - harness.check(len(results), 4, - "Should be able to inherit from an interface with a " - "mixin with [Unforgeable] properties.") + harness.check( + len(results), + 4, + "Should be able to inherit from an interface with a " + "mixin with [LegacyUnforgeable] properties.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { undefined foo(); }; interface Parent {}; interface mixin Mixin { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; Parent includes Mixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown when shadowing unforgeable attribute " - "of parent's consequential interface.") + harness.ok( + threw, + "Should have thrown when shadowing unforgeable attribute " + "of parent's consequential interface.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { }; interface Parent : GrandParent {}; interface GrandParent {}; interface mixin Mixin { - [Unforgeable] readonly attribute long foo; + [LegacyUnforgeable] readonly attribute long foo; }; GrandParent includes Mixin; interface mixin ChildMixin { undefined foo(); }; Child includes ChildMixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown when our consequential interface shadows unforgeable attribute " - "of ancestor's consequential interface.") + harness.ok( + threw, + "Should have thrown when our consequential interface shadows unforgeable attribute " + "of ancestor's consequential interface.", + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface Child : Parent { }; interface Parent : GrandParent {}; interface GrandParent {}; interface mixin Mixin { - [Unforgeable] undefined foo(); + [LegacyUnforgeable] undefined foo(); }; GrandParent includes Mixin; interface mixin ChildMixin { undefined foo(); }; Child includes ChildMixin; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown when our consequential interface shadows unforgeable operation " - "of ancestor's consequential interface.") + harness.ok( + threw, + "Should have thrown when our consequential interface shadows unforgeable operation " + "of ancestor's consequential interface.", + ) - parser = parser.reset(); - parser.parse(""" + parser = parser.reset() + parser.parse( + """ interface iface { - [Unforgeable] attribute long foo; + [LegacyUnforgeable] attribute long foo; }; - """) + """ + ) results = parser.finish() - harness.check(len(results), 1, - "Should allow writable [Unforgeable] attribute.") + harness.check( + len(results), 1, "Should allow writable [LegacyUnforgeable] attribute." + ) - parser = parser.reset(); + parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface iface { - [Unforgeable] static readonly attribute long foo; + [LegacyUnforgeable] static readonly attribute long foo; }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, "Should have thrown for static [Unforgeable] attribute.") + harness.ok(threw, "Should have thrown for static [LegacyUnforgeable] attribute.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union.py b/components/script/dom/bindings/codegen/parser/tests/test_union.py index 469208b264d..7fc1236d54e 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_union.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_union.py @@ -3,12 +3,15 @@ import itertools import string # We'd like to use itertools.chain but it's 2.6 or higher. + + def chain(*iterables): # chain('ABC', 'DEF') --> A B C D E F for it in iterables: for element in it: yield element + # We'd like to use itertools.combinations but it's 2.6 or higher. def combinations(iterable, r): # combinations('ABCD', 2) --> AB AC AD BC BD CD @@ -26,10 +29,11 @@ def combinations(iterable, r): else: return indices[i] += 1 - for j in range(i+1, r): - indices[j] = indices[j-1] + 1 + for j in range(i + 1, r): + indices[j] = indices[j - 1] + 1 yield tuple(pool[i] for i in indices) + # We'd like to use itertools.combinations_with_replacement but it's 2.7 or # higher. def combinations_with_replacement(iterable, r): @@ -49,27 +53,30 @@ def combinations_with_replacement(iterable, r): indices[i:] = [indices[i] + 1] * (r - i) yield tuple(pool[i] for i in indices) + def WebIDLTest(parser, harness): - types = ["float", - "double", - "short", - "unsigned short", - "long", - "unsigned long", - "long long", - "unsigned long long", - "boolean", - "byte", - "octet", - "DOMString", - "ByteString", - "USVString", - #"sequence<float>", - "object", - "ArrayBuffer", - #"Date", - "TestInterface1", - "TestInterface2"] + types = [ + "float", + "double", + "short", + "unsigned short", + "long", + "unsigned long", + "long long", + "unsigned long long", + "boolean", + "byte", + "octet", + "DOMString", + "ByteString", + "USVString", + # "sequence<float>", + "object", + "ArrayBuffer", + # "Date", + "TestInterface1", + "TestInterface2", + ] testPre = """ interface TestInterface1 { @@ -78,13 +85,18 @@ def WebIDLTest(parser, harness): }; """ - interface = testPre + """ + interface = ( + testPre + + """ interface PrepareForTest { """ + ) for (i, type) in enumerate(types): - interface += string.Template(""" + interface += string.Template( + """ readonly attribute ${type} attr${i}; - """).substitute(i=i, type=type) + """ + ).substitute(i=i, type=type) interface += """ }; """ @@ -98,8 +110,10 @@ def WebIDLTest(parser, harness): def typesAreDistinguishable(t): return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) + def typesAreNotDistinguishable(t): return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) + def unionTypeName(t): if len(t) > 2: t[0:2] = [unionTypeName(t[0:2])] @@ -118,29 +132,40 @@ def WebIDLTest(parser, harness): # as a string and the parsed IDL type. def invalidUnionWithUnion(typeCombinations): for c in typeCombinations: - if (typesAreNotDistinguishable((c[0][1], c[1][1])) and - typesAreDistinguishable((c[1][1], c[2][1])) and - typesAreDistinguishable((c[0][1], c[2][1]))): + if ( + typesAreNotDistinguishable((c[0][1], c[1][1])) + and typesAreDistinguishable((c[1][1], c[2][1])) + and typesAreDistinguishable((c[0][1], c[2][1])) + ): yield unionTypeName([t[0] for t in c]) # Create a list of tuples containing the name of the type as a string and # the parsed IDL type. types = zip(types, (a.type for a in iface.members)) - validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable), - unionTypes(combinations(types, 3), typesAreDistinguishable)) - invalidUnionTypes = chain(unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable), - invalidUnionWithUnion(combinations(types, 3))) - interface = testPre + """ + validUnionTypes = chain( + unionTypes(combinations(types, 2), typesAreDistinguishable), + unionTypes(combinations(types, 3), typesAreDistinguishable), + ) + invalidUnionTypes = chain( + unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable), + invalidUnionWithUnion(combinations(types, 3)), + ) + interface = ( + testPre + + """ interface TestUnion { """ + ) for (i, type) in enumerate(validUnionTypes): - interface += string.Template(""" + interface += string.Template( + """ undefined method${i}(${type} arg); ${type} returnMethod${i}(); attribute ${type} attr${i}; undefined optionalMethod${i}(${type}? arg); - """).substitute(i=i, type=type) + """ + ).substitute(i=i, type=type) interface += """ }; """ @@ -150,11 +175,16 @@ def WebIDLTest(parser, harness): parser = parser.reset() for invalid in invalidUnionTypes: - interface = testPre + string.Template(""" + interface = ( + testPre + + string.Template( + """ interface TestUnion { undefined method(${type} arg); }; - """).substitute(type=invalid) + """ + ).substitute(type=invalid) + ) threw = False try: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union_any.py b/components/script/dom/bindings/codegen/parser/tests/test_union_any.py index 3eb67648d56..caba44b55f9 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_union_any.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_union_any.py @@ -1,11 +1,13 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface AnyNotInUnion { undefined foo((any or DOMString) arg); }; - """) + """ + ) results = parser.finish() except: diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py b/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py index 71da4349e6e..d15ed4cfb54 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py @@ -1,53 +1,60 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface OneNullableInUnion { undefined foo((object? or DOMString?) arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Two nullable member types of a union should have thrown.") + harness.ok(threw, "Two nullable member types of a union should have thrown.") parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface NullableInNullableUnion { undefined foo((object? or DOMString)? arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "A nullable union type with a nullable member type should have " - "thrown.") + harness.ok( + threw, + "A nullable union type with a nullable member type should have " "thrown.", + ) parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface NullableInUnionNullableUnionHelper { }; interface NullableInUnionNullableUnion { undefined foo(((object? or DOMString) or NullableInUnionNullableUnionHelper)? arg); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "A nullable union type with a nullable member type should have " - "thrown.") + harness.ok( + threw, + "A nullable union type with a nullable member type should have " "thrown.", + ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py b/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py index 3a1369abd02..effede391cb 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py @@ -2,23 +2,27 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ interface TestUSVString { attribute USVString svs; }; - """) + """ + ) - results = parser.finish(); + results = parser.finish() harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), - "Should be an IDLInterface") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") iface = results[0] - harness.check(iface.identifier.QName(), "::TestUSVString", - "Interface has the right QName") - harness.check(iface.identifier.name, "TestUSVString", - "Interface has the right name") + harness.check( + iface.identifier.QName(), "::TestUSVString", "Interface has the right QName" + ) + harness.check( + iface.identifier.name, "TestUSVString", "Interface has the right name" + ) harness.check(iface.parent, None, "Interface has no parent") members = iface.members @@ -26,11 +30,11 @@ def WebIDLTest(parser, harness): attr = members[0] harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check(attr.identifier.QName(), "::TestUSVString::svs", - "Attr has correct QName") + harness.check( + attr.identifier.QName(), "::TestUSVString::svs", "Attr has correct QName" + ) harness.check(attr.identifier.name, "svs", "Attr has correct name") - harness.check(str(attr.type), "USVString", - "Attr type is the correct name") + harness.check(str(attr.type), "USVString", "Attr type is the correct name") harness.ok(attr.type.isUSVString(), "Should be USVString type") harness.ok(attr.type.isString(), "Should be String collective type") harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py b/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py index d9a78db2043..3fd3dccd37a 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py @@ -1,9 +1,12 @@ import WebIDL + def WebIDLTest(parser, harness): - parser.parse(""" + parser.parse( + """ callback TestVariadicCallback = any(any... arguments); - """) + """ + ) results = parser.finish() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py b/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py index e36eff8b476..06ce09d8236 100644 --- a/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py +++ b/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py @@ -1,61 +1,72 @@ def WebIDLTest(parser, harness): threw = False try: - parser.parse(""" + parser.parse( + """ interface VariadicConstraints1 { undefined foo(byte... arg1, byte arg2); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown on variadic argument followed by required " - "argument.") + harness.ok( + threw, + "Should have thrown on variadic argument followed by required " "argument.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface VariadicConstraints2 { undefined foo(byte... arg1, optional byte arg2); }; - """) - results = parser.finish(); + """ + ) + results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown on variadic argument followed by optional " - "argument.") + harness.ok( + threw, + "Should have thrown on variadic argument followed by optional " "argument.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface VariadicConstraints3 { undefined foo(optional byte... arg1); }; - """) + """ + ) results = parser.finish() except: threw = True - harness.ok(threw, - "Should have thrown on variadic argument explicitly flagged as " - "optional.") + harness.ok( + threw, + "Should have thrown on variadic argument explicitly flagged as " "optional.", + ) parser = parser.reset() threw = False try: - parser.parse(""" + parser.parse( + """ interface VariadicConstraints4 { undefined foo(byte... arg1 = 0); }; - """) + """ + ) results = parser.finish() except: threw = True |