aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/parser/WebIDL.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen/parser/WebIDL.py')
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py5904
1 files changed, 3642 insertions, 2262 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()