aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/WebIDL/WebIDL.py
diff options
context:
space:
mode:
authorNgo Iok Ui (Wu Yu Wei) <yuweiwu@pm.me>2024-06-15 13:22:42 +0900
committerGitHub <noreply@github.com>2024-06-15 04:22:42 +0000
commit8eed3b442b214f678b80dbcc7dca07eeaa1e26ff (patch)
treef8a232e86616e8e5fd234e7bbb32bed4ff7077f2 /third_party/WebIDL/WebIDL.py
parent19067366df28c9131dcbc436bc96a27e64e0a194 (diff)
downloadservo-8eed3b442b214f678b80dbcc7dca07eeaa1e26ff.tar.gz
servo-8eed3b442b214f678b80dbcc7dca07eeaa1e26ff.zip
Update WebIDL.py (#32495)
* Update WebIDL.py * Update WebIDL.py * Add builtin-array.patch * Fix CodegenRust.py and Configuration.py * Fix missing downcasts * mach fmt * Update check and comment to explain why we need this check * Update Global of DissimilarOriginWindow.webidl
Diffstat (limited to 'third_party/WebIDL/WebIDL.py')
-rw-r--r--third_party/WebIDL/WebIDL.py660
1 files changed, 505 insertions, 155 deletions
diff --git a/third_party/WebIDL/WebIDL.py b/third_party/WebIDL/WebIDL.py
index 2d5c56f1086..482aa13bc2f 100644
--- a/third_party/WebIDL/WebIDL.py
+++ b/third_party/WebIDL/WebIDL.py
@@ -43,25 +43,22 @@ def parseInt(literal):
return value * sign
-def enum(*names, **kw):
- class Foo(object):
- attrs = OrderedDict()
+# This is surprisingly faster than using the enum.IntEnum type (which doesn't
+# support 'base' anyway)
+def enum(*names, base=None):
+ if base is not None:
+ names = base.attrs + names
- 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
+ class CustomEnumType(object):
+ attrs = names
def __setattr__(self, name, value): # this makes it read-only
raise NotImplementedError
- if "base" not in kw:
- return Foo(names)
- return Foo(chain(kw["base"].attrs.keys(), names))
+ for v, k in enumerate(names):
+ setattr(CustomEnumType, k, v)
+
+ return CustomEnumType()
class WebIDLError(Exception):
@@ -85,13 +82,10 @@ class Location(object):
self._lineno = lineno
self._lexpos = lexpos
self._lexdata = lexer.lexdata
- self._file = filename if filename else "<unknown>"
+ self.filename = filename if filename else "<unknown>"
def __eq__(self, other):
- return self._lexpos == other._lexpos and self._file == other._file
-
- def filename(self):
- return self._file
+ return self._lexpos == other._lexpos and self.filename == other.filename
def resolve(self):
if self._line:
@@ -110,7 +104,7 @@ class Location(object):
def get(self):
self.resolve()
- return "%s line %s:%s" % (self._file, self._lineno, self._colno)
+ return "%s line %s:%s" % (self.filename, self._lineno, self._colno)
def _pointerline(self):
return " " * self._colno + "^"
@@ -118,7 +112,7 @@ class Location(object):
def __str__(self):
self.resolve()
return "%s line %s:%s\n%s\n%s" % (
- self._file,
+ self.filename,
self._lineno,
self._colno,
self._line,
@@ -127,15 +121,15 @@ class Location(object):
class BuiltinLocation(object):
+ __slots__ = "msg", "filename"
+
def __init__(self, text):
self.msg = text + "\n"
+ self.filename = "<builtin>"
def __eq__(self, other):
return isinstance(other, BuiltinLocation) and self.msg == other.msg
- def filename(self):
- return "<builtin>"
-
def resolve(self):
pass
@@ -150,12 +144,12 @@ class BuiltinLocation(object):
class IDLObject(object):
+ __slots__ = "location", "userData", "filename"
+
def __init__(self, location):
self.location = location
- self.userData = dict()
-
- def filename(self):
- return self.location.filename()
+ self.userData = {}
+ self.filename = location and location.filename
def isInterface(self):
return False
@@ -220,8 +214,8 @@ class IDLObject(object):
visited.add(self)
deps = set()
- if self.filename() != "<builtin>":
- deps.add(self.filename())
+ if self.filename != "<builtin>":
+ deps.add(self.filename)
for d in self._getDependentObjects():
deps.update(d.getDeps(visited))
@@ -230,6 +224,8 @@ class IDLObject(object):
class IDLScope(IDLObject):
+ __slots__ = "parentScope", "_name", "_dict", "globalNames", "globalNameMapping"
+
def __init__(self, location, parentScope, identifier):
IDLObject.__init__(self, location)
@@ -283,6 +279,9 @@ class IDLScope(IDLObject):
self._dict[identifier.name] = replacement
return
+ self.addNewIdentifier(identifier, object)
+
+ def addNewIdentifier(self, identifier, object):
assert object
self._dict[identifier.name] = object
@@ -323,6 +322,9 @@ class IDLScope(IDLObject):
return originalObject.addOverload(newObject)
# Default to throwing, derived classes can override.
+ raise self.createIdentifierConflictError(identifier, originalObject, newObject)
+
+ def createIdentifierConflictError(self, identifier, originalObject, newObject):
conflictdesc = "\n\t%s at %s\n\t%s at %s" % (
originalObject,
originalObject.location,
@@ -330,7 +332,7 @@ class IDLScope(IDLObject):
newObject.location,
)
- raise WebIDLError(
+ return WebIDLError(
"Multiple unresolvable definitions of identifier '%s' in scope '%s'%s"
% (identifier.name, str(self), conflictdesc),
[],
@@ -353,6 +355,8 @@ class IDLScope(IDLObject):
class IDLIdentifier(IDLObject):
+ __slots__ = "name", "scope"
+
def __init__(self, location, scope, name):
IDLObject.__init__(self, location)
@@ -377,12 +381,14 @@ class IDLIdentifier(IDLObject):
class IDLUnresolvedIdentifier(IDLObject):
+ __slots__ = ("name",)
+
def __init__(
self, location, name, allowDoubleUnderscore=False, allowForbidden=False
):
IDLObject.__init__(self, location)
- assert len(name) > 0
+ assert name
if name == "__noSuchMethod__":
raise WebIDLError("__noSuchMethod__ is deprecated", [location])
@@ -421,6 +427,7 @@ class IDLUnresolvedIdentifier(IDLObject):
class IDLObjectWithIdentifier(IDLObject):
+ # no slots, incompatible with multiple inheritance
def __init__(self, location, parentScope, identifier):
IDLObject.__init__(self, location)
@@ -438,6 +445,8 @@ class IDLObjectWithIdentifier(IDLObject):
class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
+ __slots__ = ()
+
def __init__(self, location, parentScope, identifier):
assert isinstance(identifier, IDLUnresolvedIdentifier)
@@ -446,6 +455,8 @@ class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
+ __slots__ = ()
+
def __init__(self, location, identifier):
assert isinstance(identifier, IDLUnresolvedIdentifier)
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
@@ -453,7 +464,7 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
def finish(self, scope):
try:
scope._lookupIdentifier(self.identifier)
- except:
+ except Exception:
raise WebIDLError(
"Unresolved type '%s'." % self.identifier, [self.location]
)
@@ -463,6 +474,7 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
class IDLExposureMixins:
+ # no slots, incompatible with multiple inheritance
def __init__(self, location):
# _exposureGlobalNames are the global names listed in our [Exposed]
# extended attribute. exposureSet is the exposure set as defined in the
@@ -492,16 +504,15 @@ class IDLExposureMixins:
# they don't include any globals, and we don't really want to go through
# and add global interfaces and [Exposed] annotations to all those
# tests.
- if len(scope.globalNames) != 0:
- 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],
+ if len(scope.globalNames) != 0 and len(self._exposureGlobalNames) == 0:
+ 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)
@@ -546,6 +557,8 @@ class IDLExposureMixins:
class IDLExternalInterface(IDLObjectWithIdentifier):
+ __slots__ = ("parent",)
+
def __init__(self, location, parentScope, identifier):
assert isinstance(identifier, IDLUnresolvedIdentifier)
assert isinstance(parentScope, IDLScope)
@@ -596,6 +609,8 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
class IDLPartialDictionary(IDLObject):
+ __slots__ = "identifier", "members", "_nonPartialDictionary", "_finished"
+
def __init__(self, location, name, members, nonPartialDictionary):
assert isinstance(name, IDLUnresolvedIdentifier)
@@ -624,6 +639,15 @@ class IDLPartialDictionary(IDLObject):
class IDLPartialInterfaceOrNamespace(IDLObject):
+ __slots__ = (
+ "identifier",
+ "members",
+ "propagatedExtendedAttrs",
+ "_haveSecureContextExtendedAttribute",
+ "_nonPartialInterfaceOrNamespace",
+ "_finished",
+ )
+
def __init__(self, location, name, members, nonPartialInterfaceOrNamespace):
assert isinstance(name, IDLUnresolvedIdentifier)
@@ -727,7 +751,26 @@ def globalNameSetToExposureSet(globalScope, nameSet, exposureSet):
exposureSet.update(globalScope.globalNameMapping[name])
+# Because WebIDL allows static and regular operations with the same identifier
+# we use a special class to be able to store them both in the scope for the
+# same identifier.
+class IDLOperations:
+ __slots__ = "static", "regular"
+
+ def __init__(self, static=None, regular=None):
+ self.static = static
+ self.regular = regular
+
+
class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMixins):
+ __slots__ = (
+ "_finished",
+ "members",
+ "_partials",
+ "_extendedAttrDict",
+ "_isKnownNonPartial",
+ )
+
def __init__(self, location, parentScope, name):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
@@ -756,15 +799,66 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix
self.addExtendedAttributes(partial.propagatedExtendedAttrs)
self.members.extend(partial.members)
+ def addNewIdentifier(self, identifier, object):
+ if isinstance(object, IDLMethod):
+ if object.isStatic():
+ object = IDLOperations(static=object)
+ else:
+ object = IDLOperations(regular=object)
+
+ IDLScope.addNewIdentifier(self, identifier, object)
+
def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
assert isinstance(scope, IDLScope)
- assert isinstance(originalObject, IDLInterfaceMember)
assert isinstance(newObject, IDLInterfaceMember)
+ # The identifier of a regular operation or static operation must not be
+ # the same as the identifier of a constant or attribute.
+ if isinstance(newObject, IDLMethod) != isinstance(
+ originalObject, IDLOperations
+ ):
+ if isinstance(originalObject, IDLOperations):
+ if originalObject.regular is not None:
+ originalObject = originalObject.regular
+ else:
+ assert originalObject.static is not None
+ originalObject = originalObject.static
+
+ raise self.createIdentifierConflictError(
+ identifier, originalObject, newObject
+ )
+
+ if isinstance(newObject, IDLMethod):
+ originalOperations = originalObject
+ if newObject.isStatic():
+ if originalOperations.static is None:
+ originalOperations.static = newObject
+ return originalOperations
+
+ originalObject = originalOperations.static
+ else:
+ if originalOperations.regular is None:
+ originalOperations.regular = newObject
+ return originalOperations
+
+ originalObject = originalOperations.regular
+
+ assert isinstance(originalObject, IDLMethod)
+ else:
+ assert isinstance(originalObject, IDLInterfaceMember)
+
retval = IDLScope.resolveIdentifierConflict(
self, scope, identifier, originalObject, newObject
)
+ if isinstance(newObject, IDLMethod):
+ if newObject.isStatic():
+ originalOperations.static = retval
+ else:
+ originalOperations.regular = retval
+
+ retval = originalOperations
+
# Might be a ctor, which isn't in self.members
if newObject in self.members:
self.members.remove(newObject)
@@ -842,10 +936,12 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix
class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
+ __slots__ = ("actualExposureGlobalNames",)
+
def __init__(self, location, parentScope, name, members, isKnownNonPartial):
self.actualExposureGlobalNames = set()
- assert isKnownNonPartial or len(members) == 0
+ assert isKnownNonPartial or not members
IDLInterfaceOrInterfaceMixinOrNamespace.__init__(
self, location, parentScope, name
)
@@ -881,7 +977,6 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
def validate(self):
for member in self.members:
-
if member.isAttr():
if member.inherit:
raise WebIDLError(
@@ -947,27 +1042,43 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
+ __slots__ = (
+ "parent",
+ "_callback",
+ "maplikeOrSetlikeOrIterable",
+ "legacyFactoryFunctions",
+ "legacyWindowAliases",
+ "includedMixins",
+ "interfacesBasedOnSelf",
+ "_hasChildInterfaces",
+ "_isOnGlobalProtoChain",
+ "totalMembersInSlots",
+ "_ownMembersInSlots",
+ "iterableInterface",
+ "asyncIterableInterface",
+ "hasCrossOriginMembers",
+ "hasDescendantWithCrossOriginMembers",
+ )
+
def __init__(self, location, parentScope, name, parent, members, isKnownNonPartial):
assert isKnownNonPartial or not parent
- assert isKnownNonPartial or len(members) == 0
+ assert isKnownNonPartial or not members
self.parent = None
self._callback = False
self.maplikeOrSetlikeOrIterable = None
- # namedConstructors needs deterministic ordering because bindings code
- # outputs the constructs in the order that namedConstructors enumerates
+ # legacyFactoryFunctions needs deterministic ordering because bindings code
+ # outputs the constructs in the order that legacyFactoryFunctions enumerates
# them.
- self.legacyFactoryFunctions = list()
+ self.legacyFactoryFunctions = []
self.legacyWindowAliases = []
self.includedMixins = set()
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
# self, including self itself.
# Used for distinguishability checking.
- self.interfacesBasedOnSelf = set([self])
+ self.interfacesBasedOnSelf = {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.
@@ -995,8 +1106,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
self.location, "constructor", allowForbidden=True
)
try:
- return self._lookupIdentifier(identifier)
- except:
+ return self._lookupIdentifier(identifier).static
+ except Exception:
return None
def isIterable(self):
@@ -1234,7 +1345,11 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
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:
+ if mixinMember.identifier.name == member.identifier.name and (
+ not mixinMember.isMethod()
+ or not member.isMethod()
+ or mixinMember.isStatic() == member.isStatic()
+ ):
raise WebIDLError(
"Multiple definitions of %s on %s coming from 'includes' statements"
% (member.identifier.name, self),
@@ -1733,14 +1848,13 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
def hasInterfaceObject(self):
if self.isCallback():
return self.hasConstants()
- return not hasattr(self, "_noInterfaceObject") and not self.isPseudoInterface()
+ return not hasattr(self, "_noInterfaceObject")
def hasInterfacePrototypeObject(self):
return (
not self.isCallback()
and not self.isNamespace()
and self.getUserData("hasConcreteDescendant", False)
- and not self.isPseudoInterface()
)
def addIncludedMixin(self, includedMixin):
@@ -1804,9 +1918,6 @@ 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)
@@ -1827,12 +1938,14 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
def isExposedConditionally(self, exclusions=[]):
return any(
- ((not a in exclusions) and self.getExtendedAttribute(a))
+ ((a not in exclusions) and self.getExtendedAttribute(a))
for a in self.conditionExtendedAttributes
)
class IDLInterface(IDLInterfaceOrNamespace):
+ __slots__ = ("classNameOverride",)
+
def __init__(
self,
location,
@@ -1885,18 +1998,19 @@ class IDLInterface(IDLInterfaceOrNamespace):
elif identifier == "LegacyFactoryFunction":
if not attr.hasValue():
raise WebIDLError(
- "LegacyFactoryFunction must either take an identifier or take a named argument list",
+ (
+ "LegacyFactoryFunction must either take an "
+ "identifier or take a named argument list"
+ ),
[attr.location],
)
args = attr.args() if attr.hasArgs() else []
- retType = IDLWrapperType(self.location, self)
-
method = IDLConstructor(attr.location, args, attr.value())
method.reallyInit(self)
- # Named constructors are always assumed to be able to
+ # Legacy factory functions are always assumed to be able to
# throw (since there's no way to indicate otherwise).
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Throws",))]
@@ -1942,7 +2056,10 @@ class IDLInterface(IDLInterfaceOrNamespace):
elif attr.hasArgs():
self.globalNames = attr.args()
else:
- self.globalNames = [self.identifier.name]
+ raise WebIDLError(
+ "[Global] must either take an identifier or take an identifier list",
+ [attr.location, self.location],
+ )
self.parentScope.addIfaceGlobalNames(
self.identifier.name, self.globalNames
)
@@ -2052,6 +2169,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
class IDLNamespace(IDLInterfaceOrNamespace):
+ __slots__ = ()
+
def __init__(self, location, parentScope, name, members, isKnownNonPartial):
IDLInterfaceOrNamespace.__init__(
self, location, parentScope, name, None, members, isKnownNonPartial
@@ -2110,6 +2229,17 @@ class IDLNamespace(IDLInterfaceOrNamespace):
class IDLDictionary(IDLObjectWithScope):
+ __slots__ = (
+ "parent",
+ "_finished",
+ "members",
+ "_partialDictionaries",
+ "_extendedAttrDict",
+ "needsConversionToJS",
+ "needsConversionFromJS",
+ "needsEqualityOperator",
+ )
+
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
@@ -2122,6 +2252,7 @@ class IDLDictionary(IDLObjectWithScope):
self._extendedAttrDict = {}
self.needsConversionToJS = False
self.needsConversionFromJS = False
+ self.needsEqualityOperator = None
IDLObjectWithScope.__init__(self, location, parentScope, name)
@@ -2186,6 +2317,14 @@ class IDLDictionary(IDLObjectWithScope):
[self.identifier.location],
)
inheritedMembers.extend(ancestor.members)
+ if (
+ self.getExtendedAttribute("GenerateEqualityOperator")
+ and ancestor.needsEqualityOperator is None
+ ):
+ # Store the dictionary that has the [GenerateEqualityOperator]
+ # extended attribute, so we can use it when generating error
+ # messages.
+ ancestor.needsEqualityOperator = self
ancestor = ancestor.parent
# Catch name duplication
@@ -2311,6 +2450,13 @@ class IDLDictionary(IDLObjectWithScope):
# implement ToJSON by converting to a JS object and
# then using JSON.stringify.
self.needsConversionToJS = True
+ elif identifier == "GenerateEqualityOperator":
+ if not attr.noArguments():
+ raise WebIDLError(
+ "[GenerateEqualityOperator] must take no arguments",
+ [attr.location],
+ )
+ self.needsEqualityOperator = self
elif identifier == "Unsorted":
if not attr.noArguments():
raise WebIDLError(
@@ -2337,6 +2483,8 @@ class IDLDictionary(IDLObjectWithScope):
class IDLEnum(IDLObjectWithIdentifier):
+ __slots__ = ("_values",)
+
def __init__(self, location, parentScope, name, values):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
@@ -2422,6 +2570,16 @@ class IDLType(IDLObject):
"observablearray",
)
+ __slots__ = (
+ "name",
+ "builtin",
+ "legacyNullToEmptyString",
+ "_clamp",
+ "_enforceRange",
+ "_allowShared",
+ "_extendedAttrDict",
+ )
+
def __init__(self, location, name):
IDLObject.__init__(self, location)
self.name = name
@@ -2625,6 +2783,8 @@ class IDLUnresolvedType(IDLType):
Unresolved types are interface types
"""
+ __slots__ = ("extraTypeAttributes",)
+
def __init__(self, location, name, attrs=[]):
IDLType.__init__(self, location, name)
self.extraTypeAttributes = attrs
@@ -2636,7 +2796,7 @@ class IDLUnresolvedType(IDLType):
obj = None
try:
obj = scope._lookupIdentifier(self.name)
- except:
+ except Exception:
raise WebIDLError("Unresolved type '%s'." % self.name, [self.location])
assert obj
@@ -2652,7 +2812,6 @@ class IDLUnresolvedType(IDLType):
assert self.name.name == obj.identifier.name
return IDLCallbackType(obj.location, obj)
- name = self.name.resolve(scope, None)
return IDLWrapperType(self.location, obj)
def withExtendedAttributes(self, attrs):
@@ -2666,6 +2825,8 @@ class IDLUnresolvedType(IDLType):
class IDLParametrizedType(IDLType):
+ __slots__ = "builtin", "inner"
+
def __init__(self, location, name, innerType):
IDLType.__init__(self, location, name)
self.builtin = False
@@ -2689,6 +2850,8 @@ class IDLParametrizedType(IDLType):
class IDLNullableType(IDLParametrizedType):
+ __slots__ = ()
+
def __init__(self, location, innerType):
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
@@ -2867,6 +3030,8 @@ class IDLNullableType(IDLParametrizedType):
class IDLSequenceType(IDLParametrizedType):
+ __slots__ = ("name",)
+
def __init__(self, location, parameterType):
assert not parameterType.isUndefined()
@@ -2927,10 +3092,17 @@ class IDLSequenceType(IDLParametrizedType):
class IDLRecordType(IDLParametrizedType):
+ __slots__ = "keyType", "name"
+
def __init__(self, location, keyType, valueType):
assert keyType.isString()
assert keyType.isComplete()
- assert not valueType.isUndefined()
+
+ if valueType.isUndefined():
+ raise WebIDLError(
+ "We don't support undefined as a Record's values' type",
+ [location, valueType.location],
+ )
IDLParametrizedType.__init__(self, location, valueType.name, valueType)
self.keyType = keyType
@@ -2984,6 +3156,9 @@ class IDLRecordType(IDLParametrizedType):
if other.isUnion():
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
+ if other.isCallback():
+ # Let other determine if it's a LegacyTreatNonObjectAsNull callback
+ return other.isDistinguishableFrom(self)
return (
other.isPrimitive()
or other.isString()
@@ -2997,6 +3172,8 @@ class IDLRecordType(IDLParametrizedType):
class IDLObservableArrayType(IDLParametrizedType):
+ __slots__ = ()
+
def __init__(self, location, innerType):
assert not innerType.isUndefined()
IDLParametrizedType.__init__(self, location, None, innerType)
@@ -3063,6 +3240,14 @@ class IDLObservableArrayType(IDLParametrizedType):
class IDLUnionType(IDLType):
+ __slots__ = (
+ "memberTypes",
+ "hasNullableType",
+ "_dictionaryType",
+ "flatMemberTypes",
+ "builtin",
+ )
+
def __init__(self, location, memberTypes):
IDLType.__init__(self, location, "")
self.memberTypes = memberTypes
@@ -3114,19 +3299,11 @@ class IDLUnionType(IDLType):
return "MaybeShared" + type.name
return type.name
- for (i, type) in enumerate(self.memberTypes):
- # Exclude typedefs because if given "typedef (B or C) test",
- # we want AOrTest, not AOrBOrC
- if not type.isComplete() and not isinstance(type, IDLTypedefType):
- self.memberTypes[i] = type.complete(scope)
-
- self.name = "Or".join(typeName(type) for type in self.memberTypes)
-
- # We do this again to complete the typedef types
- for (i, type) in enumerate(self.memberTypes):
+ for i, type in enumerate(self.memberTypes):
if not type.isComplete():
self.memberTypes[i] = type.complete(scope)
+ self.name = "Or".join(typeName(type) for type in self.memberTypes)
self.flatMemberTypes = list(self.memberTypes)
i = 0
while i < len(self.flatMemberTypes):
@@ -3163,7 +3340,7 @@ class IDLUnionType(IDLType):
continue
i += 1
- for (i, t) in enumerate(self.flatMemberTypes[:-1]):
+ for i, t in enumerate(self.flatMemberTypes[:-1]):
for u in self.flatMemberTypes[i + 1 :]:
if not t.isDistinguishableFrom(u):
raise WebIDLError(
@@ -3191,7 +3368,8 @@ class IDLUnionType(IDLType):
return True
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.
+ # 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]))
@@ -3213,6 +3391,8 @@ class IDLUnionType(IDLType):
class IDLTypedefType(IDLType):
+ __slots__ = "inner", "builtin"
+
def __init__(self, location, innerType, name):
IDLType.__init__(self, location, name)
self.inner = innerType
@@ -3323,6 +3503,8 @@ class IDLTypedefType(IDLType):
class IDLTypedef(IDLObjectWithIdentifier):
+ __slots__ = ("innerType",)
+
def __init__(self, location, parentScope, innerType, name):
# Set self.innerType first, because IDLObjectWithIdentifier.__init__
# will call our __str__, which wants to use it.
@@ -3355,6 +3537,8 @@ class IDLTypedef(IDLObjectWithIdentifier):
class IDLWrapperType(IDLType):
+ __slots__ = "inner", "_identifier", "builtin"
+
def __init__(self, location, inner):
IDLType.__init__(self, location, inner.identifier.name)
self.inner = inner
@@ -3452,7 +3636,7 @@ class IDLWrapperType(IDLType):
or other.isSequence()
or other.isRecord()
)
- if self.isDictionary() and (other.nullable() or other.isUndefined()):
+ if self.isDictionary() and other.nullable():
return False
if (
other.isPrimitive()
@@ -3461,31 +3645,57 @@ class IDLWrapperType(IDLType):
or other.isSequence()
):
return True
- if self.isDictionary():
+
+ # If this needs to handle other dictionary-like types we probably need
+ # some additional checks first.
+ assert self.isDictionaryLike() == (
+ self.isDictionary() or self.isCallbackInterface()
+ )
+ if self.isDictionaryLike():
+ if other.isCallback():
+ # Let other determine if it's a LegacyTreatNonObjectAsNull callback
+ return other.isDistinguishableFrom(self)
+
+ assert (
+ other.isNonCallbackInterface()
+ or other.isAny()
+ or other.isUndefined()
+ or other.isObject()
+ or other.isDictionaryLike()
+ )
+ # At this point, dictionary-like (for 'self') and interface-like
+ # (for 'other') are the only two that are distinguishable.
+ # any is the union of all non-union types, so it's not distinguishable
+ # from other unions (because it is a union itself), or from all
+ # non-union types (because it has all of them as its members).
return other.isNonCallbackInterface()
- assert self.isInterface()
- if other.isInterface():
+ assert self.isNonCallbackInterface()
+
+ if other.isUndefined() or other.isDictionaryLike() or other.isCallback():
+ return True
+
+ if other.isNonCallbackInterface():
if other.isSpiderMonkeyInterface():
# Just let |other| handle things
return other.isDistinguishableFrom(self)
+
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.isUndefined()
- or other.isDictionary()
- or other.isCallback()
- or other.isRecord()
- ):
- return self.isNonCallbackInterface()
+ return (
+ len(
+ self.inner.interfacesBasedOnSelf
+ & other.unroll().inner.interfacesBasedOnSelf
+ )
+ == 0
+ )
- # Not much else |other| can be
- assert other.isObject()
+ # Not much else |other| can be.
+ # any is the union of all non-union types, so it's not distinguishable
+ # from other unions (because it is a union itself), or from all
+ # non-union types (because it has all of them as its members).
+ assert other.isAny() or other.isObject()
return False
def isExposedInAllOf(self, exposureSet):
@@ -3525,6 +3735,8 @@ class IDLWrapperType(IDLType):
class IDLPromiseType(IDLParametrizedType):
+ __slots__ = ()
+
def __init__(self, location, innerType):
IDLParametrizedType.__init__(self, location, "Promise", innerType)
@@ -3578,7 +3790,6 @@ class IDLPromiseType(IDLParametrizedType):
class IDLBuiltinType(IDLType):
-
Types = enum(
# The integer types
"byte",
@@ -3692,6 +3903,14 @@ class IDLBuiltinType(IDLType):
Types.ReadableStream: "ReadableStream",
}
+ __slots__ = (
+ "_typeTag",
+ "_clamped",
+ "_rangeEnforced",
+ "_withLegacyNullToEmptyString",
+ "_withAllowShared",
+ )
+
def __init__(
self,
location,
@@ -3704,9 +3923,9 @@ class IDLBuiltinType(IDLType):
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(), .withLegacyNullToEmptyString() and .withAllowShared().
+ The mutually exclusive clamp/enforceRange/legacyNullToEmptyString/allowShared arguments
+ are used to create instances of this type with the appropriate attributes attached. Use
+ .clamped(), .rangeEnforced(), .withLegacyNullToEmptyString() and .withAllowShared().
attrLocation is an array of source locations of these attributes for error reporting.
"""
@@ -4203,6 +4422,11 @@ class NoCoercionFoundError(WebIDLError):
class IDLValue(IDLObject):
+ __slots__ = (
+ "type",
+ "value",
+ )
+
def __init__(self, location, type, value):
IDLObject.__init__(self, location)
self.type = type
@@ -4263,7 +4487,7 @@ class IDLValue(IDLObject):
)
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(
@@ -4335,6 +4559,8 @@ class IDLValue(IDLObject):
class IDLNullValue(IDLObject):
+ __slots__ = "type", "value"
+
def __init__(self, location):
IDLObject.__init__(self, location)
self.type = None
@@ -4364,6 +4590,8 @@ class IDLNullValue(IDLObject):
class IDLEmptySequenceValue(IDLObject):
+ __slots__ = "type", "value"
+
def __init__(self, location):
IDLObject.__init__(self, location)
self.type = None
@@ -4377,7 +4605,7 @@ class IDLEmptySequenceValue(IDLObject):
for subtype in type.unroll().flatMemberTypes:
try:
return self.coerceToType(subtype, location)
- except:
+ except Exception:
pass
if not type.isSequence():
@@ -4394,6 +4622,8 @@ class IDLEmptySequenceValue(IDLObject):
class IDLDefaultDictionaryValue(IDLObject):
+ __slots__ = "type", "value"
+
def __init__(self, location):
IDLObject.__init__(self, location)
self.type = None
@@ -4407,7 +4637,7 @@ class IDLDefaultDictionaryValue(IDLObject):
for subtype in type.unroll().flatMemberTypes:
try:
return self.coerceToType(subtype, location)
- except:
+ except Exception:
pass
if not type.isDictionary():
@@ -4424,6 +4654,8 @@ class IDLDefaultDictionaryValue(IDLObject):
class IDLUndefinedValue(IDLObject):
+ __slots__ = "type", "value"
+
def __init__(self, location):
IDLObject.__init__(self, location)
self.type = None
@@ -4444,7 +4676,6 @@ class IDLUndefinedValue(IDLObject):
class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
-
Tags = enum(
"Const", "Attr", "Method", "MaplikeOrSetlike", "AsyncIterable", "Iterable"
)
@@ -4454,6 +4685,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
AffectsValues = ("Nothing", "Everything")
DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
+ # no slots : multiple inheritance
def __init__(self, location, identifier, tag, extendedAttrDict=None):
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
IDLExposureMixins.__init__(self, location)
@@ -4552,7 +4784,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
)
if affects not in IDLInterfaceMember.AffectsValues:
raise WebIDLError(
- "Invalid [Affects=%s] on attribute" % dependsOn, [self.location]
+ "Invalid [Affects=%s] on attribute" % affects, [self.location]
)
self.affects = affects
@@ -4573,6 +4805,14 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
+ __slots__ = (
+ "keyType",
+ "valueType",
+ "maplikeOrSetlikeOrIterableType",
+ "disallowedMemberNames",
+ "disallowedNonMethodNames",
+ )
+
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
if keyType is not None:
@@ -4610,7 +4850,12 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
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())
+ (
+ member.isMethod()
+ and (
+ member.isStatic() or member.isMaplikeOrSetlikeOrIterableMethod()
+ )
+ )
or (member.isAttr() and member.isMaplikeOrSetlikeAttr())
):
raise WebIDLError(
@@ -4676,9 +4921,7 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
self.disallowedNonMethodNames.append(name)
# If allowExistingOperations is True, and another operation exists
# with the same name as the one we're trying to add, don't add the
- # maplike/setlike operation. However, if the operation is static,
- # then fail by way of creating the function, which will cause a
- # naming conflict, per the spec.
+ # maplike/setlike operation.
if allowExistingOperations:
for m in members:
if m.identifier.name == name and m.isMethod() and not m.isStatic():
@@ -4786,6 +5029,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
+ __slots__ = ("iteratorType",)
+
def __init__(self, location, identifier, keyType, valueType, scope):
IDLMaplikeOrSetlikeOrIterableBase.__init__(
self,
@@ -4861,6 +5106,8 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
class IDLAsyncIterable(IDLMaplikeOrSetlikeOrIterableBase):
+ __slots__ = "iteratorType", "argList"
+
def __init__(self, location, identifier, keyType, valueType, argList, scope):
for arg in argList:
if not arg.optional:
@@ -4945,6 +5192,8 @@ class IDLAsyncIterable(IDLMaplikeOrSetlikeOrIterableBase):
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
+ __slots__ = "readonly", "slotIndices", "prefix"
+
def __init__(
self, location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType
):
@@ -5112,6 +5361,8 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
class IDLConst(IDLInterfaceMember):
+ __slots__ = "type", "value"
+
def __init__(self, location, identifier, type, value):
IDLInterfaceMember.__init__(
self, location, identifier, IDLInterfaceMember.Tags.Const
@@ -5144,7 +5395,7 @@ class IDLConst(IDLInterfaceMember):
locations = [self.type.location, type.location]
try:
locations.append(type.inner.location)
- except:
+ except Exception:
pass
raise WebIDLError("Incorrect type for constant", locations)
self.type = type
@@ -5184,6 +5435,21 @@ class IDLConst(IDLInterfaceMember):
class IDLAttribute(IDLInterfaceMember):
+ __slots__ = (
+ "type",
+ "readonly",
+ "inherit",
+ "_static",
+ "legacyLenientThis",
+ "_legacyUnforgeable",
+ "stringifier",
+ "slotIndices",
+ "maplikeOrSetlike",
+ "dependsOn",
+ "affects",
+ "bindingAliases",
+ )
+
def __init__(
self,
location,
@@ -5695,9 +5961,9 @@ class IDLAttribute(IDLInterfaceMember):
or identifier == "SetterNeedsSubjectPrincipal"
or identifier == "GetterNeedsSubjectPrincipal"
or identifier == "NeedsCallerType"
- or identifier == "ReturnValueNeedsContainsHack"
or identifier == "BinaryName"
or identifier == "NonEnumerable"
+ or identifier == "BindingTemplate"
):
# Known attributes that we don't need to do anything with here
pass
@@ -5708,6 +5974,9 @@ class IDLAttribute(IDLInterfaceMember):
)
IDLInterfaceMember.handleExtendedAttribute(self, attr)
+ def getExtendedAttributes(self):
+ return self._extendedAttrDict
+
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
self.type.resolveType(parentScope)
@@ -5760,7 +6029,7 @@ class IDLAttribute(IDLInterfaceMember):
"CrossOriginWritable",
"SetterThrows",
]
- for (key, value) in self._extendedAttrDict.items():
+ for key, value in self._extendedAttrDict.items():
if key in allowedExtAttrs:
if value is not True:
raise WebIDLError(
@@ -5772,7 +6041,7 @@ class IDLAttribute(IDLInterfaceMember):
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, (key,))]
)
- elif not key in attributeOnlyExtAttrs:
+ elif key not in attributeOnlyExtAttrs:
raise WebIDLError(
"[%s] is currently unsupported in "
"stringifier attributes, please file a bug "
@@ -5783,6 +6052,18 @@ class IDLAttribute(IDLInterfaceMember):
class IDLArgument(IDLObjectWithIdentifier):
+ __slots__ = (
+ "type",
+ "optional",
+ "defaultValue",
+ "variadic",
+ "dictionaryMember",
+ "_isComplete",
+ "_allowTreatNonCallableAsNull",
+ "_extendedAttrDict",
+ "allowTypeAttributes",
+ )
+
def __init__(
self,
location,
@@ -5835,6 +6116,18 @@ class IDLArgument(IDLObjectWithIdentifier):
"dictionary member" % identifier,
[attribute.location],
)
+ elif self.dictionaryMember and identifier == "BinaryType":
+ if not len(attribute.listValue()) == 1:
+ raise WebIDLError(
+ "[%s] BinaryType must take one argument" % identifier,
+ [attribute.location],
+ )
+ if not self.defaultValue:
+ raise WebIDLError(
+ "[%s] BinaryType can't be used without default value"
+ % identifier,
+ [attribute.location],
+ )
else:
raise WebIDLError(
"Unhandled extended attribute on %s"
@@ -5914,6 +6207,15 @@ class IDLArgument(IDLObjectWithIdentifier):
class IDLCallback(IDLObjectWithScope):
+ __slots__ = (
+ "_returnType",
+ "_arguments",
+ "_treatNonCallableAsNull",
+ "_treatNonObjectAsNull",
+ "_isRunScriptBoundary",
+ "_isConstructor",
+ )
+
def __init__(
self, location, parentScope, identifier, returnType, arguments, isConstructor
):
@@ -5925,7 +6227,7 @@ class IDLCallback(IDLObjectWithScope):
IDLObjectWithScope.__init__(self, location, parentScope, identifier)
- for (returnType, arguments) in self.signatures():
+ for returnType, arguments in self.signatures():
for argument in arguments:
argument.resolve(self)
@@ -6011,6 +6313,8 @@ class IDLCallback(IDLObjectWithScope):
class IDLCallbackType(IDLType):
+ __slots__ = ("callback",)
+
def __init__(self, location, callback):
IDLType.__init__(self, location, callback.identifier.name)
self.callback = callback
@@ -6027,6 +6331,9 @@ class IDLCallbackType(IDLType):
if other.isUnion():
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
+ # Callbacks without `LegacyTreatNonObjectAsNull` are distinguishable from Dictionary likes
+ if other.isDictionaryLike():
+ return not self.callback._treatNonObjectAsNull
return (
other.isUndefined()
or other.isPrimitive()
@@ -6050,6 +6357,8 @@ class IDLMethodOverload:
the full set of overloads.
"""
+ __slots__ = "returnType", "arguments", "location"
+
def __init__(self, returnType, arguments, location):
self.returnType = returnType
# Clone the list of arguments, just in case
@@ -6066,13 +6375,31 @@ class IDLMethodOverload:
class IDLMethod(IDLInterfaceMember, IDLScope):
-
Special = enum(
"Getter", "Setter", "Deleter", "LegacyCaller", base=IDLInterfaceMember.Special
)
NamedOrIndexed = enum("Neither", "Named", "Indexed")
+ __slots__ = (
+ "_hasOverloads",
+ "_overloads",
+ "_static",
+ "_getter",
+ "_setter",
+ "_deleter",
+ "_legacycaller",
+ "_stringifier",
+ "maplikeOrSetlikeOrIterable",
+ "_htmlConstructor",
+ "underlyingAttr",
+ "_specialType",
+ "_legacyUnforgeable",
+ "dependsOn",
+ "affects",
+ "aliases",
+ )
+
def __init__(
self,
location,
@@ -6249,7 +6576,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert isinstance(parentScope, IDLScope)
IDLObjectWithIdentifier.resolve(self, parentScope)
IDLScope.__init__(self, self.location, parentScope, self.identifier)
- for (returnType, arguments) in self.signatures():
+ for returnType, arguments in self.signatures():
for argument in arguments:
argument.resolve(self)
@@ -6299,22 +6626,35 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if self.isLegacycaller() != method.isLegacycaller():
raise WebIDLError(
- "Overloaded identifier %s appears with different values of the 'legacycaller' attribute"
- % method.identifier,
+ (
+ "Overloaded identifier %s appears with different "
+ "values of the 'legacycaller' attribute" % method.identifier
+ ),
[method.location],
)
# Can't overload special things!
- assert not self.isGetter()
- assert not method.isGetter()
- assert not self.isSetter()
- assert not method.isSetter()
- assert not self.isDeleter()
- assert not method.isDeleter()
- assert not self.isStringifier()
- assert not method.isStringifier()
- assert not self.isHTMLConstructor()
- assert not method.isHTMLConstructor()
+ if (
+ self.isGetter()
+ or method.isGetter()
+ or self.isSetter()
+ or method.isSetter()
+ or self.isDeleter()
+ or method.isDeleter()
+ or self.isStringifier()
+ or method.isStringifier()
+ ):
+ raise WebIDLError(
+ ("Can't overload a special operation"),
+ [self.location, method.location],
+ )
+ if self.isHTMLConstructor() or method.isHTMLConstructor():
+ raise WebIDLError(
+ (
+ "An interface must contain only a single operation annotated with HTMLConstructor, and no others"
+ ),
+ [self.location, method.location],
+ )
return self
@@ -6390,7 +6730,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
variadicArgument = None
arguments = overload.arguments
- for (idx, argument) in enumerate(arguments):
+ for idx, argument in enumerate(arguments):
assert argument.type.isComplete()
if (
@@ -6523,8 +6863,8 @@ 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 firstSigIndex, (firstRetval, firstArgs) in enumerate(signatures[:-1]):
+ for secondRetval, secondArgs in signatures[firstSigIndex + 1 :]:
if idx < len(firstArgs):
firstType = firstArgs[idx].type
else:
@@ -6726,6 +7066,14 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
class IDLConstructor(IDLMethod):
+ __slots__ = (
+ "_initLocation",
+ "_initArgs",
+ "_initName",
+ "_inited",
+ "_initExtendedAttrs",
+ )
+
def __init__(self, location, args, name):
# We can't actually init our IDLMethod yet, because we do not know the
# return type yet. Just save the info we have for now and we will init
@@ -6795,6 +7143,8 @@ class IDLConstructor(IDLMethod):
class IDLIncludesStatement(IDLObject):
+ __slots__ = ("interface", "mixin", "_finished")
+
def __init__(self, location, interface, mixin):
IDLObject.__init__(self, location)
self.interface = interface
@@ -6851,6 +7201,8 @@ class IDLExtendedAttribute(IDLObject):
A class to represent IDL extended attributes so we can give them locations
"""
+ __slots__ = ("_tuple",)
+
def __init__(self, location, tuple):
IDLObject.__init__(self, location)
self._tuple = tuple
@@ -6891,7 +7243,7 @@ class IDLExtendedAttribute(IDLObject):
class Tokenizer(object):
- tokens = ["INTEGER", "FLOATLITERAL", "IDENTIFIER", "STRING", "WHITESPACE", "OTHER"]
+ tokens = ["INTEGER", "FLOATLITERAL", "IDENTIFIER", "STRING", "COMMENTS", "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"
@@ -6903,7 +7255,7 @@ class Tokenizer(object):
try:
# Can't use int(), because that doesn't handle octal properly.
t.value = parseInt(t.value)
- except:
+ except Exception:
raise WebIDLError(
"Invalid integer literal",
[
@@ -6930,17 +7282,19 @@ class Tokenizer(object):
t.value = t.value[1:-1]
return t
- def t_WHITESPACE(self, t):
- r"[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+"
+ t_ignore = "\t\n\r "
+
+ def t_COMMENTS(self, t):
+ r"//[^\n]*|/\*(?s:.)*?\*/"
pass
def t_ELLIPSIS(self, t):
r"\.\.\."
- t.type = self.keywords.get(t.value)
+ t.type = "ELLIPSIS"
return t
def t_OTHER(self, t):
- r"[^\t\n\r 0-9A-Z_a-z]"
+ r"[^0-9A-Z_a-z]"
t.type = self.keywords.get(t.value, "OTHER")
return t
@@ -7029,7 +7383,7 @@ class Tokenizer(object):
lexer=self.lexer,
lineno=self.lexer.lineno,
lexpos=self.lexer.lexpos,
- filename=self.filename,
+ filename=self._filename,
)
],
)
@@ -7039,14 +7393,14 @@ class Tokenizer(object):
if lexer:
self.lexer = lexer
else:
- self.lexer = lex.lex(object=self, reflags=re.DOTALL)
+ self.lexer = lex.lex(object=self)
class SqueakyCleanLogger(object):
errorWhitelist = [
- # Web IDL defines the WHITESPACE token, but doesn't actually
+ # Web IDL defines the COMMENTS 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 an unused token
"There is 1 unused token",
# Web IDL defines a OtherOrComma rule that's only used in
@@ -8600,7 +8954,7 @@ class Parser(Tokenizer):
type = IDLWrapperType(self.getLocation(p, 1), p[1])
p[0] = self.handleNullable(type, p[2])
return
- except:
+ except Exception:
pass
type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
@@ -8863,7 +9217,10 @@ class Parser(Tokenizer):
def p_error(self, p):
if not p:
raise WebIDLError(
- "Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both",
+ (
+ "Syntax Error at end of file. Possibly due to "
+ "missing semicolon(;), braces(}) or both"
+ ),
[self._filename],
)
else:
@@ -8912,9 +9269,7 @@ class Parser(Tokenizer):
):
builtin = BuiltinTypes[x]
name = builtin.name
- typedef = IDLTypedef(
- BuiltinLocation("<builtin type>"), scope, builtin, name
- )
+ IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
@staticmethod
def handleNullable(type, questionMarkLocation):
@@ -9114,13 +9469,8 @@ class Parser(Tokenizer):
production.validate()
# De-duplicate self._productions, without modifying its order.
- seen = set()
- result = []
- for p in self._productions:
- if p not in seen:
- seen.add(p)
- result.append(p)
- return result
+ result = dict.fromkeys(self._productions)
+ return list(result.keys())
def reset(self):
return Parser(lexer=self.lexer)