diff options
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
87 files changed, 0 insertions, 21116 deletions
diff --git a/components/script/dom/bindings/codegen/parser/README b/components/script/dom/bindings/codegen/parser/README deleted file mode 100644 index 94b64b88459..00000000000 --- a/components/script/dom/bindings/codegen/parser/README +++ /dev/null @@ -1 +0,0 @@ -A WebIDL parser written in Python to be used in Mozilla.
\ No newline at end of file diff --git a/components/script/dom/bindings/codegen/parser/UPSTREAM b/components/script/dom/bindings/codegen/parser/UPSTREAM deleted file mode 100644 index 7ac5899379e..00000000000 --- a/components/script/dom/bindings/codegen/parser/UPSTREAM +++ /dev/null @@ -1 +0,0 @@ -http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.409;content-type=text%2Fhtml%3b+charset=utf-8
\ No newline at end of file diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py deleted file mode 100644 index 2366e3f7027..00000000000 --- a/components/script/dom/bindings/codegen/parser/WebIDL.py +++ /dev/null @@ -1,9107 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -""" A WebIDL parser. """ - -import copy -import math -import os -import re -import string -import traceback -from collections import OrderedDict, defaultdict -from itertools import chain - -from ply import lex, yacc - -# Machinery - - -def parseInt(literal): - string = literal - sign = 0 - base = 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": - base = 16 - string = string[2:] - else: - base = 8 - string = string[1:] - else: - base = 10 - - value = int(string, base) - return value * sign - - -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(kw["base"].attrs.keys(), names)) - - -class WebIDLError(Exception): - def __init__(self, message, locations, warning=False): - self.message = message - self.locations = [str(loc) for loc in locations] - 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), - ) - - -class Location(object): - def __init__(self, lexer, lineno, lexpos, filename): - self._line = None - self._lineno = lineno - self._lexpos = lexpos - self._lexdata = lexer.lexdata - self._file = 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 - - def resolve(self): - if self._line: - return - - 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: - self._line = self._lexdata[startofline:] - 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) - - def get(self): - self.resolve() - return "%s line %s:%s" % (self._file, self._lineno, self._colno) - - def _pointerline(self): - return " " * self._colno + "^" - - def __str__(self): - self.resolve() - return "%s line %s:%s\n%s\n%s" % ( - self._file, - self._lineno, - self._colno, - self._line, - self._pointerline(), - ) - - -class BuiltinLocation(object): - def __init__(self, text): - self.msg = text + "\n" - - def __eq__(self, other): - return isinstance(other, BuiltinLocation) and self.msg == other.msg - - def filename(self): - return "<builtin>" - - def resolve(self): - pass - - def get(self): - return self.msg - - def __str__(self): - return self.get() - - -# Data Model - - -class IDLObject(object): - def __init__(self, location): - self.location = location - self.userData = dict() - - def filename(self): - return self.location.filename() - - def isInterface(self): - return False - - def isNamespace(self): - return False - - def isInterfaceMixin(self): - return False - - def isEnum(self): - return False - - def isCallback(self): - return False - - def isType(self): - return False - - def isDictionary(self): - return False - - def isUnion(self): - return False - - def isTypedef(self): - return False - - def getUserData(self, key, default): - return self.userData.get(key, default) - - def setUserData(self, key, value): - self.userData[key] = value - - def addExtendedAttributes(self, attrs): - assert False # Override me! - - def handleExtendedAttribute(self, attr): - assert False # Override me! - - def _getDependentObjects(self): - 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. - - 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 - # is executed, so there would be one set for all invocations. - if visited is None: - visited = set() - - if self in visited: - return set() - - visited.add(self) - - deps = set() - if self.filename() != "<builtin>": - deps.add(self.filename()) - - for d in self._getDependentObjects(): - deps.update(d.getDeps(visited)) - - return deps - - -class IDLScope(IDLObject): - def __init__(self, location, parentScope, identifier): - IDLObject.__init__(self, location) - - self.parentScope = parentScope - if identifier: - assert isinstance(identifier, IDLIdentifier) - self._name = identifier - else: - self._name = None - - self._dict = {} - self.globalNames = set() - # A mapping from global name to the set of global interfaces - # that have that global name. - self.globalNameMapping = defaultdict(set) - - def __str__(self): - return self.QName() - - def QName(self): - # It's possible for us to be called before __init__ has been called, for - # the IDLObjectWithScope case. In that case, self._name won't be set yet. - if hasattr(self, "_name"): - name = self._name - else: - name = None - if name: - return name.QName() + "::" - return "::" - - 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. - """ - assert isinstance(identifier, IDLUnresolvedIdentifier) - assert not object or isinstance(object, IDLObjectWithIdentifier) - assert not object or object.identifier == identifier - - if identifier.name in self._dict: - if not object: - return - - # 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 - ) - self._dict[identifier.name] = replacement - return - - assert object - - 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 - ): - return originalObject - - 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), - [], - ) - - 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), - [], - ) - - # We do the merging of overloads here as opposed to in IDLInterface - # 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 "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, - ) - - raise WebIDLError( - "Multiple unresolvable definitions of identifier '%s' in scope '%s'%s" - % (identifier.name, str(self), conflictdesc), - [], - ) - - def _lookupIdentifier(self, identifier): - return self._dict[identifier.name] - - def lookupIdentifier(self, identifier): - assert isinstance(identifier, IDLIdentifier) - assert identifier.scope == self - return self._lookupIdentifier(identifier) - - def addIfaceGlobalNames(self, interfaceName, globalNames): - """Record the global names (from |globalNames|) that can be used in - [Exposed] to expose things in a global named |interfaceName|""" - self.globalNames.update(globalNames) - for name in globalNames: - self.globalNameMapping[name].add(interfaceName) - - -class IDLIdentifier(IDLObject): - def __init__(self, location, scope, name): - IDLObject.__init__(self, location) - - self.name = name - assert isinstance(scope, IDLScope) - self.scope = scope - - def __str__(self): - return self.QName() - - def QName(self): - return self.scope.QName() + self.name - - def __hash__(self): - return self.QName().__hash__() - - def __eq__(self, other): - return self.QName() == other.QName() - - def object(self): - return self.scope.lookupIdentifier(self) - - -class IDLUnresolvedIdentifier(IDLObject): - def __init__( - self, location, name, allowDoubleUnderscore=False, allowForbidden=False - ): - IDLObject.__init__(self, location) - - assert len(name) > 0 - - if name == "__noSuchMethod__": - raise WebIDLError("__noSuchMethod__ is deprecated", [location]) - - 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] - ) - - self.name = name - - def __str__(self): - return self.QName() - - def QName(self): - return "<unresolved scope>::" + self.name - - def resolve(self, scope, object): - assert isinstance(scope, IDLScope) - assert not object or isinstance(object, IDLObjectWithIdentifier) - assert not object or object.identifier == self - - scope.ensureUnique(self, object) - - identifier = IDLIdentifier(self.location, scope, self.name) - if object: - object.identifier = identifier - return identifier - - def finish(self): - assert False # Should replace with a resolved identifier first. - - -class IDLObjectWithIdentifier(IDLObject): - def __init__(self, location, parentScope, identifier): - IDLObject.__init__(self, location) - - assert isinstance(identifier, IDLUnresolvedIdentifier) - - self.identifier = identifier - - if parentScope: - self.resolve(parentScope) - - def resolve(self, parentScope): - assert isinstance(parentScope, IDLScope) - assert isinstance(self.identifier, IDLUnresolvedIdentifier) - self.identifier.resolve(parentScope, self) - - -class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope): - def __init__(self, location, parentScope, identifier): - assert isinstance(identifier, IDLUnresolvedIdentifier) - - IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier) - IDLScope.__init__(self, location, parentScope, self.identifier) - - -class IDLIdentifierPlaceholder(IDLObjectWithIdentifier): - def __init__(self, location, identifier): - assert isinstance(identifier, IDLUnresolvedIdentifier) - IDLObjectWithIdentifier.__init__(self, location, None, identifier) - - def finish(self, scope): - try: - scope._lookupIdentifier(self.identifier) - except: - raise WebIDLError( - "Unresolved type '%s'." % self.identifier, [self.location] - ) - - obj = self.identifier.resolve(scope, None) - return scope.lookupIdentifier(obj) - - -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 - # Web IDL spec: it contains interface names. - self._exposureGlobalNames = set() - self.exposureSet = set() - self._location = location - self._globalScope = None - - def finish(self, scope): - assert scope.parentScope is None - self._globalScope = scope - - 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 - # because a lot of our parser tests have small-enough IDL snippets that - # 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], - ) - - globalNameSetToExposureSet(scope, self._exposureGlobalNames, self.exposureSet) - - def isExposedInWindow(self): - return "Window" in self.exposureSet - - def isExposedInAnyWorker(self): - return len(self.getWorkerExposureSet()) > 0 - - def isExposedInWorkerDebugger(self): - return len(self.getWorkerDebuggerExposureSet()) > 0 - - def isExposedInAnyWorklet(self): - return len(self.getWorkletExposureSet()) > 0 - - def isExposedInSomeButNotAllWorkers(self): - """ - Returns true if the Exposed extended attribute for this interface - exposes it in some worker globals but not others. The return value does - not depend on whether the interface is exposed in Window or System - globals. - """ - if not self.isExposedInAnyWorker(): - return False - 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) - - def getWorkletExposureSet(self): - workletScopes = self._globalScope.globalNameMapping["Worklet"] - return workletScopes.intersection(self.exposureSet) - - def getWorkerDebuggerExposureSet(self): - workerDebuggerScopes = self._globalScope.globalNameMapping["WorkerDebugger"] - return workerDebuggerScopes.intersection(self.exposureSet) - - -class IDLExternalInterface(IDLObjectWithIdentifier): - def __init__(self, location, parentScope, identifier): - assert isinstance(identifier, IDLUnresolvedIdentifier) - assert isinstance(parentScope, IDLScope) - self.parent = None - IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier) - IDLObjectWithIdentifier.resolve(self, parentScope) - - def finish(self, scope): - pass - - def validate(self): - pass - - def isIteratorInterface(self): - return False - - def isAsyncIteratorInterface(self): - return False - - def isExternal(self): - return True - - def isInterface(self): - return True - - 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], - ) - - def resolve(self, parentScope): - pass - - def getJSImplementation(self): - return None - - def isJSImplemented(self): - return False - - def hasProbablyShortLivingWrapper(self): - return False - - def _getDependentObjects(self): - return set() - - -class IDLPartialDictionary(IDLObject): - def __init__(self, location, name, members, nonPartialDictionary): - assert isinstance(name, IDLUnresolvedIdentifier) - - IDLObject.__init__(self, location) - self.identifier = name - self.members = members - self._nonPartialDictionary = nonPartialDictionary - self._finished = False - nonPartialDictionary.addPartialDictionary(self) - - def addExtendedAttributes(self, attrs): - pass - - def finish(self, scope): - if self._finished: - return - self._finished = True - - # Need to make sure our non-partial dictionary gets - # finished so it can report cases when we only have partial - # dictionaries. - self._nonPartialDictionary.finish(scope) - - def validate(self): - pass - - -class IDLPartialInterfaceOrNamespace(IDLObject): - def __init__(self, location, name, members, nonPartialInterfaceOrNamespace): - assert isinstance(name, IDLUnresolvedIdentifier) - - IDLObject.__init__(self, location) - self.identifier = name - self.members = members - # propagatedExtendedAttrs are the ones that should get - # propagated to our non-partial interface. - self.propagatedExtendedAttrs = [] - self._haveSecureContextExtendedAttribute = False - self._nonPartialInterfaceOrNamespace = nonPartialInterfaceOrNamespace - self._finished = False - nonPartialInterfaceOrNamespace.addPartial(self) - - def addExtendedAttributes(self, attrs): - for attr in attrs: - identifier = attr.identifier() - - 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], - ) - 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], - ) - member.addExtendedAttributes([attr]) - else: - 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" - ) - ): - # 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, - ], - ) - member.addExtendedAttributes( - [ - 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. - self._nonPartialInterfaceOrNamespace.finish(scope) - - def validate(self): - pass - - -def convertExposedAttrToGlobalNameSet(exposedAttr, targetSet): - assert len(targetSet) == 0 - if exposedAttr.hasValue(): - targetSet.add(exposedAttr.value()) - else: - assert exposedAttr.hasArgs() - targetSet.update(exposedAttr.args()) - - -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) - assert isinstance(name, IDLUnresolvedIdentifier) - - self._finished = False - self.members = [] - self._partials = [] - self._extendedAttrDict = {} - self._isKnownNonPartial = False - - IDLObjectWithScope.__init__(self, location, parentScope, name) - IDLExposureMixins.__init__(self, location) - - def finish(self, scope): - if not self._isKnownNonPartial: - raise WebIDLError( - "%s does not have a non-partial declaration" % str(self), - [self.location], - ) - - IDLExposureMixins.finish(self, scope) - - # Now go ahead and merge in our partials. - for partial in self._partials: - partial.finish(scope) - self.addExtendedAttributes(partial.propagatedExtendedAttrs) - self.members.extend(partial.members) - - def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject): - assert isinstance(scope, IDLScope) - assert isinstance(originalObject, IDLInterfaceMember) - assert isinstance(newObject, IDLInterfaceMember) - - retval = IDLScope.resolveIdentifierConflict( - self, scope, identifier, originalObject, newObject - ) - - # Might be a ctor, which isn't in self.members - if newObject in self.members: - self.members.remove(newObject) - return retval - - def typeName(self): - if self.isInterface(): - return "interface" - if self.isNamespace(): - return "namespace" - assert self.isInterfaceMixin() - return "interface mixin" - - def getExtendedAttribute(self, name): - return self._extendedAttrDict.get(name, None) - - def setNonPartial(self, location, members): - if self._isKnownNonPartial: - 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 - self.location = location - # Put the new members at the beginning - self.members = members + self.members - - def addPartial(self, partial): - assert self.identifier.name == partial.identifier.name - self._partials.append(partial) - - def getPartials(self): - # Don't let people mutate our guts. - return list(self._partials) - - def finishMembers(self, scope): - # Assuming we've merged in our partials, set the _exposureGlobalNames on - # any members that don't have it set yet. Note that any partial - # interfaces that had [Exposed] set have already set up - # _exposureGlobalNames on all the members coming from them, so this is - # just implementing the "members default to interface or interface mixin - # that defined them" and "partial interfaces or interface mixins default - # to interface or interface mixin they're a partial for" rules from the - # spec. - for m in self.members: - # If m, or the partial m came from, had [Exposed] - # specified, it already has a nonempty exposure global names set. - if len(m._exposureGlobalNames) == 0: - m._exposureGlobalNames.update(self._exposureGlobalNames) - if m.isAttr() and m.stringifier: - m.expand(self.members) - - # resolve() will modify self.members, so we need to iterate - # over a copy of the member list here. - for member in list(self.members): - member.resolve(self) - - for member in self.members: - member.finish(scope) - - # Now that we've finished our members, which has updated their exposure - # 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], - ) - - def isExternal(self): - return False - - -class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace): - def __init__(self, location, parentScope, name, members, isKnownNonPartial): - self.actualExposureGlobalNames = set() - - assert isKnownNonPartial or len(members) == 0 - IDLInterfaceOrInterfaceMixinOrNamespace.__init__( - self, location, parentScope, name - ) - - if isKnownNonPartial: - self.setNonPartial(location, members) - - def __str__(self): - return "Interface mixin '%s'" % self.identifier.name - - def isInterfaceMixin(self): - return True - - def finish(self, scope): - if self._finished: - return - self._finished = True - - # Expose to the globals of interfaces that includes this mixin if this - # mixin has no explicit [Exposed] so that its members can be exposed - # based on the base interface exposure set. - # - # Make sure this is done before IDLExposureMixins.finish call, since - # that converts our set of exposure global names to an actual exposure - # set. - hasImplicitExposure = len(self._exposureGlobalNames) == 0 - if hasImplicitExposure: - self._exposureGlobalNames.update(self.actualExposureGlobalNames) - - IDLInterfaceOrInterfaceMixinOrNamespace.finish(self, scope) - - self.finishMembers(scope) - - def validate(self): - for member in self.members: - - if member.isAttr(): - if member.inherit: - 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], - ) - - 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], - ) - - def addExtendedAttributes(self, attrs): - for attr in attrs: - identifier = attr.identifier() - - if identifier == "SecureContext": - if not attr.noArguments(): - 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], - ) - member.addExtendedAttributes([attr]) - elif identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) - else: - raise WebIDLError( - "Unknown extended attribute %s on interface" % identifier, - [attr.location], - ) - - attrlist = attr.listValue() - self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True - - def _getDependentObjects(self): - return set(self.members) - - -class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace): - def __init__(self, location, parentScope, name, parent, members, isKnownNonPartial): - assert isKnownNonPartial or not parent - assert isKnownNonPartial or len(members) == 0 - - 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 - # them. - self.legacyFactoryFunctions = list() - 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._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 - # Tracking of the number of own own members we have in slots - self._ownMembersInSlots = 0 - # 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 - - IDLInterfaceOrInterfaceMixinOrNamespace.__init__( - self, location, parentScope, name - ) - - if isKnownNonPartial: - self.setNonPartial(location, parent, members) - - def ctor(self): - 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() - ) - - 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 - - self._finished = True - - IDLInterfaceOrInterfaceMixinOrNamespace.finish(self, scope) - - if len(self.legacyWindowAliases) > 0: - if not self.hasInterfaceObject(): - 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], - ) - - # 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], - ) - 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) - - 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], - ) - 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], - ) - - self.parent = parent - - assert iter(self.members) - - if self.isNamespace(): - assert not self.parent - 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], - ) - # 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 - # start with, but that sounds annoying. - m.forceStatic() - - if self.parent: - self.parent.finish(scope) - self.parent._hasChildInterfaces = True - - self.totalMembersInSlots = self.parent.totalMembersInSlots - - # Interfaces with [Global] must not have anything inherit from them - if self.parent.getExtendedAttribute("Global"): - # 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], - ) - - # 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], - ) - - # 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], - ) - 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], - ) - - # Interfaces which have interface objects can't inherit - # 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], - ) - - for mixin in self.includedMixins: - mixin.finish(scope) - - cycleInGraph = self.findInterfaceLoopPoint(self) - if cycleInGraph: - raise WebIDLError( - "Interface %s has itself as ancestor" % self.identifier.name, - [self.location, cycleInGraph.location], - ) - - self.finishMembers(scope) - - ctor = self.ctor() - if ctor is not None: - if not self.hasInterfaceObject(): - raise WebIDLError( - "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], - ) - - 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.legacyFactoryFunctions: - if self.globalNames: - raise WebIDLError( - "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) - - # Make a copy of our member list, so things that implement us - # can get those without all the stuff we implement ourselves - # admixed. - self.originalMembers = list(self.members) - - 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], - ) - 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 [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("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( - "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( - "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( - "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.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") - ) - ): - self.hasCrossOriginMembers = True - break - - if self.hasCrossOriginMembers: - parent = self - while parent: - parent.hasDescendantWithCrossOriginMembers = True - parent = parent.parent - - # Compute slot indices for our members before we pull in unforgeable - # 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.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] 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 - self.totalMembersInSlots += 1 - if member.getExtendedAttribute("StoreInSlot"): - self._ownMembersInSlots += 1 - - if self.parent: - # 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.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 [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 - # attributes/methods of ancestor interfaces, with their - # corresponding getters, on our interface, but that gets pretty - # complicated and seems unnecessary. - self.members.append(unforgeableMember) - - # At this point, we have all of our members. If the current interface - # uses maplike/setlike, check for collisions anywhere in the current - # interface or higher in the inheritance chain. - if self.maplikeOrSetlikeOrIterable: - testInterface = self - isAncestor = False - while testInterface: - self.maplikeOrSetlikeOrIterable.checkCollisions( - testInterface.members, isAncestor - ) - isAncestor = True - testInterface = testInterface.parent - - # Ensure that there's at most one of each {named,indexed} - # {getter,setter,deleter}, at most one stringifier, - # and at most one legacycaller. Note that this last is not - # quite per spec, but in practice no one overloads - # legacycallers. Also note that in practice we disallow - # indexed deleters, but it simplifies some other code to - # treat deleter analogously to getter/setter by - # prefixing it with "named". - specialMembersSeen = {} - for member in self.members: - if not member.isMethod(): - continue - - if member.isGetter(): - memberType = "getters" - elif member.isSetter(): - memberType = "setters" - elif member.isDeleter(): - memberType = "deleters" - elif member.isStringifier(): - memberType = "stringifiers" - elif member.isLegacycaller(): - memberType = "legacycallers" - else: - continue - - if memberType != "stringifiers" and memberType != "legacycallers": - if member.isNamed(): - memberType = "named " + memberType - else: - assert member.isIndexed() - memberType = "indexed " + memberType - - if memberType in specialMembersSeen: - raise WebIDLError( - "Multiple " + memberType + " on %s" % (self), - [ - self.location, - specialMembersSeen[memberType].location, - member.location, - ], - ) - - specialMembersSeen[memberType] = member - - if self.getExtendedAttribute("LegacyUnenumerableNamedProperties"): - # Check that we have a named getter. - if "named getters" not in specialMembersSeen: - raise WebIDLError( - "Interface with [LegacyUnenumerableNamedProperties] does " - "not have a named getter", - [self.location], - ) - ancestor = self.parent - while ancestor: - if ancestor.getExtendedAttribute("LegacyUnenumerableNamedProperties"): - raise WebIDLError( - "Interface with [LegacyUnenumerableNamedProperties] " - "inherits from another interface with " - "[LegacyUnenumerableNamedProperties]", - [self.location, ancestor.location], - ) - ancestor = ancestor.parent - - if self._isOnGlobalProtoChain: - # Make sure we have no named setters or deleters - 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 [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 [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], - ) - if m.isMethod() and m != member and name in m.aliases: - 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], - ) - - # We also don't support inheriting from unforgeable interfaces. - 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.legacyFactoryFunctions: - namedCtor.validate() - - indexedGetter = None - hasLengthAttribute = False - for member in self.members: - 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], - ) - - # 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(): - 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], - ) - - 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] - ): - continue - if forwardedMember == member: - 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], - ) - - iface = forwardIface - attr = fowardAttr - putForwards = attr.getExtendedAttribute("PutForwards") - - # Check that the name of an [Alias] doesn't conflict with an - # interface member and whether we support indexed properties. - if member.isMethod(): - if member.isGetter() and member.isIndexed(): - indexedGetter = member - - 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("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], - ) - if member.isIdentifierLess(): - 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") - - # Check that the name of a [BindingAlias] doesn't conflict with an - # interface member. - if member.isAttr(): - 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], - ) - - # Value iterators are only allowed on interfaces with indexed getters, - # and pair iterators are only allowed on interfaces without indexed - # getters. - if self.isIterable(): - iterableDecl = self.maplikeOrSetlikeOrIterable - if iterableDecl.isValueIterator(): - if not indexedGetter: - 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], - ) - - if not hasLengthAttribute: - 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], - ) - - if indexedGetter and not hasLengthAttribute: - 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 - - def isCallback(self): - return self._callback - - def isSingleOperationInterface(self): - assert self.isCallback() or self.isJSImplemented() - return ( - # JS-implemented things should never need the - # this-handling weirdness of single-operation interfaces. - not self.isJSImplemented() - and - # Not inheriting from another interface - not self.parent - and - # No attributes of any kinds - 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 - ) - - def inheritanceDepth(self): - depth = 0 - parent = self.parent - while parent: - depth = depth + 1 - parent = parent.parent - return depth - - def hasConstants(self): - return any(m.isConst() for m in self.members) - - def hasInterfaceObject(self): - if self.isCallback(): - return self.hasConstants() - 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) - and not self.isPseudoInterface() - ) - - def addIncludedMixin(self, includedMixin): - assert isinstance(includedMixin, IDLInterfaceMixin) - self.includedMixins.add(includedMixin) - - def getInheritedInterfaces(self): - """ - Returns a list of the interfaces this interface inherits from - (not including this interface itself). The list is in order - from most derived to least derived. - """ - assert self._finished - if not self.parent: - return [] - parentInterfaces = self.parent.getInheritedInterfaces() - parentInterfaces.insert(0, self.parent) - return parentInterfaces - - def findInterfaceLoopPoint(self, otherInterface): - """ - Finds an interface amongst our ancestors that inherits from otherInterface. - If there is no such interface, returns None. - """ - if self.parent: - if self.parent == otherInterface: - return self - loopPoint = self.parent.findInterfaceLoopPoint(otherInterface) - if loopPoint: - return loopPoint - return None - - def setNonPartial(self, location, parent, members): - assert not parent or isinstance(parent, IDLIdentifierPlaceholder) - IDLInterfaceOrInterfaceMixinOrNamespace.setNonPartial(self, location, members) - assert not self.parent - self.parent = parent - - def getJSImplementation(self): - classId = self.getExtendedAttribute("JSImplementation") - if not classId: - return classId - assert isinstance(classId, list) - assert len(classId) == 1 - return classId[0] - - def isJSImplemented(self): - return bool(self.getJSImplementation()) - - def hasProbablyShortLivingWrapper(self): - current = self - while current: - if current.getExtendedAttribute("ProbablyShortLivingWrapper"): - return True - current = current.parent - return False - - def hasChildInterfaces(self): - return self._hasChildInterfaces - - def isOnGlobalProtoChain(self): - return self._isOnGlobalProtoChain - - def isPseudoInterface(self): - return self._isPseudo - - def _getDependentObjects(self): - deps = set(self.members) - deps.update(self.includedMixins) - if self.parent: - deps.add(self.parent) - return deps - - def hasMembersInSlots(self): - return self._ownMembersInSlots != 0 - - 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 - ) - - -class IDLInterface(IDLInterfaceOrNamespace): - 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): - return "Interface '%s'" % self.identifier.name - - def isInterface(self): - return True - - def getClassName(self): - if self.classNameOverride: - return self.classNameOverride - return IDLInterfaceOrNamespace.getClassName(self) - - def addExtendedAttributes(self, attrs): - for attr in attrs: - identifier = attr.identifier() - - # Special cased attrs - if identifier == "TreatNonCallableAsNull": - 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( - "[LegacyNoInterfaceObject] must take no arguments", - [attr.location], - ) - - self._noInterfaceObject = True - elif identifier == "LegacyFactoryFunction": - if not attr.hasValue(): - raise WebIDLError( - "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 - # throw (since there's no way to indicate otherwise). - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("Throws",))] - ) - - # We need to detect conflicts for LegacyFactoryFunctions across - # interfaces. We first call resolve on the parentScope, - # 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 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 - # LegacyFactoryFunctions. - newMethod = self.parentScope.lookupIdentifier(method.identifier) - if newMethod == method: - 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] - ) - if self.parent: - 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()] - elif attr.hasArgs(): - self.globalNames = attr.args() - else: - self.globalNames = [self.identifier.name] - self.parentScope.addIfaceGlobalNames( - self.identifier.name, self.globalNames - ) - self._isOnGlobalProtoChain = True - elif identifier == "LegacyWindowAlias": - if attr.hasValue(): - self.legacyWindowAliases = [attr.value()] - elif attr.hasArgs(): - self.legacyWindowAliases = attr.args() - else: - 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] - ) - # 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], - ) - member.addExtendedAttributes([attr]) - 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] - ) - elif identifier == "Exposed": - 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] - ) - elif identifier == "InstrumentedProps": - # Known extended attributes that take a list - if not attr.hasArgs(): - raise WebIDLError( - "[%s] must have arguments" % identifier, [attr.location] - ) - else: - raise WebIDLError( - "Unknown extended attribute %s on interface" % identifier, - [attr.location], - ) - - attrlist = attr.listValue() - self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True - - def validate(self): - IDLInterfaceOrNamespace.validate(self) - if self.parent and self.isSerializable() and not self.parent.isSerializable(): - raise WebIDLError( - "Serializable interface inherits from non-serializable " - "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], - ) - - def isSerializable(self): - return self.getExtendedAttribute("Serializable") - - def setNonPartial(self, location, parent, members): - # Before we do anything else, finish initializing any constructors that - # might be in "members", so we don't have partially-initialized objects - # hanging around. We couldn't do it before now because we needed to have - # to have the IDLInterface on hand to properly set the return type. - for member in members: - if isinstance(member, IDLConstructor): - member.reallyInit(self) - - IDLInterfaceOrNamespace.setNonPartial(self, location, parent, members) - - -class IDLNamespace(IDLInterfaceOrNamespace): - def __init__(self, location, parentScope, name, members, isKnownNonPartial): - IDLInterfaceOrNamespace.__init__( - self, location, parentScope, name, None, members, isKnownNonPartial - ) - - def __str__(self): - return "Namespace '%s'" % self.identifier.name - - def isNamespace(self): - return True - - def addExtendedAttributes(self, attrs): - # The set of things namespaces support is small enough it's simpler - # to factor out into a separate method than it is to sprinkle - # isNamespace() checks all through - # IDLInterfaceOrNamespace.addExtendedAttributes. - for attr in attrs: - identifier = attr.identifier() - - if identifier == "Exposed": - 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": - if not attr.noArguments(): - 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] - ) - else: - raise WebIDLError( - "Unknown extended attribute %s on namespace" % identifier, - [attr.location], - ) - - attrlist = attr.listValue() - self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True - - def isSerializable(self): - return False - - -class IDLDictionary(IDLObjectWithScope): - def __init__(self, location, parentScope, name, parent, members): - assert isinstance(parentScope, IDLScope) - assert isinstance(name, IDLUnresolvedIdentifier) - assert not parent or isinstance(parent, IDLIdentifierPlaceholder) - - self.parent = parent - self._finished = False - self.members = list(members) - self._partialDictionaries = [] - self._extendedAttrDict = {} - self.needsConversionToJS = False - self.needsConversionFromJS = False - - IDLObjectWithScope.__init__(self, location, parentScope, name) - - def __str__(self): - return "Dictionary '%s'" % self.identifier.name - - def isDictionary(self): - return True - - def canBeEmpty(self): - """ - 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() - ) - - def finish(self, scope): - if self._finished: - return - - self._finished = True - - if self.parent: - assert isinstance(self.parent, IDLIdentifierPlaceholder) - 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], - ) - - # Make sure the parent resolves all its members before we start - # looking at them. - self.parent.finish(scope) - - # Now go ahead and merge in our partial dictionaries. - for partial in self._partialDictionaries: - partial.finish(scope) - self.members.extend(partial.members) - - for member in self.members: - member.resolve(self) - if not member.isComplete(): - member.complete(scope) - assert member.type.isComplete() - - # 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], - ) - inheritedMembers.extend(ancestor.members) - ancestor = ancestor.parent - - # Catch name duplication - 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], - ) - - def validate(self): - def typeContainsDictionary(memberType, dictionary): - """ - Returns a tuple whose: - - - First element is a Boolean value indicating whether - memberType contains dictionary. - - - Second element is: - A list of locations that leads from the type that was passed in - the memberType argument, to the dictionary being validated, - if the boolean value in the first element is True. - - None, if the boolean value in the first element is False. - """ - - 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 - ) - if contains: - return (True, [memberType.location] + locations) - - if memberType.isUnion(): - for member in memberType.flatMemberTypes: - (contains, locations) = typeContainsDictionary(member, dictionary) - if contains: - return (True, locations) - - return (False, None) - - def dictionaryContainsDictionary(dictMember, dictionary): - for member in dictMember.members: - (contains, locations) = typeContainsDictionary(member.type, dictionary) - if contains: - return (True, [member.location] + locations) - - if dictMember.parent: - if dictMember.parent == dictionary: - return (True, [dictMember.location]) - else: - (contains, locations) = dictionaryContainsDictionary( - dictMember.parent, dictionary - ) - if contains: - return (True, [dictMember.location] + locations) - - return (False, None) - - 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], - ) - (contains, locations) = typeContainsDictionary(member.type, self) - if contains: - 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) - - def addExtendedAttributes(self, attrs): - for attr in attrs: - identifier = attr.identifier() - - if identifier == "GenerateInitFromJSON" or identifier == "GenerateInit": - if not attr.noArguments(): - raise WebIDLError( - "[%s] must not have arguments" % identifier, [attr.location] - ) - self.needsConversionFromJS = True - elif ( - identifier == "GenerateConversionToJS" or identifier == "GenerateToJSON" - ): - if not attr.noArguments(): - 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], - ) - - self._extendedAttrDict[identifier] = True - - def _getDependentObjects(self): - deps = set(self.members) - if self.parent: - deps.add(self.parent) - return deps - - def addPartialDictionary(self, partial): - assert self.identifier.name == partial.identifier.name - self._partialDictionaries.append(partial) - - -class IDLEnum(IDLObjectWithIdentifier): - def __init__(self, location, parentScope, name, values): - assert isinstance(parentScope, IDLScope) - assert isinstance(name, IDLUnresolvedIdentifier) - - if len(values) != len(set(values)): - raise WebIDLError( - "Enum %s has multiple identical strings" % name.name, [location] - ) - - IDLObjectWithIdentifier.__init__(self, location, parentScope, name) - self._values = values - - def values(self): - return self._values - - def finish(self, scope): - pass - - def validate(self): - pass - - def isEnum(self): - return True - - 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], - ) - - def _getDependentObjects(self): - return set() - - -class IDLType(IDLObject): - Tags = enum( - # The integer types - "int8", - "uint8", - "int16", - "uint16", - "int32", - "uint32", - "int64", - "uint64", - # Additional primitive types - "bool", - "unrestricted_float", - "float", - "unrestricted_double", - # "double" last primitive type to match IDLBuiltinType - "double", - # Other types - "any", - "undefined", - "domstring", - "bytestring", - "usvstring", - "utf8string", - "jsstring", - "object", - # Funny stuff - "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.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.legacyNullToEmptyString == other.legacyNullToEmptyString - and self._allowShared == other.hasAllowShared() - ) - - def __ne__(self, other): - return not self == other - - def __str__(self): - return str(self.name) - - def prettyName(self): - """ - A name that looks like what this type is named in the IDL spec. By default - this is just our .name, but types that have more interesting spec - representations should override this. - """ - return str(self.name) - - def isType(self): - return True - - def nullable(self): - return False - - def isPrimitive(self): - return False - - def isBoolean(self): - return False - - def isNumeric(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 isRecord(self): - return False - - def isReadableStream(self): - return False - - def isArrayBuffer(self): - return False - - def isArrayBufferView(self): - return False - - def isTypedArray(self): - return False - - def isBufferSource(self): - return self.isArrayBuffer() or self.isArrayBufferView() or self.isTypedArray() - - def isCallbackInterface(self): - return False - - def isNonCallbackInterface(self): - 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.""" - 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 isAny(self): - return self.tag() == IDLType.Tags.any - - def isObject(self): - return self.tag() == IDLType.Tags.object - - def isPromise(self): - return False - - def isComplete(self): - return True - - def includesRestrictedFloat(self): - return False - - def isFloat(self): - return False - - def isUnrestricted(self): - # Should only call this on float types - assert self.isFloat() - - 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 - - def hasEnforceRange(self): - return self._enforceRange - - def hasAllowShared(self): - return self._allowShared - - def tag(self): - assert False # Override me! - - def treatNonCallableAsNull(self): - assert self.tag() == IDLType.Tags.callback - return self.nullable() and self.inner.callback._treatNonCallableAsNull - - def treatNonObjectAsNull(self): - assert self.tag() == IDLType.Tags.callback - return self.nullable() and self.inner.callback._treatNonObjectAsNull - - def withExtendedAttributes(self, attrs): - if len(attrs) > 0: - raise WebIDLError( - "Extended attributes on types only supported for builtins", - [attrs[0].location, self.location], - ) - return self - - def getExtendedAttribute(self, name): - return self._extendedAttrDict.get(name, None) - - def resolveType(self, parentScope): - pass - - def unroll(self): - return self - - def isDistinguishableFrom(self, other): - raise TypeError( - "Can't tell whether a generic type is or is not " - "distinguishable from other things" - ) - - def isExposedInAllOf(self, exposureSet): - return True - - -class IDLUnresolvedType(IDLType): - """ - Unresolved types are interface types - """ - - def __init__(self, location, name, attrs=[]): - IDLType.__init__(self, location, name) - self.extraTypeAttributes = attrs - - def isComplete(self): - return False - - def complete(self, scope): - obj = None - try: - obj = scope._lookupIdentifier(self.name) - except: - raise WebIDLError("Unresolved type '%s'." % self.name, [self.location]) - - assert obj - assert not obj.isType() - if obj.isTypedef(): - assert self.name.name == obj.identifier.name - typedefType = IDLTypedefType(self.location, obj.innerType, obj.identifier) - assert not typedefType.isComplete() - 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) - - name = self.name.resolve(scope, None) - return IDLWrapperType(self.location, obj) - - def withExtendedAttributes(self, attrs): - 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" - ) - - -class IDLParametrizedType(IDLType): - def __init__(self, location, name, innerType): - IDLType.__init__(self, location, name) - self.builtin = False - self.inner = innerType - - def includesRestrictedFloat(self): - return self.inner.includesRestrictedFloat() - - def resolveType(self, parentScope): - assert isinstance(parentScope, IDLScope) - self.inner.resolveType(parentScope) - - def isComplete(self): - return self.inner.isComplete() - - def unroll(self): - return self.inner.unroll() - - def _getDependentObjects(self): - return self.inner._getDependentObjects() - - -class IDLNullableType(IDLParametrizedType): - def __init__(self, location, innerType): - assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any] - - IDLParametrizedType.__init__(self, location, None, innerType) - - 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" - - def prettyName(self): - return self.inner.prettyName() + "?" - - def nullable(self): - return True - - def isCallback(self): - return self.inner.isCallback() - - def isPrimitive(self): - return self.inner.isPrimitive() - - def isBoolean(self): - return self.inner.isBoolean() - - def isNumeric(self): - return self.inner.isNumeric() - - def isString(self): - return self.inner.isString() - - def isByteString(self): - return self.inner.isByteString() - - def isDOMString(self): - return self.inner.isDOMString() - - def isUSVString(self): - return self.inner.isUSVString() - - def isUTF8String(self): - return self.inner.isUTF8String() - - def isJSString(self): - return self.inner.isJSString() - - def isFloat(self): - return self.inner.isFloat() - - def isUnrestricted(self): - return self.inner.isUnrestricted() - - def isInteger(self): - return self.inner.isInteger() - - def isUndefined(self): - return self.inner.isUndefined() - - def isSequence(self): - return self.inner.isSequence() - - def isRecord(self): - return self.inner.isRecord() - - def isReadableStream(self): - return self.inner.isReadableStream() - - def isArrayBuffer(self): - return self.inner.isArrayBuffer() - - def isArrayBufferView(self): - return self.inner.isArrayBufferView() - - def isTypedArray(self): - return self.inner.isTypedArray() - - def isDictionary(self): - return self.inner.isDictionary() - - def isInterface(self): - return self.inner.isInterface() - - def isPromise(self): - # There is no such thing as a nullable Promise. - assert not self.inner.isPromise() - return False - - def isCallbackInterface(self): - return self.inner.isCallbackInterface() - - def isNonCallbackInterface(self): - return self.inner.isNonCallbackInterface() - - def isEnum(self): - return self.inner.isEnum() - - def isUnion(self): - return self.inner.isUnion() - - def isJSONType(self): - return self.inner.isJSONType() - - def isObservableArray(self): - return self.inner.isObservableArray() - - def hasClamp(self): - return self.inner.hasClamp() - - def hasEnforceRange(self): - return self.inner.hasEnforceRange() - - def hasAllowShared(self): - return self.inner.hasAllowShared() - - def isComplete(self): - return self.name is not None - - def tag(self): - return self.inner.tag() - - def complete(self, scope): - if not self.inner.isComplete(): - self.inner = self.inner.complete(scope) - 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], - ) - 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], - ) - if self.inner.isDOMString(): - 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()) - ) - ): - # Can't tell which type null should become - return False - return self.inner.isDistinguishableFrom(other) - - def withExtendedAttributes(self, attrs): - # See https://github.com/heycam/webidl/issues/827#issuecomment-565131350 - # Allowing extended attributes to apply to a nullable type is an intermediate solution. - # A potential longer term solution is to introduce a null type and get rid of nullables. - # For example, we could do `([Clamp] long or null) foo` in the future. - return IDLNullableType(self.location, self.inner.withExtendedAttributes(attrs)) - - -class IDLSequenceType(IDLParametrizedType): - def __init__(self, location, parameterType): - assert not parameterType.isUndefined() - - IDLParametrizedType.__init__(self, location, parameterType.name, parameterType) - # Need to set self.name up front if our inner type is already complete, - # since in that case our .complete() won't be called. - if self.inner.isComplete(): - self.name = self.inner.name + "Sequence" - - 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 isSequence(self): - return True - - def isJSONType(self): - return self.inner.isJSONType() - - def tag(self): - 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 - - def isDistinguishableFrom(self, other): - if other.isPromise(): - return False - if other.isUnion(): - # Just forward to the union; it'll deal - return other.isDistinguishableFrom(self) - 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): - def __init__(self, location, keyType, valueType): - assert keyType.isString() - assert keyType.isComplete() - assert not valueType.isUndefined() - - IDLParametrizedType.__init__(self, location, valueType.name, valueType) - self.keyType = keyType - - # Need to set self.name up front if our inner type is already complete, - # since in that case our .complete() won't be called. - 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 - - def __str__(self): - return self.keyType.__str__() + self.inner.__str__() + "Record" - - def prettyName(self): - return "record<%s, %s>" % (self.keyType.prettyName(), self.inner.prettyName()) - - def isRecord(self): - return True - - def isJSONType(self): - return self.inner.isJSONType() - - def tag(self): - 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 - - def unroll(self): - # We do not unroll our inner. Just stop at ourselves. That - # lets us add headers for both ourselves and our inner as - # needed. - return self - - def isDistinguishableFrom(self, other): - if other.isPromise(): - return False - 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() - ) - - 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, "") - self.memberTypes = memberTypes - self.hasNullableType = False - self._dictionaryType = None - self.flatMemberTypes = None - self.builtin = False - - def __eq__(self, other): - return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes - - def __hash__(self): - assert self.isComplete() - return self.name.__hash__() - - def prettyName(self): - return "(" + " or ".join(m.prettyName() for m in self.memberTypes) + ")" - - def isUnion(self): - return True - - def isJSONType(self): - return all(m.isJSONType() for m in self.memberTypes) - - def includesRestrictedFloat(self): - return any(t.includesRestrictedFloat() for t in self.memberTypes) - - def tag(self): - return IDLType.Tags.union - - def resolveType(self, parentScope): - assert isinstance(parentScope, IDLScope) - for t in self.memberTypes: - t.resolveType(parentScope) - - def isComplete(self): - return self.flatMemberTypes is not None - - def complete(self, scope): - def typeName(type): - if isinstance(type, IDLNullableType): - return typeName(type.inner) + "OrNull" - if isinstance(type, IDLWrapperType): - return typeName(type._identifier.object()) - if isinstance(type, IDLObjectWithIdentifier): - return typeName(type.identifier) - if isinstance(type, IDLBuiltinType) and type.hasAllowShared(): - assert type.isBufferSource() - 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): - if not type.isComplete(): - self.memberTypes[i] = type.complete(scope) - - self.flatMemberTypes = list(self.memberTypes) - i = 0 - 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], - ) - 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, - ], - ) - 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], - ) - 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 - continue - i += 1 - - for (i, t) in enumerate(self.flatMemberTypes[:-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], - ) - - return self - - def isDistinguishableFrom(self, other): - if self.hasNullableType and other.nullable(): - # Can't tell which type null should become - return False - if other.isUnion(): - otherTypes = other.unroll().memberTypes - else: - otherTypes = [other] - # For every type in otherTypes, check that it's distinguishable from - # every type in our types - for u in otherTypes: - if any(not t.isDistinguishableFrom(u) for t in self.memberTypes): - return False - 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. - for globalName in exposureSet: - if not any( - t.unroll().isExposedInAllOf(set([globalName])) - for t in self.flatMemberTypes - ): - return False - return True - - def hasDictionaryType(self): - return self._dictionaryType is not None - - def hasPossiblyEmptyDictionaryType(self): - return ( - self._dictionaryType is not None and self._dictionaryType.inner.canBeEmpty() - ) - - def _getDependentObjects(self): - return set(self.memberTypes) - - -class IDLTypedefType(IDLType): - def __init__(self, location, innerType, name): - IDLType.__init__(self, location, name) - 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 - - def __str__(self): - return self.name - - def nullable(self): - return self.inner.nullable() - - def isPrimitive(self): - return self.inner.isPrimitive() - - def isBoolean(self): - return self.inner.isBoolean() - - def isNumeric(self): - return self.inner.isNumeric() - - def isString(self): - return self.inner.isString() - - def isByteString(self): - return self.inner.isByteString() - - def isDOMString(self): - return self.inner.isDOMString() - - def isUSVString(self): - return self.inner.isUSVString() - - def isUTF8String(self): - return self.inner.isUTF8String() - - def isJSString(self): - return self.inner.isJSString() - - def isUndefined(self): - return self.inner.isUndefined() - - def isJSONType(self): - return self.inner.isJSONType() - - def isSequence(self): - return self.inner.isSequence() - - def isRecord(self): - return self.inner.isRecord() - - def isReadableStream(self): - return self.inner.isReadableStream() - - def isDictionary(self): - return self.inner.isDictionary() - - def isArrayBuffer(self): - return self.inner.isArrayBuffer() - - def isArrayBufferView(self): - return self.inner.isArrayBufferView() - - def isTypedArray(self): - return self.inner.isTypedArray() - - def isInterface(self): - return self.inner.isInterface() - - def isCallbackInterface(self): - return self.inner.isCallbackInterface() - - def isNonCallbackInterface(self): - return self.inner.isNonCallbackInterface() - - def isComplete(self): - return False - - def complete(self, parentScope): - if not self.inner.isComplete(): - self.inner = self.inner.complete(parentScope) - assert self.inner.isComplete() - return self.inner - - # Do we need a resolveType impl? I don't think it's particularly useful.... - - def tag(self): - return self.inner.tag() - - def unroll(self): - return self.inner.unroll() - - def isDistinguishableFrom(self, other): - return self.inner.isDistinguishableFrom(other) - - def _getDependentObjects(self): - return self.inner._getDependentObjects() - - def withExtendedAttributes(self, attrs): - return IDLTypedefType( - self.location, self.inner.withExtendedAttributes(attrs), self.name - ) - - -class IDLTypedef(IDLObjectWithIdentifier): - def __init__(self, location, parentScope, innerType, name): - # Set self.innerType first, because IDLObjectWithIdentifier.__init__ - # will call our __str__, which wants to use it. - self.innerType = innerType - identifier = IDLUnresolvedIdentifier(location, name) - IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier) - - def __str__(self): - return "Typedef %s %s" % (self.identifier.name, self.innerType) - - def finish(self, parentScope): - if not self.innerType.isComplete(): - self.innerType = self.innerType.complete(parentScope) - - def validate(self): - pass - - def isTypedef(self): - return True - - 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], - ) - - def _getDependentObjects(self): - return self.innerType._getDependentObjects() - - -class IDLWrapperType(IDLType): - def __init__(self, location, inner): - IDLType.__init__(self, location, inner.identifier.name) - self.inner = inner - self._identifier = inner.identifier - self.builtin = False - - def __hash__(self): - 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 isDictionary(self): - return isinstance(self.inner, IDLDictionary) - - def isInterface(self): - return isinstance(self.inner, IDLInterface) or isinstance( - self.inner, IDLExternalInterface - ) - - def isCallbackInterface(self): - return self.isInterface() and self.inner.isCallback() - - def isNonCallbackInterface(self): - return self.isInterface() and not self.inner.isCallback() - - def isEnum(self): - return isinstance(self.inner, IDLEnum) - - def isJSONType(self): - if self.isInterface(): - if self.inner.isExternal(): - return False - iface = self.inner - while iface: - if any(m.isMethod() and m.isToJSON() for m in iface.members): - return True - iface = iface.parent - return False - elif self.isEnum(): - return True - elif self.isDictionary(): - dictionary = self.inner - while dictionary: - if not all(m.type.isJSONType() for m in dictionary.members): - return False - 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], - ) - - def resolveType(self, parentScope): - assert isinstance(parentScope, IDLScope) - self.inner.resolve(parentScope) - - def isComplete(self): - return True - - def tag(self): - if self.isInterface(): - return IDLType.Tags.interface - elif self.isEnum(): - return IDLType.Tags.enum - elif self.isDictionary(): - return IDLType.Tags.dictionary - else: - assert False - - def isDistinguishableFrom(self, other): - if other.isPromise(): - return False - if other.isUnion(): - # Just forward to the union; it'll deal - return other.isDistinguishableFrom(self) - assert self.isInterface() or self.isEnum() or self.isDictionary() - if self.isEnum(): - 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() - ): - return True - if self.isDictionary(): - return other.isNonCallbackInterface() - - assert self.isInterface() - if other.isInterface(): - 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() - - # Not much else |other| can be - assert other.isObject() - return False - - def isExposedInAllOf(self, exposureSet): - if not self.isInterface(): - return True - iface = self.inner - if iface.isExternal(): - # Let's say true, so we don't have to implement exposure mixins on - # external interfaces and sprinkle [Exposed=Window] on every single - # external interface declaration. - return True - return iface.exposureSet.issuperset(exposureSet) - - def _getDependentObjects(self): - # NB: The codegen for an interface type depends on - # a) That the identifier is in fact an interface (as opposed to - # a dictionary or something else). - # b) The native type of the interface. - # If we depend on the interface object we will also depend on - # anything the interface depends on which is undesirable. We - # considered implementing a dependency just on the interface type - # file, but then every modification to an interface would cause this - # to be regenerated which is still undesirable. We decided not to - # depend on anything, reasoning that: - # 1) Changing the concrete type of the interface requires modifying - # Bindings.conf, which is still a global dependency. - # 2) Changing an interface to a dictionary (or vice versa) with the - # same identifier should be incredibly rare. - # - # On the other hand, if our type is a dictionary, we should - # depend on it, because the member types of a dictionary - # affect whether a method taking the dictionary as an argument - # takes a JSContext* argument or not. - if self.isDictionary(): - return set([self.inner]) - return set() - - -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() - ) - - def __str__(self): - return self.inner.__str__() + "Promise" - - def prettyName(self): - return "Promise<%s>" % self.inner.prettyName() - - def isPromise(self): - return True - - def promiseInnerType(self): - return self.inner - - def tag(self): - 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 - - def unroll(self): - # We do not unroll our inner. Just stop at ourselves. That - # lets us add headers for both ourselves and our inner as - # needed. - return self - - def isDistinguishableFrom(self, other): - # Promises are not distinguishable from anything. - return False - - def isExposedInAllOf(self, exposureSet): - # Check the internal type - return self.promiseInnerType().unroll().isExposedInAllOf(exposureSet) - - -class IDLBuiltinType(IDLType): - - Types = enum( - # The integer types - "byte", - "octet", - "short", - "unsigned_short", - "long", - "unsigned_long", - "long_long", - "unsigned_long_long", - # Additional primitive types - "boolean", - "unrestricted_float", - "float", - "unrestricted_double", - # IMPORTANT: "double" must be the last primitive type listed - "double", - # Other types - "any", - "undefined", - "domstring", - "bytestring", - "usvstring", - "utf8string", - "jsstring", - "object", - # Funny stuff - "ArrayBuffer", - "ArrayBufferView", - "Int8Array", - "Uint8Array", - "Uint8ClampedArray", - "Int16Array", - "Uint16Array", - "Int32Array", - "Uint32Array", - "Float32Array", - "Float64Array", - "ReadableStream", - ) - - TagLookup = { - Types.byte: IDLType.Tags.int8, - Types.octet: IDLType.Tags.uint8, - Types.short: IDLType.Tags.int16, - Types.unsigned_short: IDLType.Tags.uint16, - Types.long: IDLType.Tags.int32, - Types.unsigned_long: IDLType.Tags.uint32, - Types.long_long: IDLType.Tags.int64, - Types.unsigned_long_long: IDLType.Tags.uint64, - Types.boolean: IDLType.Tags.bool, - Types.unrestricted_float: IDLType.Tags.unrestricted_float, - Types.float: IDLType.Tags.float, - 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.ArrayBuffer: IDLType.Tags.interface, - Types.ArrayBufferView: IDLType.Tags.interface, - Types.Int8Array: IDLType.Tags.interface, - Types.Uint8Array: IDLType.Tags.interface, - Types.Uint8ClampedArray: IDLType.Tags.interface, - Types.Int16Array: IDLType.Tags.interface, - Types.Uint16Array: IDLType.Tags.interface, - Types.Int32Array: IDLType.Tags.interface, - Types.Uint32Array: IDLType.Tags.interface, - Types.Float32Array: IDLType.Tags.interface, - Types.Float64Array: IDLType.Tags.interface, - Types.ReadableStream: IDLType.Tags.interface, - } - - PrettyNames = { - Types.byte: "byte", - Types.octet: "octet", - Types.short: "short", - Types.unsigned_short: "unsigned short", - Types.long: "long", - Types.unsigned_long: "unsigned long", - Types.long_long: "long long", - Types.unsigned_long_long: "unsigned long long", - Types.boolean: "boolean", - Types.unrestricted_float: "unrestricted float", - Types.float: "float", - 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.object: "object", - Types.ArrayBuffer: "ArrayBuffer", - Types.ArrayBufferView: "ArrayBufferView", - Types.Int8Array: "Int8Array", - Types.Uint8Array: "Uint8Array", - Types.Uint8ClampedArray: "Uint8ClampedArray", - Types.Int16Array: "Int16Array", - Types.Uint16Array: "Uint16Array", - Types.Int32Array: "Int32Array", - Types.Uint32Array: "Uint32Array", - Types.Float32Array: "Float32Array", - Types.Float64Array: "Float64Array", - Types.ReadableStream: "ReadableStream", - } - - 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(), .withLegacyNullToEmptyString() and .withAllowShared(). - - attrLocation is an array of source locations of these attributes for error reporting. - """ - IDLType.__init__(self, location, name) - self.builtin = True - self._typeTag = type - self._clamped = None - self._rangeEnforced = None - self._withLegacyNullToEmptyString = None - self._withAllowShared = None - if self.isInteger(): - if clamp: - self._clamp = True - self.name = "Clamped" + self.name - self._extendedAttrDict["Clamp"] = True - elif enforceRange: - self._enforceRange = True - self.name = "RangeEnforced" + self.name - self._extendedAttrDict["EnforceRange"] = True - elif clamp or enforceRange: - raise WebIDLError( - "Non-integer types cannot be [Clamp] or [EnforceRange]", attrLocation - ) - if self.isDOMString() or self.isUTF8String(): - if legacyNullToEmptyString: - self.legacyNullToEmptyString = True - self.name = "NullIsEmpty" + self.name - 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, - ) - - def __str__(self): - if self._allowShared: - assert self.isBufferSource() - return "MaybeShared" + str(self.name) - return str(self.name) - - 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, - ) - return self._clamped - - def rangeEnforced(self, attrLocation): - if not self._rangeEnforced: - self._rangeEnforced = IDLBuiltinType( - self.location, - self.name, - self._typeTag, - enforceRange=True, - attrLocation=attrLocation, - ) - return self._rangeEnforced - - 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, - ) - return self._withAllowShared - - def isPrimitive(self): - return self._typeTag <= IDLBuiltinType.Types.double - - 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 - ) - - def isByteString(self): - return self._typeTag == IDLBuiltinType.Types.bytestring - - def isDOMString(self): - return self._typeTag == IDLBuiltinType.Types.domstring - - def isUSVString(self): - return self._typeTag == IDLBuiltinType.Types.usvstring - - def isUTF8String(self): - return self._typeTag == IDLBuiltinType.Types.utf8string - - def isJSString(self): - return self._typeTag == IDLBuiltinType.Types.jsstring - - def isInteger(self): - return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long - - def isArrayBuffer(self): - return self._typeTag == IDLBuiltinType.Types.ArrayBuffer - - def isArrayBufferView(self): - 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 - - 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() - ) - - 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 - ) - - def isUnrestricted(self): - assert self.isFloat() - 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() - - def includesRestrictedFloat(self): - return self.isFloat() and not self.isUnrestricted() - - def tag(self): - return IDLBuiltinType.TagLookup[self._typeTag] - - def isDistinguishableFrom(self, other): - if other.isPromise(): - return False - if other.isUnion(): - # Just forward to the union; it'll deal - return other.isDistinguishableFrom(self) - 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.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.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.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 (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) - ) - ) - ) - ) - - def _getDependentObjects(self): - return set() - - def withExtendedAttributes(self, attrs): - ret = self - for attribute in attrs: - identifier = attribute.identifier() - if identifier == "Clamp": - if not attribute.noArguments(): - 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], - ) - ret = self.clamped([self.location, attribute.location]) - elif identifier == "EnforceRange": - if not attribute.noArguments(): - 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], - ) - ret = self.rangeEnforced([self.location, attribute.location]) - elif identifier == "LegacyNullToEmptyString": - if not (self.isDOMString() or self.isUTF8String()): - raise WebIDLError( - "[LegacyNullToEmptyString] only allowed on DOMStrings and UTF8Strings", - [self.location, attribute.location], - ) - assert not self.nullable() - 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] - ) - if not self.isBufferSource(): - 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], - ) - 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.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, - ), - IDLBuiltinType.Types.ReadableStream: IDLBuiltinType( - BuiltinLocation("<builtin type>"), - "ReadableStream", - IDLBuiltinType.Types.ReadableStream, - ), -} - - -integerTypeSizes = { - IDLBuiltinType.Types.byte: (-128, 127), - 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), -} - - -def matchIntegerValueToType(value): - 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) - self.type = type - assert isinstance(type, IDLType) - - self.value = value - - def coerceToType(self, type, location): - if type == self.type: - return self # Nothing to do - - # We first check for unions to ensure that even if the union is nullable - # we end up with the right flat member type, not the union's type. - if type.isUnion(): - # We use the flat member types here, because if we have a nullable - # member type, or a nested union, we want the type the value - # actually coerces to, not the nullable or nested union type. - for subtype in type.unroll().flatMemberTypes: - try: - coercedValue = self.coerceToType(subtype, location) - # Create a new IDLValue to make sure that we have the - # correct float/double type. This is necessary because we - # use the value's type when it is a default value of a - # union, and the union cares about the exact float type. - return IDLValue(self.location, subtype, coercedValue.value) - except Exception as e: - # Make sure to propagate out WebIDLErrors that are not the - # generic "hey, we could not coerce to this type at all" - # exception, because those are specific "coercion failed for - # reason X" exceptions. Note that we want to swallow - # 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 - ): - raise e - - # If the type allows null, rerun this matching on the inner type, except - # nullable enums. We handle those specially, because we want our - # default string values to stay strings even when assigned to a nullable - # enum. - elif type.nullable() and not type.isEnum(): - innerValue = self.coerceToType(type.inner, location) - return IDLValue(self.location, type, innerValue.value) - - elif self.type.isInteger() and type.isInteger(): - # We're both integer types. See if we fit. - - (min, max) = integerTypeSizes[type._typeTag] - if self.value <= max and self.value >= min: - # Promote - return IDLValue(self.location, type, self.value) - else: - 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: - return IDLValue(self.location, type, float(self.value)) - else: - 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 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], - ) - return IDLValue(self.location, type, self.value) - elif self.type.isString() and type.isUSVString(): - # Allow USVStrings to use default value just like - # DOMString. No coercion is required in this case as Codegen.py - # treats USVString just like DOMString, but with an - # extra normalization step. - assert self.type.isDOMString() - return self - 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 - ) - 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], - ) - - 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] - ) - - def _getDependentObjects(self): - return set() - - -class IDLNullValue(IDLObject): - def __init__(self, location): - IDLObject.__init__(self, location) - self.type = None - 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]) - - nullValue = IDLNullValue(self.location) - if type.isUnion() and not type.nullable() and type.hasDictionaryType(): - # We're actually a default value for the union's dictionary member. - # Use its type. - for t in type.flatMemberTypes: - if t.isDictionary(): - nullValue.type = t - return nullValue - nullValue.type = type - return nullValue - - def _getDependentObjects(self): - return set() - - -class IDLEmptySequenceValue(IDLObject): - def __init__(self, location): - IDLObject.__init__(self, location) - self.type = None - self.value = None - - def coerceToType(self, type, location): - if type.isUnion(): - # We use the flat member types here, because if we have a nullable - # member type, or a nested union, we want the type the value - # actually coerces to, not the nullable or nested union type. - for subtype in type.unroll().flatMemberTypes: - try: - return self.coerceToType(subtype, location) - except: - pass - - if not type.isSequence(): - raise WebIDLError( - "Cannot coerce empty sequence value to type %s." % type, [location] - ) - - emptySequenceValue = IDLEmptySequenceValue(self.location) - emptySequenceValue.type = type - return emptySequenceValue - - def _getDependentObjects(self): - return set() - - -class IDLDefaultDictionaryValue(IDLObject): - def __init__(self, location): - IDLObject.__init__(self, location) - self.type = None - self.value = None - - def coerceToType(self, type, location): - if type.isUnion(): - # We use the flat member types here, because if we have a nullable - # member type, or a nested union, we want the type the value - # actually coerces to, not the nullable or nested union type. - for subtype in type.unroll().flatMemberTypes: - try: - return self.coerceToType(subtype, location) - except: - pass - - if not type.isDictionary(): - raise WebIDLError( - "Cannot coerce default dictionary value to type %s." % type, [location] - ) - - defaultDictionaryValue = IDLDefaultDictionaryValue(self.location) - defaultDictionaryValue.type = type - return defaultDictionaryValue - - def _getDependentObjects(self): - return set() - - -class IDLUndefinedValue(IDLObject): - def __init__(self, location): - IDLObject.__init__(self, location) - self.type = None - self.value = None - - def coerceToType(self, type, location): - if not type.isAny(): - raise WebIDLError( - "Cannot coerce undefined value to type %s." % type, [location] - ) - - undefinedValue = IDLUndefinedValue(self.location) - undefinedValue.type = type - return undefinedValue - - def _getDependentObjects(self): - return set() - - -class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins): - - Tags = enum( - "Const", "Attr", "Method", "MaplikeOrSetlike", "AsyncIterable", "Iterable" - ) - - Special = enum("Static", "Stringifier") - - AffectsValues = ("Nothing", "Everything") - DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything") - - def __init__(self, location, identifier, tag, extendedAttrDict=None): - IDLObjectWithIdentifier.__init__(self, location, None, identifier) - IDLExposureMixins.__init__(self, location) - self.tag = tag - if extendedAttrDict is None: - self._extendedAttrDict = {} - else: - self._extendedAttrDict = extendedAttrDict - - def isMethod(self): - return self.tag == IDLInterfaceMember.Tags.Method - - def isAttr(self): - return self.tag == IDLInterfaceMember.Tags.Attr - - def isConst(self): - return self.tag == IDLInterfaceMember.Tags.Const - - def isMaplikeOrSetlikeOrIterable(self): - 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 - - def addExtendedAttributes(self, attrs): - for attr in attrs: - self.handleExtendedAttribute(attr) - attrlist = attr.listValue() - self._extendedAttrDict[attr.identifier()] = ( - attrlist if len(attrlist) else True - ) - - def handleExtendedAttribute(self, attr): - pass - - def getExtendedAttribute(self, name): - return self._extendedAttrDict.get(name, None) - - def finish(self, scope): - IDLExposureMixins.finish(self, scope) - - 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], - ) - - 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], - ) - - 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], - ) - if dependsOn not in IDLInterfaceMember.DependsOnValues: - 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], - ) - if affects not in IDLInterfaceMember.AffectsValues: - 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] - ) - self.aliases.append(alias) - - def _addBindingAlias(self, bindingAlias): - if bindingAlias in self.bindingAliases: - raise WebIDLError( - "Duplicate [BindingAlias=%s] on attribute" % bindingAlias, - [self.location], - ) - self.bindingAliases.append(bindingAlias) - - -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", "asynciterable"] - if valueType is not None: - assert isinstance(valueType, IDLType) - self.keyType = keyType - self.valueType = valueType - self.maplikeOrSetlikeOrIterableType = ifaceType - self.disallowedMemberNames = [] - self.disallowedNonMethodNames = [] - - def isMaplike(self): - return self.maplikeOrSetlikeOrIterableType == "maplike" - - def isSetlike(self): - return self.maplikeOrSetlikeOrIterableType == "setlike" - - def isIterable(self): - return self.maplikeOrSetlikeOrIterableType == "iterable" - - def isAsyncIterable(self): - return self.maplikeOrSetlikeOrIterableType == "asynciterable" - - def hasKeyType(self): - return self.keyType is not None - - def hasValueType(self): - return self.valueType is not None - - 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], - ) - # 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, - ): - """ - Create an IDLMethod based on the parameters passed in. - - - members is the member list to add this function to, since this is - called during the member expansion portion of interface object - building. - - - chromeOnly is only True for read-only js implemented classes, to - implement underscore prefixed convenience functions which would - otherwise not be available, unlike the case of C++ bindings. - - - isPure is only True for idempotent functions, so it is not valid for - things like keys, values, etc. that return a new object every time. - - - affectsNothing means that nothing changes due to this method, which - affects JIT optimization behavior - - - newObject means the method creates and returns a new object. - - """ - # Only add name to lists for collision checks if it's not chrome - # only. - if chromeOnly: - name = "__" + name - else: - if not allowExistingOperations: - self.disallowedMemberNames.append(name) - else: - 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. - if allowExistingOperations: - 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, - ) - # We need to be able to throw from declaration methods - method.addExtendedAttributes([IDLExtendedAttribute(self.location, ("Throws",))]) - if chromeOnly: - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("ChromeOnly",))] - ) - if isPure: - method.addExtendedAttributes( - [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")), - ] - ) - if newObject: - method.addExtendedAttributes( - [IDLExtendedAttribute(self.location, ("NewObject",))] - ) - if isIteratorAlias: - 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): - if self.keyType: - self.keyType.resolveType(parentScope) - if self.valueType: - self.valueType.resolveType(parentScope) - - def finish(self, scope): - IDLInterfaceMember.finish(self, scope) - if self.keyType and not self.keyType.isComplete(): - t = self.keyType.complete(scope) - - assert not isinstance(t, IDLUnresolvedType) - assert not isinstance(t, IDLTypedefType) - assert not isinstance(t.name, IDLUnresolvedIdentifier) - self.keyType = t - if self.valueType and not self.valueType.isComplete(): - t = self.valueType.complete(scope) - - assert not isinstance(t, IDLUnresolvedType) - assert not isinstance(t, IDLTypedefType) - assert not isinstance(t.name, IDLUnresolvedIdentifier) - self.valueType = t - - def validate(self): - IDLInterfaceMember.validate(self) - - def handleExtendedAttribute(self, attr): - IDLInterfaceMember.handleExtendedAttribute(self, attr) - - def _getDependentObjects(self): - deps = set() - if self.keyType: - deps.add(self.keyType) - if self.valueType: - deps.add(self.valueType) - 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, - ), - ] - - -# 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, 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, - ) - - 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. - """ - # We only need to add entries/keys/values here if we're a pair iterator. - # Value iterators just copy these from %ArrayPrototype% instead. - if not self.isPairIterator(): - return - - # object entries() - 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, - ) - # object values() - 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(), - ) - - 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() - - 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, - ) - 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" - elif self.isSetlike(): - self.prefix = "Set" - - def __str__(self): - return "declared '%s' with key '%s'" % ( - self.maplikeOrSetlikeOrIterableType, - self.keyType, - ) - - 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 - 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(), - ) - # object keys() - 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(), - ) - - # undefined forEach(callback(valueType, keyType), thisVal) - self.addMethod( - "forEach", - members, - False, - BuiltinTypes[IDLBuiltinType.Types.undefined], - self.getForEachArguments(), - ) - - def getKeyArg(): - 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, - ) - - if not self.readonly: - # undefined clear() - self.addMethod( - "clear", members, True, BuiltinTypes[IDLBuiltinType.Types.undefined], [] - ) - # boolean delete(keyType key) - 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()], - ) - return - - # If we get this far, we're a maplike declaration. - - # valueType get(keyType key) - # - # Note that instead of the value type, we're using any here. The - # validity checks should happen as things are inserted into the map, - # and using any as the return type makes code generation much simpler. - # - # 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, - ) - - def getValueArg(): - 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()], - ) - - -class IDLConst(IDLInterfaceMember): - def __init__(self, location, identifier, type, value): - 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] - ) - if type.isRecord(): - 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] - ) - - def __str__(self): - return "'%s' const '%s'" % (self.type, self.identifier) - - def finish(self, scope): - IDLInterfaceMember.finish(self, scope) - - if not self.type.isComplete(): - type = self.type.complete(scope) - if not type.isPrimitive() and not type.isString(): - locations = [self.type.location, type.location] - try: - locations.append(type.inner.location) - except: - pass - raise WebIDLError("Incorrect type for constant", locations) - self.type = type - - # The value might not match the type - coercedValue = self.value.coerceToType(self.type, self.location) - assert coercedValue - - self.value = coercedValue - - def validate(self): - IDLInterfaceMember.validate(self) - - def handleExtendedAttribute(self, attr): - identifier = attr.identifier() - if identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) - 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], - ) - IDLInterfaceMember.handleExtendedAttribute(self, attr) - - def _getDependentObjects(self): - return set([self.type, self.value]) - - -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, - ) - - assert isinstance(type, IDLType) - self.type = type - self.readonly = readonly - self.inherit = inherit - self._static = static - self.legacyLenientThis = False - self._legacyUnforgeable = False - self.stringifier = stringifier - self.slotIndices = None - 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], - ) - - if readonly and inherit: - raise WebIDLError( - "An attribute cannot be both 'readonly' and 'inherit'", [self.location] - ) - - def isStatic(self): - return self._static - - def forceStatic(self): - self._static = True - - def __str__(self): - return "'%s' attribute '%s'" % (self.type, self.identifier) - - def finish(self, scope): - IDLInterfaceMember.finish(self, scope) - - if not self.type.isComplete(): - t = self.type.complete(scope) - - assert not isinstance(t, IDLUnresolvedType) - assert not isinstance(t, IDLTypedefType) - 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.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] - ) - if self.type.isSequence() and not self.getExtendedAttribute("Cached"): - 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] - ) - 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], - ) - 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], - ) - 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], - ) - 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], - ) - - 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] - ) - - 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(): - return typeContainsChromeOnlyDictionaryMember(type.inner) - - if type.isUnion(): - for memberType in type.flatMemberTypes: - (contains, location) = typeContainsChromeOnlyDictionaryMember( - memberType - ) - if contains: - return (True, location) - - if type.isDictionary(): - dictionary = type.inner - while dictionary: - (contains, location) = dictionaryContainsChromeOnlyMember( - dictionary - ) - if contains: - return (True, location) - dictionary = dictionary.parent - - return (False, None) - - def dictionaryContainsChromeOnlyMember(dictionary): - for member in dictionary.members: - if member.getExtendedAttribute("ChromeOnly"): - return (True, member.location) - (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 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], - ) - (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], - ) - 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.unroll().isExposedInAllOf(self.exposureSet): - 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], - ) - - 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], - ) - elif identifier == "BindingAlias": - if not attr.hasValue(): - 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 == "LegacyLenientThis": - if not attr.noArguments(): - raise WebIDLError( - "[LegacyLenientThis] must take no arguments", [attr.location] - ) - if self.isStatic(): - raise WebIDLError( - "[LegacyLenientThis] is only allowed on non-static " "attributes", - [attr.location, self.location], - ) - if self.getExtendedAttribute("CrossOriginReadable"): - raise WebIDLError( - "[LegacyLenientThis] is not allowed in combination " - "with [CrossOriginReadable]", - [attr.location, self.location], - ) - if self.getExtendedAttribute("CrossOriginWritable"): - 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( - "[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], - ) - elif identifier == "Constant" and not self.readonly: - 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], - ) - if self.type.isPromise(): - 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], - ) - if self.getExtendedAttribute("Replaceable") is not None: - 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] - ) - elif identifier == "Replaceable": - if not attr.noArguments(): - 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], - ) - if self.type.isPromise(): - 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], - ) - 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 == "LegacyLenientSetter": - if not attr.noArguments(): - raise WebIDLError( - "[LegacyLenientSetter] must take no arguments", [attr.location] - ) - if not self.readonly: - raise WebIDLError( - "[LegacyLenientSetter] is only allowed on readonly " "attributes", - [attr.location, self.location], - ) - if self.type.isPromise(): - raise WebIDLError( - "[LegacyLenientSetter] is not allowed on " - "Promise-typed attributes", - [attr.location, self.location], - ) - if self.isStatic(): - raise WebIDLError( - "[LegacyLenientSetter] is only allowed on non-static " "attributes", - [attr.location, self.location], - ) - if self.getExtendedAttribute("PutForwards") is not None: - 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( - "[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], - ) - if not self.type.includesRestrictedFloat(): - 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], - ) - 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": - if not attr.noArguments(): - 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("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]) - 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] - ) - self._setDependsOn("Nothing") - self._setAffects("Nothing") - elif identifier == "Affects": - if not attr.hasValue(): - 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], - ) - 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], - ) - elif identifier == "Unscopable": - if not attr.noArguments(): - 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], - ) - 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 == "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], - ) - IDLInterfaceMember.handleExtendedAttribute(self, attr) - - def resolve(self, parentScope): - assert isinstance(parentScope, IDLScope) - self.type.resolveType(parentScope) - IDLObjectWithIdentifier.resolve(self, parentScope) - - def hasLegacyLenientThis(self): - return self.legacyLenientThis - - def isMaplikeOrSetlikeAttr(self): - """ - True if this attribute was generated from an interface with - maplike/setlike (e.g. this is the size attribute for - maplike/setlike) - """ - return self.maplikeOrSetlike is not None - - 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() - 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 = [ - "CEReactions", - "CrossOriginWritable", - "SetterThrows", - ] - 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,))] - ) - elif not key in attributeOnlyExtAttrs: - 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, - ): - IDLObjectWithIdentifier.__init__(self, location, None, identifier) - - assert isinstance(type, IDLType) - self.type = type - - self.optional = optional - self.defaultValue = defaultValue - self.variadic = variadic - self.dictionaryMember = dictionaryMember - self._isComplete = False - self._allowTreatNonCallableAsNull = False - self._extendedAttrDict = {} - self.allowTypeAttributes = allowTypeAttributes - - assert not variadic or optional - assert not variadic or not defaultValue - - def addExtendedAttributes(self, attrs): - for attribute in attrs: - identifier = attribute.identifier() - 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 == "Trial" - or identifier == "Pref" - ): - if not self.optional: - 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], - ) - attrlist = attribute.listValue() - self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True - - def getExtendedAttribute(self, name): - return self._extendedAttrDict.get(name, None) - - def isComplete(self): - return self._isComplete - - def complete(self, scope): - if self._isComplete: - return - - self._isComplete = True - - if not self.type.isComplete(): - type = self.type.complete(scope) - assert not isinstance(type, IDLUnresolvedType) - assert not isinstance(type, IDLTypedefType) - 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 - ) - # 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.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) - assert self.defaultValue - - def allowTreatNonCallableAsNull(self): - return self._allowTreatNonCallableAsNull - - def _getDependentObjects(self): - deps = set([self.type]) - if self.defaultValue: - deps.add(self.defaultValue) - return deps - - def canHaveMissingValue(self): - return self.optional and not self.defaultValue - - -class IDLCallback(IDLObjectWithScope): - def __init__( - self, location, parentScope, identifier, returnType, arguments, isConstructor - ): - assert isinstance(returnType, IDLType) - - self._returnType = returnType - # Clone the list - self._arguments = list(arguments) - - IDLObjectWithScope.__init__(self, location, parentScope, identifier) - - for (returnType, arguments) in self.signatures(): - for argument in arguments: - argument.resolve(self) - - self._treatNonCallableAsNull = False - self._treatNonObjectAsNull = False - self._isRunScriptBoundary = False - self._isConstructor = isConstructor - - def isCallback(self): - return True - - def isConstructor(self): - return self._isConstructor - - def signatures(self): - return [(self._returnType, self._arguments)] - - def finish(self, scope): - if not self._returnType.isComplete(): - type = self._returnType.complete(scope) - - assert not isinstance(type, IDLUnresolvedType) - assert not isinstance(type, IDLTypedefType) - assert not isinstance(type.name, IDLUnresolvedIdentifier) - self._returnType = type - - for argument in self._arguments: - if argument.type.isComplete(): - continue - - type = argument.type.complete(scope) - - assert not isinstance(type, IDLUnresolvedType) - assert not isinstance(type, IDLTypedefType) - assert not isinstance(type.name, IDLUnresolvedIdentifier) - argument.type = type - - def validate(self): - 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() == "LegacyTreatNonObjectAsNull": - if self._isConstructor: - 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], - ) - self._isRunScriptBoundary = True - else: - unhandledAttrs.append(attr) - if self._treatNonCallableAsNull and self._treatNonObjectAsNull: - raise WebIDLError( - "Cannot specify both [TreatNonCallableAsNull] " - "and [LegacyTreatNonObjectAsNull]", - [self.location], - ) - if len(unhandledAttrs) != 0: - IDLType.addExtendedAttributes(self, unhandledAttrs) - - def _getDependentObjects(self): - return set([self._returnType] + self._arguments) - - def isRunScriptBoundary(self): - return self._isRunScriptBoundary - - -class IDLCallbackType(IDLType): - def __init__(self, location, callback): - IDLType.__init__(self, location, callback.identifier.name) - self.callback = callback - - def isCallback(self): - return True - - def tag(self): - return IDLType.Tags.callback - - def isDistinguishableFrom(self, other): - if other.isPromise(): - return False - if other.isUnion(): - # Just forward to the union; it'll deal - return other.isDistinguishableFrom(self) - 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() - - -class IDLMethodOverload: - """ - A class that represents a single overload of a WebIDL method. This is not - quite the same as an element of the "effective overload set" in the spec, - because separate IDLMethodOverloads are not created based on arguments being - optional. Rather, when multiple methods have the same name, there is an - 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 - self.arguments = list(arguments) - self.location = location - - def _getDependentObjects(self): - deps = set(self.arguments) - deps.add(self.returnType) - return deps - - def includesRestrictedFloatArgument(self): - return any(arg.type.includesRestrictedFloat() for arg in self.arguments) - - -class IDLMethod(IDLInterfaceMember, IDLScope): - - Special = enum( - "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, - ): - # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up. - IDLInterfaceMember.__init__( - self, location, identifier, IDLInterfaceMember.Tags.Method - ) - - self._hasOverloads = False - - assert isinstance(returnType, IDLType) - - # self._overloads is a list of IDLMethodOverloads - self._overloads = [IDLMethodOverload(returnType, arguments, location)] - - assert isinstance(static, bool) - self._static = static - assert isinstance(getter, bool) - self._getter = getter - assert isinstance(setter, bool) - self._setter = setter - assert isinstance(deleter, bool) - self._deleter = deleter - assert isinstance(legacycaller, bool) - self._legacycaller = legacycaller - assert isinstance(stringifier, bool) - self._stringifier = stringifier - assert maplikeOrSetlikeOrIterable is None or isinstance( - maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase - ) - self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable - self._htmlConstructor = False - self.underlyingAttr = underlyingAttr - self._specialType = specialType - 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], - ) - - self.assertSignatureConstraints() - - def __str__(self): - return "Method '%s'" % self.identifier - - def assertSignatureConstraints(self): - if self._getter or self._deleter: - assert len(self._overloads) == 1 - 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 not arguments[0].optional and not arguments[0].variadic - assert not self._getter or not overload.returnType.isUndefined() - - if self._setter: - 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 not arguments[0].optional and not arguments[0].variadic - assert not arguments[1].optional and not arguments[1].variadic - - if self._stringifier: - assert len(self._overloads) == 1 - overload = self._overloads[0] - assert len(overload.arguments) == 0 - if not self.underlyingAttr: - assert ( - overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring] - ) - - def isStatic(self): - return self._static - - def forceStatic(self): - self._static = True - - def isGetter(self): - return self._getter - - def isSetter(self): - return self._setter - - def isDeleter(self): - return self._deleter - - def isNamed(self): - 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 - ) - return self._specialType == IDLMethod.NamedOrIndexed.Indexed - - def isLegacycaller(self): - return self._legacycaller - - def isStringifier(self): - return self._stringifier - - def isToJSON(self): - return self.identifier.name == "toJSON" - - def isDefaultToJSON(self): - return self.isToJSON() and self.getExtendedAttribute("Default") - - def isMaplikeOrSetlikeOrIterableMethod(self): - """ - True if this method was generated as part of a - maplike/setlike/etc interface (e.g. has/get methods) - """ - return self.maplikeOrSetlikeOrIterable is not None - - def isSpecial(self): - return ( - self.isGetter() - or self.isSetter() - or self.isDeleter() - or self.isLegacycaller() - or self.isStringifier() - ) - - def isHTMLConstructor(self): - return self._htmlConstructor - - def hasOverloads(self): - return self._hasOverloads - - def isIdentifierLess(self): - """ - True if the method name started with __, and if the method is not a - maplike/setlike method. Interfaces with maplike/setlike will generate - methods starting with __ for chrome only backing object access in JS - 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() - ) - - def resolve(self, parentScope): - assert isinstance(parentScope, IDLScope) - IDLObjectWithIdentifier.resolve(self, parentScope) - IDLScope.__init__(self, self.location, parentScope, self.identifier) - for (returnType, arguments) in self.signatures(): - for argument in arguments: - argument.resolve(self) - - def addOverload(self, method): - assert len(method._overloads) == 1 - - if self._extendedAttrDict != method._extendedAttrDict: - extendedAttrDiff = set(self._extendedAttrDict.keys()) ^ set( - method._extendedAttrDict.keys() - ) - - 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" - ] - elif method._overloads[0].includesRestrictedFloatArgument(): - 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], - ) - - 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], - ) - - if self.isLegacycaller() != method.isLegacycaller(): - 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() - 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() - - return self - - def signatures(self): - return [ - (overload.returnType, overload.arguments) for overload in self._overloads - ] - - def finish(self, scope): - IDLInterfaceMember.finish(self, scope) - - for overload in self._overloads: - returnType = overload.returnType - if not returnType.isComplete(): - returnType = returnType.complete(scope) - assert not isinstance(returnType, IDLUnresolvedType) - assert not isinstance(returnType, IDLTypedefType) - assert not isinstance(returnType.name, IDLUnresolvedIdentifier) - overload.returnType = returnType - - for argument in overload.arguments: - if not argument.isComplete(): - argument.complete(scope) - assert argument.type.isComplete() - - # 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 - ] - - def validate(self): - IDLInterfaceMember.validate(self) - - # Make sure our overloads are properly distinguishable and don't have - # different argument types before the distinguishing args. - for argCount in self.allowedArgCounts: - possibleOverloads = self.overloadsForArgCount(argCount) - if len(possibleOverloads) == 1: - continue - distinguishingIndex = self.distinguishingIndexForArgCount(argCount) - for idx in range(distinguishingIndex): - firstSigType = possibleOverloads[0].arguments[idx].type - for overload in possibleOverloads[1:]: - if overload.arguments[idx].type != firstSigType: - 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], - ) - - 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], - ) - - variadicArgument = None - - arguments = overload.arguments - 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() - ): - # 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], - ) - - # 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], - ) - - # Only the last argument can be variadic - if variadicArgument: - raise WebIDLError( - "Variadic argument is not last argument", - [variadicArgument.location], - ) - if argument.variadic: - variadicArgument = argument - - if returnType.isPromise(): - overloadWithPromiseReturnType = overload - else: - overloadWithoutPromiseReturnType = overload - - # 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, - ], - ) - - if overloadWithPromiseReturnType and self._legacycaller: - 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], - ) - - # 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], - ) - if len(self.signatures()[0][1]) != 0: - 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] - ) - - 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 - ) - ] - - def signaturesForArgCount(self, 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)] - - def distinguishingIndexForArgCount(self, argc): - def isValidDistinguishingIndex(idx, signatures): - for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]): - for (secondRetval, secondArgs) in signatures[firstSigIndex + 1 :]: - if idx < len(firstArgs): - firstType = firstArgs[idx].type - else: - assert firstArgs[-1].variadic - firstType = firstArgs[-1].type - if idx < len(secondArgs): - secondType = secondArgs[idx].type - else: - 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, - ) - - 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 == "LegacyUnforgeable": - if self.isStatic(): - 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], - ) - elif identifier == "Constant": - 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 == "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 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], - ) - elif identifier == "Exposed": - convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) - elif ( - identifier == "CrossOriginCallable" - or identifier == "WebGLHandlesContextLoss" - ): - # Known no-argument attributes. - if not attr.noArguments(): - 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], - ) - elif identifier == "Pure": - if not attr.noArguments(): - 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]) - self._setAffects(attr.value()) - elif identifier == "DependsOn": - if not attr.hasValue(): - 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] - ) - 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], - ) - elif identifier == "Unscopable": - if not attr.noArguments(): - 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], - ) - elif identifier == "CEReactions": - if not attr.noArguments(): - 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], - ) - elif identifier == "Default": - if not attr.noArguments(): - 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], - ) - - 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 == "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] - ) - IDLInterfaceMember.handleExtendedAttribute(self, attr) - - def returnsPromise(self): - return self._overloads[0].returnType.isPromise() - - def isLegacyUnforgeable(self): - return self._legacyUnforgeable - - def _getDependentObjects(self): - deps = set() - for overload in self._overloads: - deps.update(overload._getDependentObjects()) - return deps - - -class IDLConstructor(IDLMethod): - 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 - # it later. - self._initLocation = location - self._initArgs = args - self._initName = name - self._inited = False - self._initExtendedAttrs = [] - - def addExtendedAttributes(self, attrs): - if self._inited: - return IDLMethod.addExtendedAttributes(self, attrs) - self._initExtendedAttrs.extend(attrs) - - 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 == "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 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], - ) - self._htmlConstructor = True - else: - 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 - # 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",))] - ) - - -class IDLIncludesStatement(IDLObject): - def __init__(self, location, interface, mixin): - IDLObject.__init__(self, location) - self.interface = interface - self.mixin = mixin - self._finished = False - - def finish(self, scope): - if self._finished: - return - self._finished = True - 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], - ) - if interface.isCallback(): - 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], - ) - - mixin.actualExposureGlobalNames.update(interface._exposureGlobalNames) - - interface.addIncludedMixin(mixin) - self.interface = interface - self.mixin = mixin - - def validate(self): - pass - - 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], - ) - - -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 - - def identifier(self): - return self._tuple[0] - - def noArguments(self): - return len(self._tuple) == 1 - - def hasValue(self): - return len(self._tuple) >= 2 and isinstance(self._tuple[1], str) - - def value(self): - 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 - ) - - def args(self): - assert self.hasArgs() - # Our args are our last element - return self._tuple[-1] - - def listValue(self): - """ - Backdoor for storing random data in _extendedAttrDict - """ - return list(self._tuple)[1:] - - -# Parser - - -class Tokenizer(object): - 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" - 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]*)" - 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, - ) - ], - ) - return t - - def t_IDENTIFIER(self, t): - r"[_-]?[A-Za-z][0-9A-Z_a-z-]*" - t.type = self.keywords.get(t.value, "IDENTIFIER") - # If Builtin readable streams are disabled, mark ReadableStream as an identifier. - if t.type == "READABLESTREAM" and not self._use_builtin_readable_streams: - t.type = "IDENTIFIER" - return t - - def t_STRING(self, t): - r'"[^"]*"' - t.value = t.value[1:-1] - return t - - def t_WHITESPACE(self, t): - r"[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+" - pass - - def t_ELLIPSIS(self, t): - 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") - return t - - keywords = { - "interface": "INTERFACE", - "partial": "PARTIAL", - "mixin": "MIXIN", - "dictionary": "DICTIONARY", - "exception": "EXCEPTION", - "enum": "ENUM", - "callback": "CALLBACK", - "typedef": "TYPEDEF", - "includes": "INCLUDES", - "const": "CONST", - "null": "NULL", - "true": "TRUE", - "false": "FALSE", - "serializer": "SERIALIZER", - "stringifier": "STRINGIFIER", - "unrestricted": "UNRESTRICTED", - "attribute": "ATTRIBUTE", - "readonly": "READONLY", - "inherit": "INHERIT", - "static": "STATIC", - "getter": "GETTER", - "setter": "SETTER", - "deleter": "DELETER", - "legacycaller": "LEGACYCALLER", - "optional": "OPTIONAL", - "...": "ELLIPSIS", - "::": "SCOPE", - "DOMString": "DOMSTRING", - "ByteString": "BYTESTRING", - "USVString": "USVSTRING", - "JSString": "JSSTRING", - "UTF8String": "UTF8STRING", - "any": "ANY", - "boolean": "BOOLEAN", - "byte": "BYTE", - "double": "DOUBLE", - "float": "FLOAT", - "long": "LONG", - "object": "OBJECT", - "ObservableArray": "OBSERVABLEARRAY", - "octet": "OCTET", - "Promise": "PROMISE", - "required": "REQUIRED", - "sequence": "SEQUENCE", - "record": "RECORD", - "short": "SHORT", - "unsigned": "UNSIGNED", - "undefined": "UNDEFINED", - ":": "COLON", - ";": "SEMICOLON", - "{": "LBRACE", - "}": "RBRACE", - "(": "LPAREN", - ")": "RPAREN", - "[": "LBRACKET", - "]": "RBRACKET", - "?": "QUESTIONMARK", - "*": "ASTERISK", - ",": "COMMA", - "=": "EQUALS", - "<": "LT", - ">": "GT", - "ArrayBuffer": "ARRAYBUFFER", - "or": "OR", - "maplike": "MAPLIKE", - "setlike": "SETLIKE", - "iterable": "ITERABLE", - "namespace": "NAMESPACE", - "ReadableStream": "READABLESTREAM", - "constructor": "CONSTRUCTOR", - "symbol": "SYMBOL", - "async": "ASYNC", - } - - 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, - ) - ], - ) - - def __init__(self, outputdir, lexer=None, use_builtin_readable_streams=True): - self._use_builtin_readable_streams = use_builtin_readable_streams - if lexer: - self.lexer = lexer - else: - self.lexer = lex.lex(object=self, reflags=re.DOTALL) - - -class SqueakyCleanLogger(object): - errorWhitelist = [ - # Web IDL defines the WHITESPACE token, but doesn't actually - # use it ... so far. - "Token 'WHITESPACE' 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 - # ExtendedAttributeInner, which we don't use yet. - "Rule 'OtherOrComma' defined, but not used", - # And an unused rule - "There is 1 unused rule", - # And the OtherOrComma grammar symbol is unreachable. - "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" - ): - # Munge things so we don't have to hardcode filenames and - # line numbers in our whitelist. - whitelistmsg = "Rule %r defined, but not used" - whitelistargs = args[2:] - else: - whitelistmsg = msg - whitelistargs = args - if (whitelistmsg % whitelistargs) not in SqueakyCleanLogger.errorWhitelist: - self.errors.append(msg % args) - - error = warning - - def reportGrammarErrors(self): - if self.errors: - raise WebIDLError("\n".join(self.errors), []) - - -class Parser(Tokenizer): - def getLocation(self, p, i): - return Location(self.lexer, p.lineno(i), p.lexpos(i), self._filename) - - def globalScope(self): - return self._globalScope - - # The p_Foo functions here must match the WebIDL spec's grammar. - # It's acceptable to split things at '|' boundaries. - def p_Definitions(self, p): - """ - Definitions : ExtendedAttributeList Definition Definitions - """ - if p[2]: - p[0] = [p[2]] - p[2].addExtendedAttributes(p[1]) - else: - assert not p[1] - p[0] = [] - - p[0].extend(p[3]) - - def p_DefinitionsEmpty(self, p): - """ - Definitions : - """ - p[0] = [] - - def p_Definition(self, p): - """ - 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 - """ - if p[2].isInterface(): - assert isinstance(p[2], IDLInterface) - p[2].setCallback(True) - - p[0] = p[2] - - def p_CallbackOrInterfaceOrMixinInterfaceOrMixin(self, p): - """ - CallbackOrInterfaceOrMixin : INTERFACE InterfaceOrMixin - """ - p[0] = p[2] - - def p_CallbackRestOrInterface(self, p): - """ - CallbackRestOrInterface : CallbackRest - | CallbackConstructorRest - | CallbackInterface - """ - assert p[1] - p[0] = p[1] - - 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 - it to non-partial as needed. The return value is the non-partial - object. - - constructorArgs are all the args for the constructor except the last - one: isKnownNonPartial. - - nonPartialArgs are the args for the setNonPartial call. - """ - # The name of the class starts with "IDL", so strip that off. - # Also, starts with a capital letter after that, so nix that - # as well. - prettyname = constructor.__name__[3:].lower() - - try: - 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], - ) - existingObj.setNonPartial(*nonPartialArgs) - return existingObj - except Exception as ex: - if isinstance(ex, WebIDLError): - raise ex - pass - - # True for isKnownNonPartial - return constructor(*(constructorArgs + [True])) - - def p_InterfaceOrMixin(self, p): - """ - InterfaceOrMixin : InterfaceRest - | MixinRest - """ - p[0] = p[1] - - def p_CallbackInterface(self, p): - """ - CallbackInterface : INTERFACE InterfaceRest - """ - p[0] = p[2] - - def p_InterfaceRest(self, p): - """ - InterfaceRest : IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON - """ - location = self.getLocation(p, 1) - identifier = IDLUnresolvedIdentifier(location, p[1]) - members = p[4] - parent = p[2] - - p[0] = self.handleNonPartialObject( - location, - identifier, - IDLInterface, - [location, self.globalScope(), identifier, parent, members], - [location, parent, members], - ) - - def p_InterfaceForwardDecl(self, p): - """ - InterfaceRest : IDENTIFIER SEMICOLON - """ - location = self.getLocation(p, 1) - identifier = IDLUnresolvedIdentifier(location, p[1]) - - try: - 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], - ) - return - except Exception as ex: - if isinstance(ex, WebIDLError): - raise ex - pass - - p[0] = IDLExternalInterface(location, self.globalScope(), identifier) - - def p_MixinRest(self, p): - """ - 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, self.globalScope(), identifier, members], - [location, members], - ) - - def p_Namespace(self, p): - """ - 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, self.globalScope(), identifier, members], - [location, None, members], - ) - - def p_Partial(self, p): - """ - Partial : PARTIAL PartialDefinition - """ - p[0] = p[2] - - def p_PartialDefinitionInterface(self, p): - """ - PartialDefinition : INTERFACE PartialInterfaceOrPartialMixin - """ - p[0] = p[2] - - def p_PartialDefinition(self, p): - """ - PartialDefinition : PartialNamespace - | PartialDictionary - """ - p[0] = p[1] - - 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 - it as needed. The return value is our partial object. We use - IDLPartialInterfaceOrNamespace for partial interfaces or namespaces, - and IDLPartialDictionary for partial dictionaries. - - nonPartialConstructorArgs are all the args for the non-partial - constructor except the last two: members and isKnownNonPartial. - - partialConstructorArgs are the arguments for the partial object - constructor, except the last one (the non-partial object). - """ - # The name of the class starts with "IDL", so strip that off. - # Also, starts with a capital letter after that, so nix that - # as well. - prettyname = nonPartialConstructor.__name__[3:].lower() - - nonPartialObject = None - try: - 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], - ) - except Exception as ex: - if isinstance(ex, WebIDLError): - raise ex - pass - - if not nonPartialObject: - nonPartialObject = nonPartialConstructor( - # No members, False for isKnownNonPartial - *(nonPartialConstructorArgs), - members=[], - isKnownNonPartial=False - ) - - partialObject = None - if isinstance(nonPartialObject, IDLDictionary): - partialObject = IDLPartialDictionary( - *(partialConstructorArgs + [nonPartialObject]) - ) - elif isinstance( - nonPartialObject, (IDLInterface, IDLInterfaceMixin, IDLNamespace) - ): - partialObject = IDLPartialInterfaceOrNamespace( - *(partialConstructorArgs + [nonPartialObject]) - ) - else: - raise WebIDLError( - "Unknown partial object type %s" % type(partialObject), [location] - ) - - return partialObject - - def p_PartialInterfaceOrPartialMixin(self, p): - """ - PartialInterfaceOrPartialMixin : PartialInterfaceRest - | PartialMixinRest - """ - p[0] = p[1] - - def p_PartialInterfaceRest(self, p): - """ - 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, self.globalScope(), identifier, None], - [location, identifier, members], - ) - - def p_PartialMixinRest(self, p): - """ - 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, self.globalScope(), identifier], - [location, identifier, members], - ) - - def p_PartialNamespace(self, p): - """ - 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, self.globalScope(), identifier], - [location, identifier, members], - ) - - def p_PartialDictionary(self, p): - """ - 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, self.globalScope(), identifier], - [location, identifier, members], - ) - - def p_Inheritance(self, p): - """ - Inheritance : COLON ScopedName - """ - p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2]) - - def p_InheritanceEmpty(self, p): - """ - Inheritance : - """ - pass - - def p_InterfaceMembers(self, p): - """ - InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers - """ - p[0] = [p[2]] - - assert not p[1] or p[2] - p[2].addExtendedAttributes(p[1]) - - p[0].extend(p[3]) - - def p_InterfaceMembersEmpty(self, p): - """ - InterfaceMembers : - """ - p[0] = [] - - def p_InterfaceMember(self, p): - """ - InterfaceMember : PartialInterfaceMember - | Constructor - """ - p[0] = p[1] - - def p_Constructor(self, p): - """ - 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 - """ - p[0] = [p[2]] - - assert not p[1] or p[2] - p[2].addExtendedAttributes(p[1]) - - p[0].extend(p[3]) - - def p_PartialInterfaceMembersEmpty(self, p): - """ - PartialInterfaceMembers : - """ - p[0] = [] - - def p_PartialInterfaceMember(self, p): - """ - PartialInterfaceMember : Const - | AttributeOrOperationOrMaplikeOrSetlikeOrIterable - """ - p[0] = p[1] - - def p_MixinMembersEmpty(self, p): - """ - MixinMembers : - """ - p[0] = [] - - def p_MixinMembers(self, p): - """ - MixinMembers : ExtendedAttributeList MixinMember MixinMembers - """ - p[0] = [p[2]] - - assert not p[1] or p[2] - p[2].addExtendedAttributes(p[1]) - - p[0].extend(p[3]) - - def p_MixinMember(self, p): - """ - MixinMember : Const - | Attribute - | Operation - """ - p[0] = p[1] - - def p_Dictionary(self, p): - """ - Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON - """ - location = self.getLocation(p, 1) - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) - members = p[5] - p[0] = IDLDictionary(location, self.globalScope(), identifier, p[3], members) - - def p_DictionaryMembers(self, p): - """ - DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers - | - """ - if len(p) == 1: - # We're at the end of the list - p[0] = [] - return - p[2].addExtendedAttributes(p[1]) - p[0] = [p[2]] - p[0].extend(p[3]) - - def p_DictionaryMemberRequired(self, p): - """ - 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, - ) - - def p_DictionaryMember(self, p): - """ - DictionaryMember : Type IDENTIFIER Default SEMICOLON - """ - # These quack a lot like optional arguments, so just treat them that way. - t = p[1] - assert isinstance(t, IDLType) - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) - defaultValue = p[3] - - # 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, - ) - - def p_Default(self, p): - """ - Default : EQUALS DefaultValue - | - """ - if len(p) > 1: - p[0] = p[2] - else: - p[0] = None - - def p_DefaultValue(self, p): - """ - DefaultValue : ConstValue - | LBRACKET RBRACKET - | LBRACE RBRACE - """ - if len(p) == 2: - p[0] = p[1] - else: - assert len(p) == 3 # Must be [] or {} - if p[1] == "[": - p[0] = IDLEmptySequenceValue(self.getLocation(p, 1)) - else: - assert p[1] == "{" - p[0] = IDLDefaultDictionaryValue(self.getLocation(p, 1)) - - def p_DefaultValueNull(self, p): - """ - 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 - """ - pass - - def p_Enum(self, p): - """ - Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON - """ - location = self.getLocation(p, 1) - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) - - values = p[4] - assert values - p[0] = IDLEnum(location, self.globalScope(), identifier, values) - - def p_EnumValueList(self, p): - """ - EnumValueList : STRING EnumValueListComma - """ - p[0] = [p[1]] - p[0].extend(p[2]) - - def p_EnumValueListComma(self, p): - """ - EnumValueListComma : COMMA EnumValueListString - """ - p[0] = p[2] - - def p_EnumValueListCommaEmpty(self, p): - """ - EnumValueListComma : - """ - p[0] = [] - - def p_EnumValueListString(self, p): - """ - EnumValueListString : STRING EnumValueListComma - """ - p[0] = [p[1]] - p[0].extend(p[2]) - - def p_EnumValueListStringEmpty(self, p): - """ - EnumValueListString : - """ - p[0] = [] - - def p_CallbackRest(self, p): - """ - 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, - ) - - def p_CallbackConstructorRest(self, p): - """ - 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, - ) - - def p_ExceptionMembers(self, p): - """ - ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers - | - """ - pass - - def p_Typedef(self, p): - """ - Typedef : TYPEDEF TypeWithExtendedAttributes IDENTIFIER SEMICOLON - """ - 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 - """ - 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 - """ - location = self.getLocation(p, 1) - type = p[2] - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3]) - value = p[5] - p[0] = IDLConst(location, identifier, type, value) - - def p_ConstValueBoolean(self, p): - """ - ConstValue : BooleanLiteral - """ - location = self.getLocation(p, 1) - booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean] - p[0] = IDLValue(location, booleanType, p[1]) - - def p_ConstValueInteger(self, p): - """ - ConstValue : INTEGER - """ - location = self.getLocation(p, 1) - - # We don't know ahead of time what type the integer literal is. - # Determine the smallest type it could possibly fit in and use that. - integerType = matchIntegerValueToType(p[1]) - if integerType is None: - raise WebIDLError("Integer literal out of range", [location]) - - p[0] = IDLValue(location, integerType, p[1]) - - def p_ConstValueFloat(self, p): - """ - ConstValue : FLOATLITERAL - """ - location = self.getLocation(p, 1) - p[0] = IDLValue( - location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1] - ) - - def p_ConstValueString(self, p): - """ - ConstValue : STRING - """ - location = self.getLocation(p, 1) - stringType = BuiltinTypes[IDLBuiltinType.Types.domstring] - p[0] = IDLValue(location, stringType, p[1]) - - def p_BooleanLiteralTrue(self, p): - """ - BooleanLiteral : TRUE - """ - p[0] = True - - def p_BooleanLiteralFalse(self, p): - """ - BooleanLiteral : FALSE - """ - p[0] = False - - def p_AttributeOrOperationOrMaplikeOrSetlikeOrIterable(self, p): - """ - 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 - """ - location = self.getLocation(p, 2) - identifier = IDLUnresolvedIdentifier( - location, "__iterable", allowDoubleUnderscore=True - ) - if len(p) > 6: - keyType = p[3] - valueType = p[5] - else: - keyType = None - valueType = p[3] - - 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 - """ - readonly = p[1] - maplikeOrSetlikeType = p[2] - location = self.getLocation(p, 2) - identifier = IDLUnresolvedIdentifier( - location, "__setlike", allowDoubleUnderscore=True - ) - keyType = p[4] - valueType = keyType - p[0] = IDLMaplikeOrSetlike( - location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType - ) - - def p_Maplike(self, p): - """ - 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 - ) - keyType = p[4] - valueType = p[6] - p[0] = IDLMaplikeOrSetlike( - location, identifier, maplikeOrSetlikeType, readonly, keyType, valueType - ) - - def p_AttributeWithQualifier(self, p): - """ - 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 - ) - - def p_AttributeInherited(self, p): - """ - 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 - """ - (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 - """ - location = self.getLocation(p, 2) - readonly = p[1] - t = p[3] - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 4), p[4]) - p[0] = (location, identifier, t, readonly) - - def p_ReadOnly(self, p): - """ - ReadOnly : READONLY - """ - p[0] = True - - def p_ReadOnlyEmpty(self, p): - """ - ReadOnly : - """ - p[0] = False - - def p_Operation(self, p): - """ - 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)] - ) - - static = IDLInterfaceMember.Special.Static in p[1] - # If static is there that's all that's allowed. This is disallowed - # by the parser, so we can assert here. - assert not static or len(qualifiers) == 1 - - stringifier = IDLInterfaceMember.Special.Stringifier in p[1] - # If stringifier is there that's all that's allowed. This is disallowed - # by the parser, so we can assert here. - assert not stringifier or len(qualifiers) == 1 - - getter = True if IDLMethod.Special.Getter in p[1] else False - setter = True if IDLMethod.Special.Setter in p[1] else False - deleter = True if IDLMethod.Special.Deleter in p[1] else False - legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False - - if getter or deleter: - if setter: - raise WebIDLError( - "getter and deleter are incompatible with setter", - [self.getLocation(p, 1)], - ) - - (returnType, identifier, arguments) = p[2] - - assert isinstance(returnType, IDLType) - - specialType = IDLMethod.NamedOrIndexed.Neither - - 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)], - ) - 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)], - ) - else: - 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], - ) - if getter: - if returnType.isUndefined(): - 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)] - ) - 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], - ) - 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], - ) - 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], - ) - - if stringifier: - if len(arguments) != 0: - 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)], - ) - - # 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)], - ) - - 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, - ) - p[0] = method - - def p_Stringifier(self, p): - """ - 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, - ) - p[0] = method - - def p_QualifierStatic(self, p): - """ - Qualifier : STATIC - """ - p[0] = [IDLInterfaceMember.Special.Static] - - def p_QualifierStringifier(self, p): - """ - Qualifier : STRINGIFIER - """ - p[0] = [IDLInterfaceMember.Special.Stringifier] - - def p_Qualifiers(self, p): - """ - Qualifiers : Qualifier - | Specials - """ - p[0] = p[1] - - def p_Specials(self, p): - """ - Specials : Special Specials - """ - p[0] = [p[1]] - p[0].extend(p[2]) - - def p_SpecialsEmpty(self, p): - """ - Specials : - """ - p[0] = [] - - def p_SpecialGetter(self, p): - """ - Special : GETTER - """ - p[0] = IDLMethod.Special.Getter - - def p_SpecialSetter(self, p): - """ - Special : SETTER - """ - p[0] = IDLMethod.Special.Setter - - def p_SpecialDeleter(self, p): - """ - Special : DELETER - """ - p[0] = IDLMethod.Special.Deleter - - def p_SpecialLegacyCaller(self, p): - """ - Special : LEGACYCALLER - """ - p[0] = IDLMethod.Special.LegacyCaller - - def p_OperationRest(self, p): - """ - OperationRest : Type OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON - """ - p[0] = (p[1], p[2], p[4]) - - def p_OptionalIdentifier(self, p): - """ - OptionalIdentifier : IDENTIFIER - """ - p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) - - def p_OptionalIdentifierEmpty(self, p): - """ - OptionalIdentifier : - """ - pass - - def p_ArgumentList(self, p): - """ - ArgumentList : Argument Arguments - """ - p[0] = [p[1]] if p[1] else [] - p[0].extend(p[2]) - - def p_ArgumentListEmpty(self, p): - """ - ArgumentList : - """ - p[0] = [] - - def p_Arguments(self, p): - """ - Arguments : COMMA Argument Arguments - """ - p[0] = [p[2]] if p[2] else [] - p[0].extend(p[3]) - - def p_ArgumentsEmpty(self, p): - """ - Arguments : - """ - p[0] = [] - - def p_Argument(self, p): - """ - Argument : ExtendedAttributeList ArgumentRest - """ - p[0] = p[2] - p[0].addExtendedAttributes(p[1]) - - def p_ArgumentRestOptional(self, p): - """ - 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 - ) - - 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 - ) - - def p_ArgumentRest(self, p): - """ - 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 - ) - - variadic = p[2] - - # 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. - - # variadic implies optional - # 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, - ) - - def p_ArgumentName(self, p): - """ - 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 - """ - p[0] = p[1] - - def p_AttributeName(self, p): - """ - AttributeName : IDENTIFIER - | AttributeNameKeyword - """ - p[0] = p[1] - - def p_AttributeNameKeyword(self, p): - """ - AttributeNameKeyword : ASYNC - | REQUIRED - """ - p[0] = p[1] - - def p_Ellipsis(self, p): - """ - Ellipsis : ELLIPSIS - """ - p[0] = True - - def p_EllipsisEmpty(self, p): - """ - Ellipsis : - """ - p[0] = False - - def p_ExceptionMember(self, p): - """ - ExceptionMember : Const - | ExceptionField - """ - pass - - def p_ExceptionField(self, p): - """ - ExceptionField : Type IDENTIFIER SEMICOLON - """ - pass - - def p_ExtendedAttributeList(self, p): - """ - ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET - """ - p[0] = [p[2]] - if p[3]: - p[0].extend(p[3]) - - def p_ExtendedAttributeListEmpty(self, p): - """ - ExtendedAttributeList : - """ - p[0] = [] - - def p_ExtendedAttribute(self, p): - """ - ExtendedAttribute : ExtendedAttributeNoArgs - | ExtendedAttributeArgList - | ExtendedAttributeIdent - | ExtendedAttributeWildcard - | ExtendedAttributeNamedArgList - | ExtendedAttributeIdentList - """ - p[0] = IDLExtendedAttribute(self.getLocation(p, 1), p[1]) - - def p_ExtendedAttributeEmpty(self, p): - """ - ExtendedAttribute : - """ - pass - - def p_ExtendedAttributes(self, p): - """ - ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes - """ - p[0] = [p[2]] if p[2] else [] - p[0].extend(p[3]) - - def p_ExtendedAttributesEmpty(self, p): - """ - ExtendedAttributes : - """ - p[0] = [] - - def p_Other(self, p): - """ - 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 - """ - pass - - def p_TypeSingleType(self, p): - """ - Type : SingleType - """ - p[0] = p[1] - - def p_TypeUnionType(self, p): - """ - Type : UnionType Null - """ - p[0] = self.handleNullable(p[1], p[2]) - - def p_TypeWithExtendedAttributes(self, p): - """ - TypeWithExtendedAttributes : ExtendedAttributeList Type - """ - p[0] = p[2].withExtendedAttributes(p[1]) - - def p_SingleTypeDistinguishableType(self, p): - """ - SingleType : DistinguishableType - """ - p[0] = p[1] - - def p_SingleTypeAnyType(self, p): - """ - SingleType : ANY - """ - p[0] = BuiltinTypes[IDLBuiltinType.Types.any] - - def p_SingleTypePromiseType(self, p): - """ - 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 - """ - types = [p[2], p[4]] - types.extend(p[5]) - p[0] = IDLUnionType(self.getLocation(p, 1), types) - - def p_UnionMemberTypeDistinguishableType(self, p): - """ - UnionMemberType : ExtendedAttributeList DistinguishableType - """ - p[0] = p[2].withExtendedAttributes(p[1]) - - def p_UnionMemberType(self, p): - """ - UnionMemberType : UnionType Null - """ - p[0] = self.handleNullable(p[1], p[2]) - - def p_UnionMemberTypes(self, p): - """ - UnionMemberTypes : OR UnionMemberType UnionMemberTypes - """ - p[0] = [p[2]] - p[0].extend(p[3]) - - def p_UnionMemberTypesEmpty(self, p): - """ - UnionMemberTypes : - """ - p[0] = [] - - def p_DistinguishableType(self, p): - """ - DistinguishableType : PrimitiveType Null - | ARRAYBUFFER Null - | READABLESTREAM 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]] - - p[0] = self.handleNullable(type, p[2]) - - def p_DistinguishableTypeStringType(self, p): - """ - DistinguishableType : StringType Null - """ - p[0] = self.handleNullable(p[1], p[2]) - - def p_DistinguishableTypeSequenceType(self, p): - """ - DistinguishableType : SEQUENCE LT TypeWithExtendedAttributes GT Null - """ - innerType = p[3] - type = IDLSequenceType(self.getLocation(p, 1), innerType) - p[0] = self.handleNullable(type, p[5]) - - def p_DistinguishableTypeRecordType(self, p): - """ - 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 - """ - 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)], - ) - - type = None - - try: - if self.globalScope()._lookupIdentifier(p[1]): - obj = self.globalScope()._lookupIdentifier(p[1]) - assert not obj.isType() - if obj.isTypedef(): - type = IDLTypedefType( - self.getLocation(p, 1), obj.innerType, obj.identifier.name - ) - elif obj.isCallback() and not obj.isInterface(): - type = IDLCallbackType(obj.location, obj) - else: - type = IDLWrapperType(self.getLocation(p, 1), p[1]) - p[0] = self.handleNullable(type, p[2]) - return - except: - pass - - type = IDLUnresolvedType(self.getLocation(p, 1), p[1]) - p[0] = self.handleNullable(type, p[2]) - - def p_ConstType(self, p): - """ - ConstType : PrimitiveType - """ - p[0] = BuiltinTypes[p[1]] - - def p_ConstTypeIdentifier(self, p): - """ - ConstType : IDENTIFIER - """ - identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) - - p[0] = IDLUnresolvedType(self.getLocation(p, 1), identifier) - - def p_PrimitiveTypeUint(self, p): - """ - PrimitiveType : UnsignedIntegerType - """ - p[0] = p[1] - - def p_PrimitiveTypeBoolean(self, p): - """ - PrimitiveType : BOOLEAN - """ - p[0] = IDLBuiltinType.Types.boolean - - def p_PrimitiveTypeByte(self, p): - """ - PrimitiveType : BYTE - """ - p[0] = IDLBuiltinType.Types.byte - - def p_PrimitiveTypeOctet(self, p): - """ - PrimitiveType : OCTET - """ - p[0] = IDLBuiltinType.Types.octet - - def p_PrimitiveTypeFloat(self, p): - """ - PrimitiveType : FLOAT - """ - p[0] = IDLBuiltinType.Types.float - - def p_PrimitiveTypeUnrestictedFloat(self, p): - """ - PrimitiveType : UNRESTRICTED FLOAT - """ - p[0] = IDLBuiltinType.Types.unrestricted_float - - def p_PrimitiveTypeDouble(self, p): - """ - PrimitiveType : DOUBLE - """ - p[0] = IDLBuiltinType.Types.double - - def p_PrimitiveTypeUnrestictedDouble(self, p): - """ - PrimitiveType : UNRESTRICTED DOUBLE - """ - p[0] = IDLBuiltinType.Types.unrestricted_double - - def p_StringType(self, p): - """ - StringType : BuiltinStringType - """ - p[0] = BuiltinTypes[p[1]] - - def p_BuiltinStringTypeDOMString(self, p): - """ - BuiltinStringType : DOMSTRING - """ - p[0] = IDLBuiltinType.Types.domstring - - def p_BuiltinStringTypeBytestring(self, p): - """ - BuiltinStringType : BYTESTRING - """ - p[0] = IDLBuiltinType.Types.bytestring - - def p_BuiltinStringTypeUSVString(self, p): - """ - BuiltinStringType : USVSTRING - """ - p[0] = IDLBuiltinType.Types.usvstring - - def p_BuiltinStringTypeUTF8String(self, p): - """ - BuiltinStringType : UTF8STRING - """ - p[0] = IDLBuiltinType.Types.utf8string - - def p_BuiltinStringTypeJSString(self, p): - """ - BuiltinStringType : JSSTRING - """ - p[0] = IDLBuiltinType.Types.jsstring - - def p_UnsignedIntegerTypeUnsigned(self, p): - """ - 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 - """ - p[0] = p[1] - - def p_IntegerTypeShort(self, p): - """ - IntegerType : SHORT - """ - p[0] = IDLBuiltinType.Types.short - - def p_IntegerTypeLong(self, p): - """ - IntegerType : LONG OptionalLong - """ - if p[2]: - p[0] = IDLBuiltinType.Types.long_long - else: - p[0] = IDLBuiltinType.Types.long - - def p_OptionalLong(self, p): - """ - OptionalLong : LONG - """ - p[0] = True - - def p_OptionalLongEmpty(self, p): - """ - OptionalLong : - """ - p[0] = False - - def p_Null(self, p): - """ - Null : QUESTIONMARK - | - """ - if len(p) > 1: - p[0] = self.getLocation(p, 1) - else: - p[0] = None - - def p_ScopedName(self, p): - """ - ScopedName : AbsoluteScopedName - | RelativeScopedName - """ - p[0] = p[1] - - def p_AbsoluteScopedName(self, p): - """ - AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts - """ - assert False - pass - - def p_RelativeScopedName(self, p): - """ - RelativeScopedName : IDENTIFIER ScopedNameParts - """ - assert not p[2] # Not implemented! - - p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) - - def p_ScopedNameParts(self, p): - """ - ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts - """ - assert False - pass - - def p_ScopedNamePartsEmpty(self, p): - """ - ScopedNameParts : - """ - p[0] = None - - def p_ExtendedAttributeNoArgs(self, p): - """ - ExtendedAttributeNoArgs : IDENTIFIER - """ - p[0] = (p[1],) - - def p_ExtendedAttributeArgList(self, p): - """ - ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN - """ - p[0] = (p[1], p[3]) - - def p_ExtendedAttributeIdent(self, p): - """ - 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 - """ - p[0] = (p[1], p[3], p[5]) - - def p_ExtendedAttributeIdentList(self, p): - """ - ExtendedAttributeIdentList : IDENTIFIER EQUALS LPAREN IdentifierList RPAREN - """ - p[0] = (p[1], p[4]) - - def p_IdentifierList(self, p): - """ - 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] == "_": - ident = ident[1:] - idents.insert(0, ident) - p[0] = idents - - def p_IdentifiersList(self, p): - """ - 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] == "_": - ident = ident[1:] - idents.insert(0, ident) - p[0] = idents - - def p_IdentifiersEmpty(self, p): - """ - 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], - ) - else: - raise WebIDLError( - "invalid syntax", - [Location(self.lexer, p.lineno, p.lexpos, self._filename)], - ) - - def __init__(self, outputdir="", lexer=None, use_builtin_readable_stream=True): - Tokenizer.__init__(self, outputdir, lexer, use_builtin_readable_stream) - - logger = SqueakyCleanLogger() - try: - 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 = [] - - self._filename = "<builtin>" - self.lexer.input(Parser._builtins) - self._filename = None - - self.parser.parse(lexer=self.lexer, tracking=True) - - def _installBuiltins(self, scope): - assert isinstance(scope, IDLScope) - - # range omits the last value. - 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 - ) - - @staticmethod - def handleNullable(type, questionMarkLocation): - if questionMarkLocation is not None: - type = IDLNullableType(questionMarkLocation, type) - - return type - - def parse(self, t, filename=None): - 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 - - def finish(self): - # If we have interfaces that are iterable, create their - # iterator interfaces and add them to the productions array. - interfaceStatements = [] - for p in self._productions: - if isinstance(p, IDLInterface): - interfaceStatements.append(p) - - for iface in interfaceStatements: - iterable = None - # We haven't run finish() on the interface yet, so we don't know - # whether our interface is maplike/setlike/iterable or not. This - # 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, IDLAsyncIterable)): - iterable = m - break - if iterable and (iterable.isPairIterator() or iterable.isAsyncIterable()): - - def simpleExtendedAttr(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( - iterable.location, - IDLUnresolvedIdentifier(iterable.location, "next"), - nextReturnType, - [], - ) - nextMethod.addExtendedAttributes([simpleExtendedAttr("Throws")]) - - 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 - # instances of the iterator. - itr_iface._exposureGlobalNames = set(iface._exposureGlobalNames) - # Always append generated iterable interfaces after the - # interface they're a member of, otherwise nativeType generation - # won't work correctly. - 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) - ] - for production in includesStatements: - production.finish(self.globalScope()) - for production in otherStatements: - production.finish(self.globalScope()) - - # Do any post-finish validation we need to do - for production in self._productions: - 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 - - def reset(self): - return Parser(lexer=self.lexer) - - # Builtin IDL defined by WebIDL - _builtins = """ - typedef (ArrayBufferView or ArrayBuffer) BufferSource; - """ - - -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.", - ) - (options, args) = o.parse_args() - - if len(args) < 1: - o.error(usageString) - - fileList = args - baseDir = os.getcwd() - - # Parse the WebIDL. - parser = Parser(options.cachedir) - try: - for filename in fileList: - fullPath = os.path.normpath(os.path.join(baseDir, filename)) - f = open(fullPath, "rb") - lines = f.readlines() - f.close() - print(fullPath) - parser.parse("".join(lines), fullPath) - parser.finish() - except WebIDLError as e: - if options.verbose_errors: - traceback.print_exc() - else: - print(e) - - -if __name__ == "__main__": - main() diff --git a/components/script/dom/bindings/codegen/parser/abstract.patch b/components/script/dom/bindings/codegen/parser/abstract.patch deleted file mode 100644 index 316ed8ce0a1..00000000000 --- a/components/script/dom/bindings/codegen/parser/abstract.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -1987,6 +1987,7 @@ class IDLInterface(IDLInterfaceOrNamespace): - or identifier == "RunConstructorInCallerCompartment" - or identifier == "WantsEventListenerHooks" - or identifier == "Serializable" -+ or identifier == "Abstract" - ): - # Known extended attributes that do not take values - if not attr.noArguments(): diff --git a/components/script/dom/bindings/codegen/parser/callback-location.patch b/components/script/dom/bindings/codegen/parser/callback-location.patch deleted file mode 100644 index b7a308df631..00000000000 --- a/components/script/dom/bindings/codegen/parser/callback-location.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -2283,7 +2283,7 @@ class IDLUnresolvedType(IDLType): - return typedefType.complete(scope).withExtendedAttributes(self.extraTypeAttributes) - elif obj.isCallback() and not obj.isInterface(): - assert self.name.name == obj.identifier.name -- return IDLCallbackType(self.location, obj) -+ return IDLCallbackType(obj.location, obj) - - name = self.name.resolve(scope, None) - return IDLWrapperType(self.location, obj) -@@ -6854,7 +6854,7 @@ class Parser(Tokenizer): - type = IDLTypedefType(self.getLocation(p, 1), obj.innerType, - obj.identifier.name) - elif obj.isCallback() and not obj.isInterface(): -- type = IDLCallbackType(self.getLocation(p, 1), obj) -+ type = IDLCallbackType(obj.location, obj) - else: - type = IDLWrapperType(self.getLocation(p, 1), p[1]) - p[0] = self.handleNullable(type, p[2]) diff --git a/components/script/dom/bindings/codegen/parser/debug.patch b/components/script/dom/bindings/codegen/parser/debug.patch deleted file mode 100644 index ffab062d801..00000000000 --- a/components/script/dom/bindings/codegen/parser/debug.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -8827,6 +8827,7 @@ class Parser(Tokenizer): - module=self, - outputdir=outputdir, - errorlog=logger, -+ debug=False, - write_tables=False, - # Pickling the grammar is a speedup in - # some cases (older Python?) but a diff --git a/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch b/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch deleted file mode 100644 index 210134d8ca6..00000000000 --- a/components/script/dom/bindings/codegen/parser/ext-attribute-no-value-error.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -3490,7 +3490,7 @@ class IDLBuiltinType(IDLType): - [self.location, attribute.location]) - assert not self.nullable() - if not attribute.hasValue(): -- raise WebIDLError("[TreatNullAs] must take an identifier argument" -+ raise WebIDLError("[TreatNullAs] must take an identifier argument", - [attribute.location]) - value = attribute.value() - if value != 'EmptyString': diff --git a/components/script/dom/bindings/codegen/parser/inline.patch b/components/script/dom/bindings/codegen/parser/inline.patch deleted file mode 100644 index ad4d0f8f959..00000000000 --- a/components/script/dom/bindings/codegen/parser/inline.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -1988,6 +1988,7 @@ class IDLInterface(IDLInterfaceOrNamespace): - or identifier == "WantsEventListenerHooks" - or identifier == "Serializable" - or identifier == "Abstract" -+ or identifier == "Inline" - ): - # Known extended attributes that do not take values - if not attr.noArguments(): diff --git a/components/script/dom/bindings/codegen/parser/readable-stream.patch b/components/script/dom/bindings/codegen/parser/readable-stream.patch deleted file mode 100644 index 4b90067696e..00000000000 --- a/components/script/dom/bindings/codegen/parser/readable-stream.patch +++ /dev/null @@ -1,162 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -2498,6 +2498,9 @@ class IDLType(IDLObject): - def isRecord(self): - return False - -+ def isReadableStream(self): -+ return False -+ - def isArrayBuffer(self): - return False - -@@ -2526,7 +2529,7 @@ class IDLType(IDLObject): - 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() -+ return self.isInterface() and (self.isBufferSource() or self.isReadableStream()) - - def isAny(self): - return self.tag() == IDLType.Tags.any -@@ -2743,6 +2746,9 @@ class IDLNullableType(IDLParametrizedType): - def isRecord(self): - return self.inner.isRecord() - -+ def isReadableStream(self): -+ return self.inner.isReadableStream() -+ - def isArrayBuffer(self): - return self.inner.isArrayBuffer() - -@@ -3252,6 +3258,9 @@ class IDLTypedefType(IDLType): - def isRecord(self): - return self.inner.isRecord() - -+ def isReadableStream(self): -+ return self.inner.isReadableStream() -+ - def isDictionary(self): - return self.inner.isDictionary() - -@@ -3597,6 +3606,7 @@ class IDLBuiltinType(IDLType): - "Uint32Array", - "Float32Array", - "Float64Array", -+ "ReadableStream", - ) - - TagLookup = { -@@ -3632,6 +3642,7 @@ class IDLBuiltinType(IDLType): - Types.Uint32Array: IDLType.Tags.interface, - Types.Float32Array: IDLType.Tags.interface, - Types.Float64Array: IDLType.Tags.interface, -+ Types.ReadableStream: IDLType.Tags.interface, - } - - PrettyNames = { -@@ -3667,6 +3678,7 @@ class IDLBuiltinType(IDLType): - Types.Uint32Array: "Uint32Array", - Types.Float32Array: "Float32Array", - Types.Float64Array: "Float64Array", -+ Types.ReadableStream: "ReadableStream", - } - - def __init__( -@@ -3830,11 +3842,19 @@ class IDLBuiltinType(IDLType): - and self._typeTag <= IDLBuiltinType.Types.Float64Array - ) - -+ def isReadableStream(self): -+ return self._typeTag == IDLBuiltinType.Types.ReadableStream -+ - 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() -+ return ( -+ self.isArrayBuffer() -+ or self.isArrayBufferView() -+ or self.isTypedArray() -+ or self.isReadableStream() -+ ) - - def isNonCallbackInterface(self): - # All the interfaces we can be are non-callback -@@ -3928,6 +3948,7 @@ class IDLBuiltinType(IDLType): - # 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. -@@ -4134,6 +4155,11 @@ BuiltinTypes = { - "Float64Array", - IDLBuiltinType.Types.Float64Array, - ), -+ IDLBuiltinType.Types.ReadableStream: IDLBuiltinType( -+ BuiltinLocation("<builtin type>"), -+ "ReadableStream", -+ IDLBuiltinType.Types.ReadableStream, -+ ), - } - - -@@ -6883,6 +6909,9 @@ class Tokenizer(object): - def t_IDENTIFIER(self, t): - r"[_-]?[A-Za-z][0-9A-Z_a-z-]*" - t.type = self.keywords.get(t.value, "IDENTIFIER") -+ # If Builtin readable streams are disabled, mark ReadableStream as an identifier. -+ if t.type == "READABLESTREAM" and not self._use_builtin_readable_streams: -+ t.type = "IDENTIFIER" - return t - - def t_STRING(self, t): -@@ -6973,6 +7002,7 @@ class Tokenizer(object): - "setlike": "SETLIKE", - "iterable": "ITERABLE", - "namespace": "NAMESPACE", -+ "ReadableStream": "READABLESTREAM", - "constructor": "CONSTRUCTOR", - "symbol": "SYMBOL", - "async": "ASYNC", -@@ -6993,7 +7023,8 @@ class Tokenizer(object): - ], - ) - -- def __init__(self, outputdir, lexer=None): -+ def __init__(self, outputdir, lexer=None, use_builtin_readable_streams=True): -+ self._use_builtin_readable_streams = use_builtin_readable_streams - if lexer: - self.lexer = lexer - else: -@@ -8482,6 +8513,7 @@ class Parser(Tokenizer): - """ - DistinguishableType : PrimitiveType Null - | ARRAYBUFFER Null -+ | READABLESTREAM Null - | OBJECT Null - | UNDEFINED Null - """ -@@ -8489,6 +8521,8 @@ class Parser(Tokenizer): - 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: -@@ -8827,8 +8861,8 @@ class Parser(Tokenizer): - [Location(self.lexer, p.lineno, p.lexpos, self._filename)], - ) - -- def __init__(self, outputdir="", lexer=None): -- Tokenizer.__init__(self, outputdir, lexer) -+ def __init__(self, outputdir="", lexer=None, use_builtin_readable_stream=True): -+ Tokenizer.__init__(self, outputdir, lexer, use_builtin_readable_stream) - - logger = SqueakyCleanLogger() - try: diff --git a/components/script/dom/bindings/codegen/parser/runtests.py b/components/script/dom/bindings/codegen/parser/runtests.py deleted file mode 100644 index 0599bf55fec..00000000000 --- a/components/script/dom/bindings/codegen/parser/runtests.py +++ /dev/null @@ -1,79 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -import os, sys -import glob -import optparse -import traceback -import WebIDL - -class TestHarness(object): - def __init__(self, test, verbose): - self.test = test - self.verbose = verbose - self.printed_intro = False - - def start(self): - if self.verbose: - self.maybe_print_intro() - - def finish(self): - if self.verbose or self.printed_intro: - print("Finished test %s" % self.test) - - def maybe_print_intro(self): - if not self.printed_intro: - print("Starting test %s" % self.test) - self.printed_intro = True - - def test_pass(self, msg): - if self.verbose: - print("TEST-PASS | %s" % msg) - - def test_fail(self, msg): - self.maybe_print_intro() - print("TEST-UNEXPECTED-FAIL | %s" % msg) - - def ok(self, condition, msg): - if condition: - self.test_pass(msg) - else: - self.test_fail(msg) - - def check(self, a, b, msg): - if a == b: - self.test_pass(msg) - else: - self.test_fail(msg) - print("\tGot %s expected %s" % (a, b)) - -def run_tests(tests, verbose): - testdir = os.path.join(os.path.dirname(__file__), 'tests') - if not tests: - tests = glob.iglob(os.path.join(testdir, "*.py")) - sys.path.append(testdir) - - for test in tests: - (testpath, ext) = os.path.splitext(os.path.basename(test)) - _test = __import__(testpath, globals(), locals(), ['WebIDLTest']) - - harness = TestHarness(test, verbose) - harness.start() - try: - _test.WebIDLTest.__call__(WebIDL.Parser(), harness) - except Exception as ex: - print("TEST-UNEXPECTED-FAIL | Unhandled exception in test %s: %s" % (testpath, ex)) - traceback.print_exc() - finally: - harness.finish() - -if __name__ == '__main__': - usage = """%prog [OPTIONS] [TESTS] - Where TESTS are relative to the tests directory.""" - parser = optparse.OptionParser(usage=usage) - parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help="Don't print passing tests.") - options, tests = parser.parse_args() - - run_tests(tests, verbose=options.verbose) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_any_null.py b/components/script/dom/bindings/codegen/parser/tests/test_any_null.py deleted file mode 100644 index f9afdacb02f..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_any_null.py +++ /dev/null @@ -1,16 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface DoubleNull { - attribute any? foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py b/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py deleted file mode 100644 index 3f50cb05158..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_argument_identifier_conflicts.py +++ /dev/null @@ -1,16 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface ArgumentIdentifierConflict { - undefined foo(boolean arg1, boolean arg1); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py b/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py deleted file mode 100644 index bbed33df926..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_argument_keywords.py +++ /dev/null @@ -1,22 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - interface Foo { - undefined foo(object constructor); - }; - """ - ) - - results = parser.finish() - harness.check(len(results), 1, "Should have an interface") - iface = results[0] - harness.check(len(iface.members), 1, "Should have an operation") - operation = iface.members[0] - harness.check(len(operation.signatures()), 1, "Should have one signature") - (retval, args) = operation.signatures()[0] - harness.check(len(args), 1, "Should have an argument") - harness.check( - args[0].identifier.name, - "constructor", - "Should have an identifier named 'constructor'", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py b/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py deleted file mode 100644 index b762d06ac29..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py +++ /dev/null @@ -1,95 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestArrayBuffer { - attribute ArrayBuffer bufferAttr; - undefined bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3); - - attribute ArrayBufferView viewAttr; - undefined viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, sequence<ArrayBufferView> arg3); - - attribute Int8Array int8ArrayAttr; - undefined int8ArrayMethod(Int8Array arg1, Int8Array? arg2, sequence<Int8Array> arg3); - - attribute Uint8Array uint8ArrayAttr; - undefined uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, sequence<Uint8Array> arg3); - - attribute Uint8ClampedArray uint8ClampedArrayAttr; - undefined uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, sequence<Uint8ClampedArray> arg3); - - attribute Int16Array int16ArrayAttr; - undefined int16ArrayMethod(Int16Array arg1, Int16Array? arg2, sequence<Int16Array> arg3); - - attribute Uint16Array uint16ArrayAttr; - undefined uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, sequence<Uint16Array> arg3); - - attribute Int32Array int32ArrayAttr; - undefined int32ArrayMethod(Int32Array arg1, Int32Array? arg2, sequence<Int32Array> arg3); - - attribute Uint32Array uint32ArrayAttr; - undefined uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, sequence<Uint32Array> arg3); - - attribute Float32Array float32ArrayAttr; - undefined float32ArrayMethod(Float32Array arg1, Float32Array? arg2, sequence<Float32Array> arg3); - - attribute Float64Array float64ArrayAttr; - undefined float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3); - }; - """ - ) - - results = parser.finish() - - iface = results[0] - - harness.ok(True, "TestArrayBuffer interface parsed without error") - harness.check(len(iface.members), 22, "Interface should have twenty two members") - - members = iface.members - - def checkStuff(attr, method, t): - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Expect an IDLAttribute") - harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod") - - harness.check(str(attr.type), t, "Expect an ArrayBuffer type") - harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface") - - (retType, arguments) = method.signatures()[0] - harness.ok(retType.isUndefined(), "Should have an undefined return type") - harness.check(len(arguments), 3, "Expect 3 arguments") - - harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type") - harness.ok( - arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface" - ) - - harness.check( - str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type" - ) - harness.ok( - arguments[1].type.inner.isSpiderMonkeyInterface(), - "Should test as a js interface", - ) - - harness.check( - str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type" - ) - harness.ok( - arguments[2].type.inner.isSpiderMonkeyInterface(), - "Should test as a js interface", - ) - - checkStuff(members[0], members[1], "ArrayBuffer") - checkStuff(members[2], members[3], "ArrayBufferView") - checkStuff(members[4], members[5], "Int8Array") - checkStuff(members[6], members[7], "Uint8Array") - checkStuff(members[8], members[9], "Uint8ClampedArray") - checkStuff(members[10], members[11], "Int16Array") - checkStuff(members[12], members[13], "Uint16Array") - checkStuff(members[14], members[15], "Int32Array") - checkStuff(members[16], members[17], "Uint32Array") - checkStuff(members[18], members[19], "Float32Array") - checkStuff(members[20], members[21], "Float64Array") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_attr.py deleted file mode 100644 index e19689a81a9..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_attr.py +++ /dev/null @@ -1,199 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - testData = [ - ("::TestAttr%s::b", "b", "Byte%s", False), - ("::TestAttr%s::rb", "rb", "Byte%s", True), - ("::TestAttr%s::o", "o", "Octet%s", False), - ("::TestAttr%s::ro", "ro", "Octet%s", True), - ("::TestAttr%s::s", "s", "Short%s", False), - ("::TestAttr%s::rs", "rs", "Short%s", True), - ("::TestAttr%s::us", "us", "UnsignedShort%s", False), - ("::TestAttr%s::rus", "rus", "UnsignedShort%s", True), - ("::TestAttr%s::l", "l", "Long%s", False), - ("::TestAttr%s::rl", "rl", "Long%s", True), - ("::TestAttr%s::ul", "ul", "UnsignedLong%s", False), - ("::TestAttr%s::rul", "rul", "UnsignedLong%s", True), - ("::TestAttr%s::ll", "ll", "LongLong%s", False), - ("::TestAttr%s::rll", "rll", "LongLong%s", True), - ("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False), - ("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True), - ("::TestAttr%s::str", "str", "String%s", False), - ("::TestAttr%s::rstr", "rstr", "String%s", True), - ("::TestAttr%s::obj", "obj", "Object%s", False), - ("::TestAttr%s::robj", "robj", "Object%s", True), - ("::TestAttr%s::object", "object", "Object%s", False), - ("::TestAttr%s::f", "f", "Float%s", False), - ("::TestAttr%s::rf", "rf", "Float%s", True), - ] - - parser.parse( - """ - interface TestAttr { - attribute byte b; - readonly attribute byte rb; - attribute octet o; - readonly attribute octet ro; - attribute short s; - readonly attribute short rs; - attribute unsigned short us; - readonly attribute unsigned short rus; - attribute long l; - readonly attribute long rl; - attribute unsigned long ul; - readonly attribute unsigned long rul; - attribute long long ll; - readonly attribute long long rll; - attribute unsigned long long ull; - readonly attribute unsigned long long rull; - attribute DOMString str; - readonly attribute DOMString rstr; - attribute object obj; - readonly attribute object robj; - attribute object _object; - attribute float f; - readonly attribute float rf; - }; - - interface TestAttrNullable { - attribute byte? b; - readonly attribute byte? rb; - attribute octet? o; - readonly attribute octet? ro; - attribute short? s; - readonly attribute short? rs; - attribute unsigned short? us; - readonly attribute unsigned short? rus; - attribute long? l; - readonly attribute long? rl; - attribute unsigned long? ul; - readonly attribute unsigned long? rul; - attribute long long? ll; - readonly attribute long long? rll; - attribute unsigned long long? ull; - readonly attribute unsigned long long? rull; - attribute DOMString? str; - readonly attribute DOMString? rstr; - attribute object? obj; - readonly attribute object? robj; - attribute object? _object; - attribute float? f; - readonly attribute float? rf; - }; - """ - ) - - results = parser.finish() - - def checkAttr(attr, QName, name, type, readonly): - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.ok(attr.isAttr(), "Attr is an Attr") - harness.ok(not attr.isMethod(), "Attr is not an method") - harness.ok(not attr.isConst(), "Attr is not a const") - harness.check(attr.identifier.QName(), QName, "Attr has the right QName") - harness.check(attr.identifier.name, name, "Attr has the right name") - harness.check(str(attr.type), type, "Attr has the right type") - harness.check(attr.readonly, readonly, "Attr's readonly state is correct") - - harness.ok(True, "TestAttr interface parsed without error.") - harness.check(len(results), 2, "Should be two productions.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestAttr", "Interface has the right QName" - ) - harness.check(iface.identifier.name, "TestAttr", "Interface has the right name") - harness.check( - len(iface.members), len(testData), "Expect %s members" % len(testData) - ) - - attrs = iface.members - - for i in range(len(attrs)): - data = testData[i] - attr = attrs[i] - (QName, name, type, readonly) = data - checkAttr(attr, QName % "", name, type % "", readonly) - - iface = results[1] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName" - ) - harness.check( - iface.identifier.name, "TestAttrNullable", "Interface has the right name" - ) - harness.check( - len(iface.members), len(testData), "Expect %s members" % len(testData) - ) - - attrs = iface.members - - for i in range(len(attrs)): - data = testData[i] - attr = attrs[i] - (QName, name, type, readonly) = data - checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [SetterThrows] readonly attribute boolean foo; - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should not allow [SetterThrows] on readonly attributes") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throw] readonly attribute boolean foo; - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should spell [Throws] correctly") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [SameObject] readonly attribute boolean foo; - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, "Should not allow [SameObject] on attributes not of interface type" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [SameObject] readonly attribute A foo; - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(not threw, "Should allow [SameObject] on attributes of interface type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py b/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py deleted file mode 100644 index f3249de900a..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_attr_sequence_type.py +++ /dev/null @@ -1,77 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface AttrSequenceType { - attribute sequence<object> foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Attribute type must not be a sequence type") - - parser.reset() - - threw = False - try: - parser.parse( - """ - interface AttrUnionWithSequenceType { - attribute (sequence<object> or DOMString) foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Attribute type must not be a union with a sequence member type") - - parser.reset() - - threw = False - try: - parser.parse( - """ - interface AttrNullableUnionWithSequenceType { - attribute (sequence<object>? or DOMString) foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Attribute type must not be a union with a nullable sequence " "member type", - ) - - parser.reset() - - threw = False - try: - parser.parse( - """ - interface AttrUnionWithUnionWithSequenceType { - attribute ((sequence<object> or DOMString) or AttrUnionWithUnionWithSequenceType) foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Attribute type must not be a union type with a union member " - "type that has a sequence member type", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py b/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py deleted file mode 100644 index 97a7f47859a..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_attributes_on_types.py +++ /dev/null @@ -1,570 +0,0 @@ -# Import the WebIDL module, so we can do isinstance checks and whatnot -import WebIDL - - -def WebIDLTest(parser, harness): - # Basic functionality - threw = False - try: - parser.parse( - """ - typedef [EnforceRange] long Foo; - typedef [Clamp] long Bar; - typedef [LegacyNullToEmptyString] DOMString Baz; - dictionary A { - required [EnforceRange] long a; - required [Clamp] long b; - [ChromeOnly, EnforceRange] long c; - Foo d; - }; - interface B { - attribute Foo typedefFoo; - attribute [EnforceRange] long foo; - attribute [Clamp] long bar; - attribute [LegacyNullToEmptyString] DOMString baz; - undefined method([EnforceRange] long foo, [Clamp] long bar, - [LegacyNullToEmptyString] DOMString baz); - undefined method2(optional [EnforceRange] long foo, optional [Clamp] long bar, - optional [LegacyNullToEmptyString] DOMString baz); - undefined method3(optional [LegacyNullToEmptyString] UTF8String foo = ""); - }; - interface C { - attribute [EnforceRange] long? foo; - attribute [Clamp] long? bar; - undefined method([EnforceRange] long? foo, [Clamp] long? bar); - undefined method2(optional [EnforceRange] long? foo, optional [Clamp] long? bar); - }; - interface Setlike { - setlike<[Clamp] long>; - }; - interface Maplike { - maplike<[Clamp] long, [EnforceRange] long>; - }; - interface Iterable { - iterable<[Clamp] long, [EnforceRange] long>; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(not threw, "Should not have thrown on parsing normal") - if not threw: - harness.check( - results[0].innerType.hasEnforceRange(), True, "Foo is [EnforceRange]" - ) - harness.check(results[1].innerType.hasClamp(), True, "Bar is [Clamp]") - harness.check( - results[2].innerType.legacyNullToEmptyString, - True, - "Baz is [LegacyNullToEmptyString]", - ) - A = results[3] - harness.check( - A.members[0].type.hasEnforceRange(), True, "A.a is [EnforceRange]" - ) - harness.check(A.members[1].type.hasClamp(), True, "A.b is [Clamp]") - harness.check( - A.members[2].type.hasEnforceRange(), True, "A.c is [EnforceRange]" - ) - harness.check( - A.members[3].type.hasEnforceRange(), True, "A.d is [EnforceRange]" - ) - B = results[4] - harness.check( - B.members[0].type.hasEnforceRange(), True, "B.typedefFoo is [EnforceRange]" - ) - harness.check( - B.members[1].type.hasEnforceRange(), True, "B.foo is [EnforceRange]" - ) - harness.check(B.members[2].type.hasClamp(), True, "B.bar is [Clamp]") - harness.check( - B.members[3].type.legacyNullToEmptyString, - True, - "B.baz is [LegacyNullToEmptyString]", - ) - method = B.members[4].signatures()[0][1] - harness.check( - method[0].type.hasEnforceRange(), - True, - "foo argument of method is [EnforceRange]", - ) - harness.check( - method[1].type.hasClamp(), True, "bar argument of method is [Clamp]" - ) - harness.check( - method[2].type.legacyNullToEmptyString, - True, - "baz argument of method is [LegacyNullToEmptyString]", - ) - method2 = B.members[5].signatures()[0][1] - harness.check( - method2[0].type.hasEnforceRange(), - True, - "foo argument of method2 is [EnforceRange]", - ) - harness.check( - method2[1].type.hasClamp(), True, "bar argument of method2 is [Clamp]" - ) - harness.check( - method2[2].type.legacyNullToEmptyString, - True, - "baz argument of method2 is [LegacyNullToEmptyString]", - ) - - method3 = B.members[6].signatures()[0][1] - harness.check( - method3[0].type.legacyNullToEmptyString, - True, - "bar argument of method2 is [LegacyNullToEmptyString]", - ) - harness.check( - method3[0].defaultValue.type.isUTF8String(), - True, - "default value of bar argument of method2 is correctly coerced to UTF8String", - ) - - C = results[5] - harness.ok(C.members[0].type.nullable(), "C.foo is nullable") - harness.ok(C.members[0].type.hasEnforceRange(), "C.foo has [EnforceRange]") - harness.ok(C.members[1].type.nullable(), "C.bar is nullable") - harness.ok(C.members[1].type.hasClamp(), "C.bar has [Clamp]") - method = C.members[2].signatures()[0][1] - harness.ok(method[0].type.nullable(), "foo argument of method is nullable") - harness.ok( - method[0].type.hasEnforceRange(), - "foo argument of method has [EnforceRange]", - ) - harness.ok(method[1].type.nullable(), "bar argument of method is nullable") - harness.ok(method[1].type.hasClamp(), "bar argument of method has [Clamp]") - method2 = C.members[3].signatures()[0][1] - harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable") - harness.ok( - method2[0].type.hasEnforceRange(), - "foo argument of method2 has [EnforceRange]", - ) - harness.ok(method2[1].type.nullable(), "bar argument of method2 is nullable") - harness.ok(method2[1].type.hasClamp(), "bar argument of method2 has [Clamp]") - - # Test [AllowShared] - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [AllowShared] ArrayBufferView Foo; - dictionary A { - required [AllowShared] ArrayBufferView a; - [ChromeOnly, AllowShared] ArrayBufferView b; - Foo c; - }; - interface B { - attribute Foo typedefFoo; - attribute [AllowShared] ArrayBufferView foo; - undefined method([AllowShared] ArrayBufferView foo); - undefined method2(optional [AllowShared] ArrayBufferView foo); - }; - interface C { - attribute [AllowShared] ArrayBufferView? foo; - undefined method([AllowShared] ArrayBufferView? foo); - undefined method2(optional [AllowShared] ArrayBufferView? foo); - }; - interface Setlike { - setlike<[AllowShared] ArrayBufferView>; - }; - interface Maplike { - maplike<[Clamp] long, [AllowShared] ArrayBufferView>; - }; - interface Iterable { - iterable<[Clamp] long, [AllowShared] ArrayBufferView>; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(not threw, "Should not have thrown on parsing normal") - if not threw: - harness.ok(results[0].innerType.hasAllowShared(), "Foo is [AllowShared]") - A = results[1] - harness.ok(A.members[0].type.hasAllowShared(), "A.a is [AllowShared]") - harness.ok(A.members[1].type.hasAllowShared(), "A.b is [AllowShared]") - harness.ok(A.members[2].type.hasAllowShared(), "A.c is [AllowShared]") - B = results[2] - harness.ok(B.members[0].type.hasAllowShared(), "B.typedefFoo is [AllowShared]") - harness.ok(B.members[1].type.hasAllowShared(), "B.foo is [AllowShared]") - method = B.members[2].signatures()[0][1] - harness.ok( - method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]" - ) - method2 = B.members[3].signatures()[0][1] - harness.ok( - method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]" - ) - C = results[3] - harness.ok(C.members[0].type.nullable(), "C.foo is nullable") - harness.ok(C.members[0].type.hasAllowShared(), "C.foo is [AllowShared]") - method = C.members[1].signatures()[0][1] - harness.ok(method[0].type.nullable(), "foo argument of method is nullable") - harness.ok( - method[0].type.hasAllowShared(), "foo argument of method is [AllowShared]" - ) - method2 = C.members[2].signatures()[0][1] - harness.ok(method2[0].type.nullable(), "foo argument of method2 is nullable") - harness.ok( - method2[0].type.hasAllowShared(), "foo argument of method2 is [AllowShared]" - ) - - ATTRIBUTES = [ - ("[Clamp]", "long"), - ("[EnforceRange]", "long"), - ("[LegacyNullToEmptyString]", "DOMString"), - ("[AllowShared]", "ArrayBufferView"), - ] - TEMPLATES = [ - ( - "required dictionary members", - """ - dictionary Foo { - %s required %s foo; - }; - """, - ), - ( - "optional arguments", - """ - interface Foo { - undefined foo(%s optional %s foo); - }; - """, - ), - ( - "typedefs", - """ - %s typedef %s foo; - """, - ), - ( - "attributes", - """ - interface Foo { - %s attribute %s foo; - }; - """, - ), - ( - "readonly attributes", - """ - interface Foo { - readonly attribute %s %s foo; - }; - """, - ), - ( - "readonly unresolved attributes", - """ - interface Foo { - readonly attribute Bar baz; - }; - typedef %s %s Bar; - """, - ), - ( - "method", - """ - interface Foo { - %s %s foo(); - }; - """, - ), - ( - "interface", - """ - %s - interface Foo { - attribute %s foo; - }; - """, - ), - ( - "partial interface", - """ - interface Foo { - undefined foo(); - }; - %s - partial interface Foo { - attribute %s bar; - }; - """, - ), - ( - "interface mixin", - """ - %s - interface mixin Foo { - attribute %s foo; - }; - """, - ), - ( - "namespace", - """ - %s - namespace Foo { - attribute %s foo; - }; - """, - ), - ( - "partial namespace", - """ - namespace Foo { - undefined foo(); - }; - %s - partial namespace Foo { - attribute %s bar; - }; - """, - ), - ( - "dictionary", - """ - %s - dictionary Foo { - %s foo; - }; - """, - ), - ] - - for (name, template) in TEMPLATES: - parser = parser.reset() - threw = False - try: - parser.parse(template % ("", "long")) - parser.finish() - except: - threw = True - harness.ok(not threw, "Template for %s parses without attributes" % name) - for (attribute, type) in ATTRIBUTES: - parser = parser.reset() - threw = False - try: - parser.parse(template % (attribute, type)) - parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow %s on %s" % (attribute, name)) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [Clamp, EnforceRange] long Foo; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange]") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [EnforceRange, Clamp] long Foo; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange]") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [Clamp] long Foo; - typedef [EnforceRange] Foo bar; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [EnforceRange] long Foo; - typedef [Clamp] Foo bar; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs") - - TYPES = [ - "DOMString", - "unrestricted float", - "float", - "unrestricted double", - "double", - ] - - for type in TYPES: - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [Clamp] %s Foo; - """ - % type - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow [Clamp] on %s" % type) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [EnforceRange] %s Foo; - """ - % type - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow [EnforceRange] on %s" % type) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [LegacyNullToEmptyString] long Foo; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow [LegacyNullToEmptyString] on long") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [LegacyNullToEmptyString] JSString Foo; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow [LegacyNullToEmptyString] on JSString") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [LegacyNullToEmptyString] DOMString? Foo; - """ - ) - parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not allow [LegacyNullToEmptyString] on nullable DOMString" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [AllowShared] DOMString Foo; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[AllowShared] only allowed on buffer source types") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef [AllowShared=something] ArrayBufferView Foo; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[AllowShared] must take no arguments") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - undefined foo([Clamp] Bar arg); - }; - typedef long Bar; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(not threw, "Should allow type attributes on unresolved types") - harness.check( - results[0].members[0].signatures()[0][1][0].type.hasClamp(), - True, - "Unresolved types with type attributes should correctly resolve with attributes", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - undefined foo(Bar arg); - }; - typedef [Clamp] long Bar; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(not threw, "Should allow type attributes on typedefs") - harness.check( - results[0].members[0].signatures()[0][1][0].type.hasClamp(), - True, - "Unresolved types that resolve to typedefs with attributes should correctly resolve with attributes", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py b/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py deleted file mode 100644 index 6c913bba822..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_builtin_filename.py +++ /dev/null @@ -1,14 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface Test { - attribute long b; - }; - """ - ) - - attr = parser.finish()[0].members[0] - harness.check(attr.type.filename(), "<builtin>", "Filename on builtin type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_builtins.py b/components/script/dom/bindings/codegen/parser/tests/test_builtins.py deleted file mode 100644 index a75a12e8143..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_builtins.py +++ /dev/null @@ -1,59 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestBuiltins { - attribute boolean b; - attribute byte s8; - attribute octet u8; - attribute short s16; - attribute unsigned short u16; - attribute long s32; - attribute unsigned long u32; - attribute long long s64; - attribute unsigned long long u64; - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestBuiltins interface parsed without error.") - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - iface = results[0] - harness.check( - iface.identifier.QName(), "::TestBuiltins", "Interface has the right QName" - ) - harness.check(iface.identifier.name, "TestBuiltins", "Interface has the right name") - harness.check(iface.parent, None, "Interface has no parent") - - members = iface.members - harness.check(len(members), 9, "Should be one production") - - names = ["b", "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "ts"] - types = [ - "Boolean", - "Byte", - "Octet", - "Short", - "UnsignedShort", - "Long", - "UnsignedLong", - "LongLong", - "UnsignedLongLong", - "UnsignedLongLong", - ] - for i in range(9): - attr = members[i] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check( - attr.identifier.QName(), - "::TestBuiltins::" + names[i], - "Attr has correct QName", - ) - harness.check(attr.identifier.name, names[i], "Attr has correct name") - harness.check(str(attr.type), types[i], "Attr type is the correct name") - harness.ok(attr.type.isPrimitive(), "Should be a primitive type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py deleted file mode 100644 index a6f9f6ab9cb..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: UTF-8 -*- - -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestByteString { - attribute ByteString bs; - attribute DOMString ds; - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestByteString interface parsed without error.") - - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - iface = results[0] - harness.check( - iface.identifier.QName(), "::TestByteString", "Interface has the right QName" - ) - harness.check( - iface.identifier.name, "TestByteString", "Interface has the right name" - ) - harness.check(iface.parent, None, "Interface has no parent") - - members = iface.members - harness.check(len(members), 2, "Should be two productions") - - attr = members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check( - attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName" - ) - harness.check(attr.identifier.name, "bs", "Attr has correct name") - harness.check(str(attr.type), "ByteString", "Attr type is the correct name") - harness.ok(attr.type.isByteString(), "Should be ByteString type") - harness.ok(attr.type.isString(), "Should be String collective type") - harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type") - - # now check we haven't broken DOMStrings in the process. - attr = members[1] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check( - attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName" - ) - harness.check(attr.identifier.name, "ds", "Attr has correct name") - harness.check(str(attr.type), "String", "Attr type is the correct name") - harness.ok(attr.type.isDOMString(), "Should be DOMString type") - harness.ok(attr.type.isString(), "Should be String collective type") - harness.ok(not attr.type.isByteString(), "Should be not be ByteString type") - - # Cannot represent constant ByteString in IDL. - threw = False - try: - parser.parse( - """ - interface ConstByteString { - const ByteString foo = "hello" - }; - """ - ) - except WebIDL.WebIDLError: - threw = True - harness.ok( - threw, "Should have thrown a WebIDL error for ByteString default in interface" - ) - - # Can have optional ByteStrings with default values - try: - parser.parse( - """ - interface OptionalByteString { - undefined passByteString(optional ByteString arg = "hello"); - }; - """ - ) - results2 = parser.finish() - except WebIDL.WebIDLError as e: - harness.ok( - False, - "Should not have thrown a WebIDL error for ByteString " - "default in dictionary. " + str(e), - ) - - # Can have a default ByteString value in a dictionary - try: - parser.parse( - """ - dictionary OptionalByteStringDict { - ByteString item = "some string"; - }; - """ - ) - results3 = parser.finish() - except WebIDL.WebIDLError as e: - harness.ok( - False, - "Should not have thrown a WebIDL error for ByteString " - "default in dictionary. " + str(e), - ) - - # Don't allow control characters in ByteString literals - threw = False - try: - parser.parse( - """ - dictionary OptionalByteStringDict2 { - ByteString item = "\x03"; - }; - """ - ) - results4 = parser.finish() - except WebIDL.WebIDLError as e: - threw = True - - harness.ok( - threw, - "Should have thrown a WebIDL error for invalid ByteString " - "default in dictionary", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback.py b/components/script/dom/bindings/codegen/parser/tests/test_callback.py deleted file mode 100644 index 407644a6a8d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback.py +++ /dev/null @@ -1,42 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestCallback { - attribute CallbackType? listener; - }; - - callback CallbackType = boolean (unsigned long arg); - """ - ) - - results = parser.finish() - - harness.ok(True, "TestCallback interface parsed without error.") - harness.check(len(results), 2, "Should be two productions.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestCallback", "Interface has the right QName" - ) - harness.check(iface.identifier.name, "TestCallback", "Interface has the right name") - harness.check(len(iface.members), 1, "Expect %s members" % 1) - - attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.ok(attr.isAttr(), "Should be an attribute") - harness.ok(not attr.isMethod(), "Attr is not an method") - harness.ok(not attr.isConst(), "Attr is not a const") - harness.check( - attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName" - ) - harness.check(attr.identifier.name, "listener", "Attr has the right name") - t = attr.type - harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type") - harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type") - harness.ok(t.isCallback(), "Attr has the right type") - - callback = results[1] - harness.ok(not callback.isConstructor(), "callback is not constructor") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py deleted file mode 100644 index 832a92bb147..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback_constructor.py +++ /dev/null @@ -1,84 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestCallbackConstructor { - attribute CallbackConstructorType? constructorAttribute; - }; - - callback constructor CallbackConstructorType = TestCallbackConstructor (unsigned long arg); - """ - ) - - results = parser.finish() - - harness.ok(True, "TestCallbackConstructor interface parsed without error.") - harness.check(len(results), 2, "Should be two productions.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), - "::TestCallbackConstructor", - "Interface has the right QName", - ) - harness.check( - iface.identifier.name, "TestCallbackConstructor", "Interface has the right name" - ) - harness.check(len(iface.members), 1, "Expect %s members" % 1) - - attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.ok(attr.isAttr(), "Should be an attribute") - harness.ok(not attr.isMethod(), "Attr is not an method") - harness.ok(not attr.isConst(), "Attr is not a const") - harness.check( - attr.identifier.QName(), - "::TestCallbackConstructor::constructorAttribute", - "Attr has the right QName", - ) - harness.check( - attr.identifier.name, "constructorAttribute", "Attr has the right name" - ) - t = attr.type - harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type") - harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type") - harness.ok(t.isCallback(), "Attr has the right type") - - callback = results[1] - harness.ok(callback.isConstructor(), "Callback is constructor") - - parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyTreatNonObjectAsNull] - callback constructor CallbackConstructorType = object (); - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should throw on LegacyTreatNonObjectAsNull callback constructors" - ) - - parser.reset() - threw = False - try: - parser.parse( - """ - [MOZ_CAN_RUN_SCRIPT_BOUNDARY] - callback constructor CallbackConstructorType = object (); - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not permit MOZ_CAN_RUN_SCRIPT_BOUNDARY callback constructors" - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py deleted file mode 100644 index 0d657f48032..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py +++ /dev/null @@ -1,106 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - callback interface TestCallbackInterface { - attribute boolean bool; - }; - """ - ) - - results = parser.finish() - - iface = results[0] - - harness.ok(iface.isCallback(), "Interface should be a callback") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestInterface { - }; - callback interface TestCallbackInterface : TestInterface { - attribute boolean bool; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow non-callback parent of callback interface") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestInterface : TestCallbackInterface { - }; - callback interface TestCallbackInterface { - attribute boolean bool; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow callback parent of non-callback interface") - - parser = parser.reset() - parser.parse( - """ - callback interface TestCallbackInterface1 { - undefined foo(); - }; - callback interface TestCallbackInterface2 { - undefined foo(DOMString arg); - undefined foo(TestCallbackInterface1 arg); - }; - callback interface TestCallbackInterface3 { - undefined foo(DOMString arg); - undefined foo(TestCallbackInterface1 arg); - static undefined bar(); - }; - callback interface TestCallbackInterface4 { - undefined foo(DOMString arg); - undefined foo(TestCallbackInterface1 arg); - static undefined bar(); - const long baz = 5; - }; - callback interface TestCallbackInterface5 { - static attribute boolean bool; - undefined foo(); - }; - callback interface TestCallbackInterface6 { - undefined foo(DOMString arg); - undefined foo(TestCallbackInterface1 arg); - undefined bar(); - }; - callback interface TestCallbackInterface7 { - static attribute boolean bool; - }; - callback interface TestCallbackInterface8 { - attribute boolean bool; - }; - callback interface TestCallbackInterface9 : TestCallbackInterface1 { - undefined foo(); - }; - callback interface TestCallbackInterface10 : TestCallbackInterface1 { - undefined bar(); - }; - """ - ) - results = parser.finish() - for (i, iface) in enumerate(results): - harness.check( - iface.isSingleOperationInterface(), - i < 4, - "Interface %s should be a single operation interface" - % iface.identifier.name, - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py b/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py deleted file mode 100644 index c56c3dbde10..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_cereactions.py +++ /dev/null @@ -1,157 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions(DOMString a)] undefined foo(boolean arg2); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] with an argument") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions(DOMString b)] readonly attribute boolean bar; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] with an argument") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] attribute boolean bar; - }; - """ - ) - - results = parser.finish() - except Exception as e: - harness.ok( - False, - "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" - % e, - ) - threw = True - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] undefined foo(boolean arg2); - }; - """ - ) - - results = parser.finish() - except Exception as e: - harness.ok( - False, - "Shouldn't have thrown for [CEReactions] used on regular operations. %s" - % e, - ) - threw = True - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] readonly attribute boolean A; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should have thrown for [CEReactions] used on a readonly attribute" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [CEReactions] - interface Foo { - } - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] used on a interface") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] getter any(DOMString name); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] used on a named getter") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] legacycaller double compute(double x); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] used on a legacycaller") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - [CEReactions] stringifier DOMString (); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for [CEReactions] used on a stringifier") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py b/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py deleted file mode 100644 index 2aef8ebe8ff..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_conditional_dictionary_member.py +++ /dev/null @@ -1,128 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - dictionary Dict { - any foo; - [ChromeOnly] any bar; - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should have a dictionary") - members = results[0].members - harness.check(len(members), 2, "Should have two members") - # Note that members are ordered lexicographically, so "bar" comes - # before "foo". - harness.ok( - members[0].getExtendedAttribute("ChromeOnly"), "First member is not ChromeOnly" - ) - harness.ok( - not members[1].getExtendedAttribute("ChromeOnly"), "Second member is ChromeOnly" - ) - - parser = parser.reset() - parser.parse( - """ - dictionary Dict { - any foo; - any bar; - }; - - interface Iface { - [Constant, Cached] readonly attribute Dict dict; - }; - """ - ) - results = parser.finish() - harness.check(len(results), 2, "Should have a dictionary and an interface") - - parser = parser.reset() - exception = None - try: - parser.parse( - """ - dictionary Dict { - any foo; - [ChromeOnly] any bar; - }; - - interface Iface { - [Constant, Cached] readonly attribute Dict dict; - }; - """ - ) - results = parser.finish() - except Exception as e: - exception = e - - harness.ok(exception, "Should have thrown.") - harness.check( - exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception", - ) - - parser = parser.reset() - exception = None - try: - parser.parse( - """ - dictionary ParentDict { - [ChromeOnly] any bar; - }; - - dictionary Dict : ParentDict { - any foo; - }; - - interface Iface { - [Constant, Cached] readonly attribute Dict dict; - }; - """ - ) - results = parser.finish() - except Exception as e: - exception = e - - harness.ok(exception, "Should have thrown (2).") - harness.check( - exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception (2)", - ) - - parser = parser.reset() - exception = None - try: - parser.parse( - """ - dictionary GrandParentDict { - [ChromeOnly] any baz; - }; - - dictionary ParentDict : GrandParentDict { - any bar; - }; - - dictionary Dict : ParentDict { - any foo; - }; - - interface Iface { - [Constant, Cached] readonly attribute Dict dict; - }; - """ - ) - results = parser.finish() - except Exception as e: - exception = e - - harness.ok(exception, "Should have thrown (3).") - harness.check( - exception.message, - "[Cached] and [StoreInSlot] must not be used on an attribute " - "whose type contains a [ChromeOnly] dictionary member", - "Should have thrown the right exception (3)", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_const.py b/components/script/dom/bindings/codegen/parser/tests/test_const.py deleted file mode 100644 index f2d4b79d467..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_const.py +++ /dev/null @@ -1,96 +0,0 @@ -import WebIDL - -expected = [ - ("::TestConsts::zero", "zero", "Byte", 0), - ("::TestConsts::b", "b", "Byte", -1), - ("::TestConsts::o", "o", "Octet", 2), - ("::TestConsts::s", "s", "Short", -3), - ("::TestConsts::us", "us", "UnsignedShort", 4), - ("::TestConsts::l", "l", "Long", -5), - ("::TestConsts::ul", "ul", "UnsignedLong", 6), - ("::TestConsts::ull", "ull", "UnsignedLongLong", 7), - ("::TestConsts::ll", "ll", "LongLong", -8), - ("::TestConsts::t", "t", "Boolean", True), - ("::TestConsts::f", "f", "Boolean", False), - ("::TestConsts::fl", "fl", "Float", 0.2), - ("::TestConsts::db", "db", "Double", 0.2), - ("::TestConsts::ufl", "ufl", "UnrestrictedFloat", 0.2), - ("::TestConsts::udb", "udb", "UnrestrictedDouble", 0.2), - ("::TestConsts::fli", "fli", "Float", 2), - ("::TestConsts::dbi", "dbi", "Double", 2), - ("::TestConsts::ufli", "ufli", "UnrestrictedFloat", 2), - ("::TestConsts::udbi", "udbi", "UnrestrictedDouble", 2), -] - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestConsts { - const byte zero = 0; - const byte b = -1; - const octet o = 2; - const short s = -3; - const unsigned short us = 0x4; - const long l = -0X5; - const unsigned long ul = 6; - const unsigned long long ull = 7; - const long long ll = -010; - const boolean t = true; - const boolean f = false; - const float fl = 0.2; - const double db = 0.2; - const unrestricted float ufl = 0.2; - const unrestricted double udb = 0.2; - const float fli = 2; - const double dbi = 2; - const unrestricted float ufli = 2; - const unrestricted double udbi = 2; - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestConsts interface parsed without error.") - harness.check(len(results), 1, "Should be one production.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestConsts", "Interface has the right QName" - ) - harness.check(iface.identifier.name, "TestConsts", "Interface has the right name") - harness.check( - len(iface.members), len(expected), "Expect %s members" % len(expected) - ) - - for (const, (QName, name, type, value)) in zip(iface.members, expected): - harness.ok(isinstance(const, WebIDL.IDLConst), "Should be an IDLConst") - harness.ok(const.isConst(), "Const is a const") - harness.ok(not const.isAttr(), "Const is not an attr") - harness.ok(not const.isMethod(), "Const is not a method") - harness.check(const.identifier.QName(), QName, "Const has the right QName") - harness.check(const.identifier.name, name, "Const has the right name") - harness.check(str(const.type), type, "Const has the right type") - harness.ok(const.type.isPrimitive(), "All consts should be primitive") - harness.check( - str(const.value.type), - str(const.type), - "Const's value has the same type as the type", - ) - harness.check(const.value.value, value, "Const value has the right value.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestConsts { - const boolean? zero = 0; - }; - """ - ) - parser.finish() - except: - threw = True - harness.ok(threw, "Nullable types are not allowed for consts.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py deleted file mode 100644 index de5d52f1412..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py +++ /dev/null @@ -1,594 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - def checkArgument(argument, QName, name, type, optional, variadic): - harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") - harness.check( - argument.identifier.QName(), QName, "Argument has the right QName" - ) - harness.check(argument.identifier.name, name, "Argument has the right name") - harness.check(str(argument.type), type, "Argument has the right return type") - harness.check( - argument.optional, optional, "Argument has the right optional value" - ) - harness.check( - argument.variadic, variadic, "Argument has the right variadic value" - ) - - def checkMethod( - method, - QName, - name, - signatures, - static=True, - getter=False, - setter=False, - deleter=False, - legacycaller=False, - stringifier=False, - chromeOnly=False, - htmlConstructor=False, - secureContext=False, - pref=None, - func=None, - ): - harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") - harness.ok(method.isMethod(), "Method is a method") - harness.ok(not method.isAttr(), "Method is not an attr") - harness.ok(not method.isConst(), "Method is not a const") - harness.check(method.identifier.QName(), QName, "Method has the right QName") - harness.check(method.identifier.name, name, "Method has the right name") - harness.check(method.isStatic(), static, "Method has the correct static value") - harness.check(method.isGetter(), getter, "Method has the correct getter value") - harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check( - method.isDeleter(), deleter, "Method has the correct deleter value" - ) - harness.check( - method.isLegacycaller(), - legacycaller, - "Method has the correct legacycaller value", - ) - harness.check( - method.isStringifier(), - stringifier, - "Method has the correct stringifier value", - ) - harness.check( - method.getExtendedAttribute("ChromeOnly") is not None, - chromeOnly, - "Method has the correct value for ChromeOnly", - ) - harness.check( - method.isHTMLConstructor(), - htmlConstructor, - "Method has the correct htmlConstructor value", - ) - harness.check( - len(method.signatures()), - len(signatures), - "Method has the correct number of signatures", - ) - harness.check( - method.getExtendedAttribute("Pref"), - pref, - "Method has the correct pref value", - ) - harness.check( - method.getExtendedAttribute("Func"), - func, - "Method has the correct func value", - ) - harness.check( - method.getExtendedAttribute("SecureContext") is not None, - secureContext, - "Method has the correct SecureContext value", - ) - - sigpairs = zip(method.signatures(), signatures) - for (gotSignature, expectedSignature) in sigpairs: - (gotRetType, gotArgs) = gotSignature - (expectedRetType, expectedArgs) = expectedSignature - - harness.check( - str(gotRetType), expectedRetType, "Method has the expected return type." - ) - - for i in range(0, len(gotArgs)): - (QName, name, type, optional, variadic) = expectedArgs[i] - checkArgument(gotArgs[i], QName, name, type, optional, variadic) - - def checkResults(results): - harness.check(len(results), 3, "Should be three productions") - harness.ok( - isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface" - ) - harness.ok( - isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface" - ) - harness.ok( - isinstance(results[2], WebIDL.IDLInterface), "Should be an IDLInterface" - ) - - checkMethod( - results[0].ctor(), - "::TestConstructorNoArgs::constructor", - "constructor", - [("TestConstructorNoArgs (Wrapper)", [])], - ) - harness.check( - len(results[0].members), 0, "TestConstructorNoArgs should not have members" - ) - checkMethod( - results[1].ctor(), - "::TestConstructorWithArgs::constructor", - "constructor", - [ - ( - "TestConstructorWithArgs (Wrapper)", - [ - ( - "::TestConstructorWithArgs::constructor::name", - "name", - "String", - False, - False, - ) - ], - ) - ], - ) - harness.check( - len(results[1].members), - 0, - "TestConstructorWithArgs should not have members", - ) - checkMethod( - results[2].ctor(), - "::TestConstructorOverloads::constructor", - "constructor", - [ - ( - "TestConstructorOverloads (Wrapper)", - [ - ( - "::TestConstructorOverloads::constructor::foo", - "foo", - "Object", - False, - False, - ) - ], - ), - ( - "TestConstructorOverloads (Wrapper)", - [ - ( - "::TestConstructorOverloads::constructor::bar", - "bar", - "Boolean", - False, - False, - ) - ], - ), - ], - ) - harness.check( - len(results[2].members), - 0, - "TestConstructorOverloads should not have members", - ) - - parser.parse( - """ - interface TestConstructorNoArgs { - constructor(); - }; - - interface TestConstructorWithArgs { - constructor(DOMString name); - }; - - interface TestConstructorOverloads { - constructor(object foo); - constructor(boolean bar); - }; - """ - ) - results = parser.finish() - checkResults(results) - - parser = parser.reset() - parser.parse( - """ - interface TestPrefConstructor { - [Pref="dom.webidl.test1"] constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestPrefConstructor::constructor", - "constructor", - [("TestPrefConstructor (Wrapper)", [])], - pref=["dom.webidl.test1"], - ) - - parser = parser.reset() - parser.parse( - """ - interface TestChromeOnlyConstructor { - [ChromeOnly] constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestChromeOnlyConstructor::constructor", - "constructor", - [("TestChromeOnlyConstructor (Wrapper)", [])], - chromeOnly=True, - ) - - parser = parser.reset() - parser.parse( - """ - interface TestSCConstructor { - [SecureContext] constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestSCConstructor::constructor", - "constructor", - [("TestSCConstructor (Wrapper)", [])], - secureContext=True, - ) - - parser = parser.reset() - parser.parse( - """ - interface TestFuncConstructor { - [Func="Document::IsWebAnimationsEnabled"] constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestFuncConstructor::constructor", - "constructor", - [("TestFuncConstructor (Wrapper)", [])], - func=["Document::IsWebAnimationsEnabled"], - ) - - parser = parser.reset() - parser.parse( - """ - interface TestPrefChromeOnlySCFuncConstructor { - [ChromeOnly, Pref="dom.webidl.test1", SecureContext, Func="Document::IsWebAnimationsEnabled"] - constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestPrefChromeOnlySCFuncConstructor::constructor", - "constructor", - [("TestPrefChromeOnlySCFuncConstructor (Wrapper)", [])], - func=["Document::IsWebAnimationsEnabled"], - pref=["dom.webidl.test1"], - chromeOnly=True, - secureContext=True, - ) - - parser = parser.reset() - parser.parse( - """ - interface TestHTMLConstructor { - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - - checkMethod( - results[0].ctor(), - "::TestHTMLConstructor::constructor", - "constructor", - [("TestHTMLConstructor (Wrapper)", [])], - htmlConstructor=True, - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestChromeOnlyConstructor { - constructor() - [ChromeOnly] constructor(DOMString a); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have both a constructor and a ChromeOnly constructor") - - # Test HTMLConstructor with argument - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorWithArgs { - [HTMLConstructor] constructor(DOMString a); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "HTMLConstructor should take no argument") - - # Test HTMLConstructor on a callback interface - parser = parser.reset() - threw = False - try: - parser.parse( - """ - callback interface TestHTMLConstructorOnCallbackInterface { - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "HTMLConstructor can't be used on a callback interface") - - # Test HTMLConstructor and constructor operation - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - constructor(); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have both a constructor and a HTMLConstructor") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [Throws] - constructor(); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have both a throwing constructor and a HTMLConstructor") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - constructor(DOMString a); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have both a HTMLConstructor and a constructor operation") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [Throws] - constructor(DOMString a); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Can't have both a HTMLConstructor and a throwing constructor " "operation", - ) - - # Test HTMLConstructor and [ChromeOnly] constructor operation - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [ChromeOnly] - constructor(); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have both a ChromeOnly constructor and a HTMLConstructor") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [Throws, ChromeOnly] - constructor(); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Can't have both a throwing chromeonly constructor and a " "HTMLConstructor", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [ChromeOnly] - constructor(DOMString a); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Can't have both a HTMLConstructor and a chromeonly constructor " "operation", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestHTMLConstructorAndConstructor { - [Throws, ChromeOnly] - constructor(DOMString a); - [HTMLConstructor] constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Can't have both a HTMLConstructor and a throwing chromeonly " - "constructor operation", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyNoInterfaceObject] - interface InterfaceWithoutInterfaceObject { - constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Can't have a constructor operation on a [LegacyNoInterfaceObject] " - "interface", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface InterfaceWithPartial { - }; - - partial interface InterfaceWithPartial { - constructor(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have a constructor operation on a partial interface") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface InterfaceWithMixin { - }; - - interface mixin Mixin { - constructor(); - }; - - InterfaceWithMixin includes Mixin - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Can't have a constructor operation on a mixin") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py deleted file mode 100644 index 5f3663602e4..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py +++ /dev/null @@ -1,72 +0,0 @@ -import traceback - - -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - [Global, Exposed=TestConstructorGlobal] - interface TestConstructorGlobal { - constructor(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=TestLegacyFactoryFunctionGlobal, - LegacyFactoryFunction=FooBar] - interface TestLegacyFactoryFunctionGlobal { - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyFactoryFunction=FooBar, Global, - Exposed=TestLegacyFactoryFunctionGlobal] - interface TestLegacyFactoryFunctionGlobal { - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=TestHTMLConstructorGlobal] - interface TestHTMLConstructorGlobal { - [HTMLConstructor] constructor(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py deleted file mode 100644 index 9855352a9d4..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py +++ /dev/null @@ -1,47 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - [LegacyNoInterfaceObject] - interface TestConstructorLegacyNoInterfaceObject { - constructor(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - - parser.parse( - """ - [LegacyNoInterfaceObject, LegacyFactoryFunction=FooBar] - interface TestLegacyFactoryFunctionLegacyNoInterfaceObject { - }; - """ - ) - - # Test HTMLConstructor and LegacyNoInterfaceObject - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - [LegacyNoInterfaceObject] - interface TestHTMLConstructorLegacyNoInterfaceObject { - [HTMLConstructor] constructor(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py b/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py deleted file mode 100644 index 6649f4ec05d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_deduplicate.py +++ /dev/null @@ -1,20 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface Foo; - interface Bar; - interface Foo; - """ - ) - - results = parser.finish() - - # There should be no duplicate interfaces in the result. - expectedNames = sorted(["Foo", "Bar"]) - actualNames = sorted(map(lambda iface: iface.identifier.name, results)) - harness.check( - actualNames, expectedNames, "Parser shouldn't output duplicate names." - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py b/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py deleted file mode 100644 index e7d04f995a9..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py +++ /dev/null @@ -1,875 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - dictionary Dict2 : Dict1 { - long child = 5; - Dict1 aaandAnother; - }; - dictionary Dict1 { - long parent; - double otherParent; - }; - """ - ) - results = parser.finish() - - dict1 = results[1] - dict2 = results[0] - - harness.check(len(dict1.members), 2, "Dict1 has two members") - harness.check(len(dict2.members), 2, "Dict2 has four members") - - harness.check( - dict1.members[0].identifier.name, "otherParent", "'o' comes before 'p'" - ) - harness.check( - dict1.members[1].identifier.name, "parent", "'o' really comes before 'p'" - ) - harness.check( - dict2.members[0].identifier.name, "aaandAnother", "'a' comes before 'c'" - ) - harness.check( - dict2.members[1].identifier.name, "child", "'a' really comes before 'c'" - ) - - # Test partial dictionary. - parser = parser.reset() - parser.parse( - """ - dictionary A { - long c; - long g; - }; - partial dictionary A { - long h; - long d; - }; - """ - ) - results = parser.finish() - - dict1 = results[0] - harness.check(len(dict1.members), 4, "Dict1 has four members") - harness.check(dict1.members[0].identifier.name, "c", "c should be first") - harness.check(dict1.members[1].identifier.name, "d", "d should come after c") - harness.check(dict1.members[2].identifier.name, "g", "g should come after d") - harness.check(dict1.members[3].identifier.name, "h", "h should be last") - - # Now reset our parser - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Dict { - long prop = 5; - long prop; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow name duplication in a dictionary") - - # Test no name duplication across normal and partial dictionary. - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - long prop = 5; - }; - partial dictionary A { - long prop; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not allow name duplication across normal and partial dictionary" - ) - - # Now reset our parser again - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Dict1 : Dict2 { - long prop = 5; - }; - dictionary Dict2 : Dict3 { - long prop2; - }; - dictionary Dict3 { - double prop; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not allow name duplication in a dictionary and " "its ancestor" - ) - - # More reset - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Iface {}; - dictionary Dict : Iface { - long prop; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow non-dictionary parents for dictionaries") - - # Even more reset - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A : B {}; - dictionary B : A {}; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow cycles in dictionary inheritance chains") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - [LegacyNullToEmptyString] DOMString foo; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not allow [LegacyNullToEmptyString] on dictionary members" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(A arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Trailing dictionary arg must be optional") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional A arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Trailing dictionary arg must have a default value") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo((A or DOMString) arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Trailing union arg containing a dictionary must be optional") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or DOMString) arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Trailing union arg containing a dictionary must have a default value" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(A arg1, optional long arg2); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Dictionary arg followed by optional arg must be optional") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional A arg1, optional long arg2); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Dictionary arg followed by optional arg must have default value") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(A arg1, optional long arg2, long arg3); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - not threw, - "Dictionary arg followed by non-optional arg doesn't have to be optional", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo((A or DOMString) arg1, optional long arg2); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Union arg containing dictionary followed by optional arg must " "be optional", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or DOMString) arg1, optional long arg2); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Union arg containing dictionary followed by optional arg must " - "have a default value", - ) - - parser = parser.reset() - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(A arg1, long arg2); - }; - """ - ) - results = parser.finish() - harness.ok(True, "Dictionary arg followed by required arg can be required") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional A? arg1 = {}); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = x - - harness.ok(threw, "Optional dictionary arg must not be nullable") - harness.ok( - "nullable" in str(threw), - "Must have the expected exception for optional nullable dictionary arg", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - required long x; - }; - interface X { - undefined doFoo(A? arg1); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = x - - harness.ok(threw, "Required dictionary arg must not be nullable") - harness.ok( - "nullable" in str(threw), - "Must have the expected exception for required nullable " "dictionary arg", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or long)? arg1 = {}); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = x - - harness.ok(threw, "Dictionary arg must not be in an optional nullable union") - harness.ok( - "nullable" in str(threw), - "Must have the expected exception for optional nullable union " - "arg containing dictionary", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - required long x; - }; - interface X { - undefined doFoo((A or long)? arg1); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = x - - harness.ok(threw, "Dictionary arg must not be in a required nullable union") - harness.ok( - "nullable" in str(threw), - "Must have the expected exception for required nullable union " - "arg containing dictionary", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(sequence<A?> arg1); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(not threw, "Nullable union should be allowed in a sequence argument") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or long?) arg1); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Dictionary must not be in a union with a nullable type") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (long? or A) arg1); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "A nullable type must not be in a union with a dictionary") - - parser = parser.reset() - parser.parse( - """ - dictionary A { - }; - interface X { - A? doFoo(); - }; - """ - ) - results = parser.finish() - harness.ok(True, "Dictionary return value can be nullable") - - parser = parser.reset() - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional A arg = {}); - }; - """ - ) - results = parser.finish() - harness.ok(True, "Dictionary arg should actually parse") - - parser = parser.reset() - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or DOMString) arg = {}); - }; - """ - ) - results = parser.finish() - harness.ok(True, "Union arg containing a dictionary should actually parse") - - parser = parser.reset() - parser.parse( - """ - dictionary A { - }; - interface X { - undefined doFoo(optional (A or DOMString) arg = "abc"); - }; - """ - ) - results = parser.finish() - harness.ok( - True, - "Union arg containing a dictionary with string default should actually parse", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - Foo foo; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Member type must not be its Dictionary.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo3 : Foo { - short d; - }; - - dictionary Foo2 : Foo3 { - boolean c; - }; - - dictionary Foo1 : Foo2 { - long a; - }; - - dictionary Foo { - Foo1 b; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be a Dictionary that " "inherits from its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - (Foo or DOMString)[]? b; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be a Nullable type " - "whose inner type includes its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - (DOMString or Foo) b; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be a Union type, one of " - "whose member types includes its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - sequence<sequence<sequence<Foo>>> c; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be a Sequence type " - "whose element type includes its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - (DOMString or Foo)[] d; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be an Array type " - "whose element type includes its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - Foo1 b; - }; - - dictionary Foo3 { - Foo d; - }; - - dictionary Foo2 : Foo3 { - short c; - }; - - dictionary Foo1 : Foo2 { - long a; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Member type must not be a Dictionary, one of whose " - "members or inherited members has a type that includes " - "its Dictionary.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - }; - - dictionary Bar { - Foo? d; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Member type must not be a nullable dictionary") - - parser = parser.reset() - parser.parse( - """ - dictionary Foo { - unrestricted float urFloat = 0; - unrestricted float urFloat2 = 1.1; - unrestricted float urFloat3 = -1.1; - unrestricted float? urFloat4 = null; - unrestricted float infUrFloat = Infinity; - unrestricted float negativeInfUrFloat = -Infinity; - unrestricted float nanUrFloat = NaN; - - unrestricted double urDouble = 0; - unrestricted double urDouble2 = 1.1; - unrestricted double urDouble3 = -1.1; - unrestricted double? urDouble4 = null; - unrestricted double infUrDouble = Infinity; - unrestricted double negativeInfUrDouble = -Infinity; - unrestricted double nanUrDouble = NaN; - }; - """ - ) - results = parser.finish() - harness.ok(True, "Parsing default values for unrestricted types succeeded.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - double f = Infinity; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to Infinity") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - double f = -Infinity; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - double f = NaN; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to NaN") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - float f = Infinity; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to Infinity") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - float f = -Infinity; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - float f = NaN; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Only unrestricted values can be initialized to NaN") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Foo { - long module; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(not threw, "Should be able to use 'module' as a dictionary member name") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py deleted file mode 100644 index e96026c2a09..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py +++ /dev/null @@ -1,425 +0,0 @@ -import traceback - - -def firstArgType(method): - return method.signatures()[0][1][0].type - - -def WebIDLTest(parser, harness): - parser.parse( - """ - // Give our dictionary a required member so we don't need to - // mess with optional and default values. - dictionary Dict { - required long member; - }; - callback interface Foo { - }; - interface Bar { - // Bit of a pain to get things that have dictionary types - undefined passDict(Dict arg); - undefined passFoo(Foo arg); - undefined passNullableUnion((object? or DOMString) arg); - undefined passNullable(Foo? arg); - }; - """ - ) - results = parser.finish() - - iface = results[2] - harness.ok(iface.isInterface(), "Should have interface") - dictMethod = iface.members[0] - ifaceMethod = iface.members[1] - nullableUnionMethod = iface.members[2] - nullableIfaceMethod = iface.members[3] - - dictType = firstArgType(dictMethod) - ifaceType = firstArgType(ifaceMethod) - - harness.ok(dictType.isDictionary(), "Should have dictionary type") - harness.ok(ifaceType.isInterface(), "Should have interface type") - harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type") - - harness.ok( - not dictType.isDistinguishableFrom(ifaceType), - "Dictionary not distinguishable from callback interface", - ) - harness.ok( - not ifaceType.isDistinguishableFrom(dictType), - "Callback interface not distinguishable from dictionary", - ) - - nullableUnionType = firstArgType(nullableUnionMethod) - nullableIfaceType = firstArgType(nullableIfaceMethod) - - harness.ok(nullableUnionType.isUnion(), "Should have union type") - harness.ok(nullableIfaceType.isInterface(), "Should have interface type") - harness.ok(nullableIfaceType.nullable(), "Should have nullable type") - - harness.ok( - not nullableUnionType.isDistinguishableFrom(nullableIfaceType), - "Nullable type not distinguishable from union with nullable " "member type", - ) - harness.ok( - not nullableIfaceType.isDistinguishableFrom(nullableUnionType), - "Union with nullable member type not distinguishable from " "nullable type", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestIface { - undefined passKid(Kid arg); - undefined passParent(Parent arg); - undefined passGrandparent(Grandparent arg); - undefined passUnrelated1(Unrelated1 arg); - undefined passUnrelated2(Unrelated2 arg); - undefined passArrayBuffer(ArrayBuffer arg); - undefined passArrayBuffer(ArrayBufferView arg); - }; - - interface Kid : Parent {}; - interface Parent : Grandparent {}; - interface Grandparent {}; - interface Unrelated1 {}; - interface Unrelated2 {}; - """ - ) - results = parser.finish() - - iface = results[0] - harness.ok(iface.isInterface(), "Should have interface") - argTypes = [firstArgType(method) for method in iface.members] - unrelatedTypes = [firstArgType(method) for method in iface.members[-3:]] - - for type1 in argTypes: - for type2 in argTypes: - distinguishable = type1 is not type2 and ( - type1 in unrelatedTypes or type2 in unrelatedTypes - ) - - harness.check( - type1.isDistinguishableFrom(type2), - distinguishable, - "Type %s should %sbe distinguishable from type %s" - % (type1, "" if distinguishable else "not ", type2), - ) - harness.check( - type2.isDistinguishableFrom(type1), - distinguishable, - "Type %s should %sbe distinguishable from type %s" - % (type2, "" if distinguishable else "not ", type1), - ) - - parser = parser.reset() - parser.parse( - """ - interface Dummy {}; - interface TestIface { - undefined method(long arg1, TestIface arg2); - undefined method(long arg1, long arg2); - undefined method(long arg1, Dummy arg2); - undefined method(DOMString arg1, DOMString arg2, DOMString arg3); - }; - """ - ) - results = parser.finish() - harness.check(len(results[1].members), 1, "Should look like we have one method") - harness.check( - len(results[1].members[0].signatures()), 4, "Should have four signatures" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Dummy {}; - interface TestIface { - undefined method(long arg1, TestIface arg2); - undefined method(long arg1, long arg2); - undefined method(any arg1, Dummy arg2); - undefined method(DOMString arg1, DOMString arg2, DOMString arg3); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should throw when args before the distinguishing arg are not " - "all the same type", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Dummy {}; - interface TestIface { - undefined method(long arg1, TestIface arg2); - undefined method(long arg1, long arg2); - undefined method(any arg1, DOMString arg2); - undefined method(DOMString arg1, DOMString arg2, DOMString arg3); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should throw when there is no distinguishing index") - - # Now let's test our whole distinguishability table - argTypes = [ - "long", - "short", - "long?", - "short?", - "boolean", - "boolean?", - "undefined", - "undefined?", - "DOMString", - "ByteString", - "UTF8String", - "Enum", - "Enum2", - "Interface", - "Interface?", - "AncestorInterface", - "UnrelatedInterface", - "CallbackInterface", - "CallbackInterface?", - "CallbackInterface2", - "object", - "Callback", - "Callback2", - "Dict", - "Dict2", - "sequence<long>", - "sequence<short>", - "record<DOMString, object>", - "record<USVString, Dict>", - "record<ByteString, long>", - "record<UTF8String, long>", - "any", - "Promise<any>", - "Promise<any>?", - "USVString", - "JSString", - "ArrayBuffer", - "ArrayBufferView", - "Uint8Array", - "Uint16Array", - "(long or Callback)", - "(long or Dict)", - ] - - # Try to categorize things a bit to keep list lengths down - def allBut(list1, list2): - return [ - a - for a in list1 - if a not in list2 - and (a != "any" and a != "Promise<any>" and a != "Promise<any>?") - ] - - unions = ["(long or Callback)", "(long or Dict)"] - numerics = ["long", "short", "long?", "short?"] - booleans = ["boolean", "boolean?"] - undefineds = ["undefined", "undefined?"] - primitives = numerics + booleans - nonNumerics = allBut(argTypes, numerics + unions) - nonBooleans = allBut(argTypes, booleans) - strings = [ - "DOMString", - "ByteString", - "Enum", - "Enum2", - "USVString", - "JSString", - "UTF8String", - ] - nonStrings = allBut(argTypes, strings) - nonObjects = undefineds + primitives + strings - objects = allBut(argTypes, nonObjects) - bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"] - interfaces = [ - "Interface", - "Interface?", - "AncestorInterface", - "UnrelatedInterface", - ] + bufferSourceTypes - nullables = [ - "long?", - "short?", - "boolean?", - "undefined?", - "Interface?", - "CallbackInterface?", - "Dict", - "Dict2", - "Date?", - "any", - "Promise<any>?", - ] + allBut(unions, ["(long or Callback)"]) - sequences = ["sequence<long>", "sequence<short>"] - nonUserObjects = nonObjects + interfaces + sequences - otherObjects = allBut(argTypes, nonUserObjects + ["object"]) - notRelatedInterfaces = ( - nonObjects - + ["UnrelatedInterface"] - + otherObjects - + sequences - + bufferSourceTypes - ) - records = [ - "record<DOMString, object>", - "record<USVString, Dict>", - "record<ByteString, long>", - "record<UTF8String, long>", - ] # JSString not supported in records - dictionaryLike = ( - [ - "Dict", - "Dict2", - "CallbackInterface", - "CallbackInterface?", - "CallbackInterface2", - ] - + records - + allBut(unions, ["(long or Callback)"]) - ) - - # Build a representation of the distinguishability table as a dict - # of dicts, holding True values where needed, holes elsewhere. - data = dict() - for type in argTypes: - data[type] = dict() - - def setDistinguishable(type, types): - for other in types: - data[type][other] = True - - setDistinguishable("long", nonNumerics) - setDistinguishable("short", nonNumerics) - setDistinguishable("long?", allBut(nonNumerics, nullables)) - setDistinguishable("short?", allBut(nonNumerics, nullables)) - setDistinguishable("boolean", nonBooleans) - setDistinguishable("boolean?", allBut(nonBooleans, nullables)) - setDistinguishable("undefined", allBut(argTypes, undefineds + dictionaryLike)) - setDistinguishable( - "undefined?", allBut(argTypes, undefineds + dictionaryLike + nullables) - ) - setDistinguishable("DOMString", nonStrings) - setDistinguishable("ByteString", nonStrings) - setDistinguishable("UTF8String", nonStrings) - setDistinguishable("USVString", nonStrings) - setDistinguishable("JSString", nonStrings) - setDistinguishable("Enum", nonStrings) - setDistinguishable("Enum2", nonStrings) - setDistinguishable("Interface", notRelatedInterfaces) - setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables)) - setDistinguishable("AncestorInterface", notRelatedInterfaces) - setDistinguishable( - "UnrelatedInterface", allBut(argTypes, ["object", "UnrelatedInterface"]) - ) - setDistinguishable("CallbackInterface", allBut(nonUserObjects, undefineds)) - setDistinguishable( - "CallbackInterface?", allBut(nonUserObjects, nullables + undefineds) - ) - setDistinguishable("CallbackInterface2", allBut(nonUserObjects, undefineds)) - setDistinguishable("object", nonObjects) - setDistinguishable("Callback", nonUserObjects) - setDistinguishable("Callback2", nonUserObjects) - setDistinguishable("Dict", allBut(nonUserObjects, nullables + undefineds)) - setDistinguishable("Dict2", allBut(nonUserObjects, nullables + undefineds)) - setDistinguishable("sequence<long>", allBut(argTypes, sequences + ["object"])) - setDistinguishable("sequence<short>", allBut(argTypes, sequences + ["object"])) - setDistinguishable("record<DOMString, object>", allBut(nonUserObjects, undefineds)) - setDistinguishable("record<USVString, Dict>", allBut(nonUserObjects, undefineds)) - # JSString not supported in records - setDistinguishable("record<ByteString, long>", allBut(nonUserObjects, undefineds)) - setDistinguishable("record<UTF8String, long>", allBut(nonUserObjects, undefineds)) - setDistinguishable("any", []) - setDistinguishable("Promise<any>", []) - setDistinguishable("Promise<any>?", []) - setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"])) - setDistinguishable( - "ArrayBufferView", - allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]), - ) - setDistinguishable( - "Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]) - ) - setDistinguishable( - "Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]) - ) - setDistinguishable("(long or Callback)", allBut(nonUserObjects, numerics)) - setDistinguishable( - "(long or Dict)", allBut(nonUserObjects, numerics + nullables + undefineds) - ) - - def areDistinguishable(type1, type2): - return data[type1].get(type2, False) - - def checkDistinguishability(parser, type1, type2): - idlTemplate = """ - enum Enum { "a", "b" }; - enum Enum2 { "c", "d" }; - interface Interface : AncestorInterface {}; - interface AncestorInterface {}; - interface UnrelatedInterface {}; - callback interface CallbackInterface {}; - callback interface CallbackInterface2 {}; - callback Callback = any(); - callback Callback2 = long(short arg); - // Give our dictionaries required members so we don't need to - // mess with optional and default values. - dictionary Dict { required long member; }; - dictionary Dict2 { required long member; }; - interface TestInterface {%s - }; - """ - if type1 in undefineds or type2 in undefineds: - methods = """ - (%s or %s) myMethod();""" % ( - type1, - type2, - ) - else: - methodTemplate = """ - undefined myMethod(%s arg);""" - methods = (methodTemplate % type1) + (methodTemplate % type2) - idl = idlTemplate % methods - - parser = parser.reset() - threw = False - try: - parser.parse(idl) - results = parser.finish() - except: - threw = True - - if areDistinguishable(type1, type2): - harness.ok( - not threw, - "Should not throw for '%s' and '%s' because they are distinguishable" - % (type1, type2), - ) - else: - harness.ok( - threw, - "Should throw for '%s' and '%s' because they are not distinguishable" - % (type1, type2), - ) - - # Enumerate over everything in both orders, since order matters in - # terms of our implementation of distinguishability checks - for type1 in argTypes: - for type2 in argTypes: - checkDistinguishability(parser, type1, type2) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_double_null.py b/components/script/dom/bindings/codegen/parser/tests/test_double_null.py deleted file mode 100644 index a8876a7fd2d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_double_null.py +++ /dev/null @@ -1,16 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface DoubleNull { - attribute byte?? foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py b/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py deleted file mode 100644 index 89a4e1acf0b..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_duplicate_qualifiers.py +++ /dev/null @@ -1,64 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface DuplicateQualifiers1 { - getter getter byte foo(unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface DuplicateQualifiers2 { - setter setter byte foo(unsigned long index, byte value); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface DuplicateQualifiers4 { - deleter deleter byte foo(unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface DuplicateQualifiers5 { - getter deleter getter byte foo(unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py b/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py deleted file mode 100644 index 09333a659cd..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_empty_enum.py +++ /dev/null @@ -1,17 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - try: - parser.parse( - """ - enum TestEmptyEnum { - }; - """ - ) - - harness.ok(False, "Should have thrown!") - except: - harness.ok(True, "Parsing TestEmptyEnum enum should fail") - - results = parser.finish() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py b/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py deleted file mode 100644 index 21837743523..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py +++ /dev/null @@ -1,54 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface X { - const sequence<long> foo = []; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Constant cannot have [] as a default value") - - parser = parser.reset() - - parser.parse( - """ - interface X { - undefined foo(optional sequence<long> arg = []); - }; - """ - ) - results = parser.finish() - - harness.ok( - isinstance( - results[0].members[0].signatures()[0][1][0].defaultValue, - WebIDL.IDLEmptySequenceValue, - ), - "Should have IDLEmptySequenceValue as default value of argument", - ) - - parser = parser.reset() - - parser.parse( - """ - dictionary X { - sequence<long> foo = []; - }; - """ - ) - results = parser.finish() - - harness.ok( - isinstance(results[0].members[0].defaultValue, WebIDL.IDLEmptySequenceValue), - "Should have IDLEmptySequenceValue as default value of " "dictionary member", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_enum.py b/components/script/dom/bindings/codegen/parser/tests/test_enum.py deleted file mode 100644 index 56c6b3f64aa..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_enum.py +++ /dev/null @@ -1,107 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - enum TestEnum { - "", - "foo", - "bar" - }; - - interface TestEnumInterface { - TestEnum doFoo(boolean arg); - readonly attribute TestEnum foo; - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestEnumInterfaces interface parsed without error.") - harness.check(len(results), 2, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLEnum), "Should be an IDLEnum") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") - - enum = results[0] - harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName") - harness.check(enum.identifier.name, "TestEnum", "Enum has the right name") - harness.check(enum.values(), ["", "foo", "bar"], "Enum has the right values") - - iface = results[1] - - harness.check( - iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName" - ) - harness.check( - iface.identifier.name, "TestEnumInterface", "Interface has the right name" - ) - harness.check(iface.parent, None, "Interface has no parent") - - members = iface.members - harness.check(len(members), 2, "Should be one production") - harness.ok(isinstance(members[0], WebIDL.IDLMethod), "Should be an IDLMethod") - method = members[0] - harness.check( - method.identifier.QName(), - "::TestEnumInterface::doFoo", - "Method has correct QName", - ) - harness.check(method.identifier.name, "doFoo", "Method has correct name") - - signatures = method.signatures() - harness.check(len(signatures), 1, "Expect one signature") - - (returnType, arguments) = signatures[0] - harness.check( - str(returnType), "TestEnum (Wrapper)", "Method type is the correct name" - ) - harness.check(len(arguments), 1, "Method has the right number of arguments") - arg = arguments[0] - harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument") - harness.check(str(arg.type), "Boolean", "Argument has the right type") - - attr = members[1] - harness.check( - attr.identifier.QName(), "::TestEnumInterface::foo", "Attr has correct QName" - ) - harness.check(attr.identifier.name, "foo", "Attr has correct name") - - harness.check(str(attr.type), "TestEnum (Wrapper)", "Attr type is the correct name") - - # Now reset our parser - parser = parser.reset() - threw = False - try: - parser.parse( - """ - enum Enum { - "a", - "b", - "c" - }; - interface TestInterface { - undefined foo(optional Enum e = "d"); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow a bogus default value for an enum") - - # Now reset our parser - parser = parser.reset() - parser.parse( - """ - enum Enum { - "a", - "b", - "c", - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should allow trailing comma in enum") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py b/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py deleted file mode 100644 index 8969281e1c7..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_enum_duplicate_values.py +++ /dev/null @@ -1,16 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - try: - parser.parse( - """ - enum TestEnumDuplicateValue { - "", - "" - }; - """ - ) - harness.ok(False, "Should have thrown!") - except: - harness.ok(True, "Enum TestEnumDuplicateValue should throw") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py b/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py deleted file mode 100644 index 1c9bb065580..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_error_colno.py +++ /dev/null @@ -1,24 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - # Check that error messages put the '^' in the right place. - - threw = False - input = "interface ?" - try: - parser.parse(input) - results = parser.finish() - except WebIDL.WebIDLError as e: - threw = True - lines = str(e).split("\n") - - harness.check(len(lines), 3, "Expected number of lines in error message") - harness.check(lines[1], input, "Second line shows error") - harness.check( - lines[2], - " " * (len(input) - 1) + "^", - "Correct column pointer in error message", - ) - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py b/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py deleted file mode 100644 index 0d10e006787..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_error_lineno.py +++ /dev/null @@ -1,38 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - # Check that error messages put the '^' in the right place. - - threw = False - input = """\ -// This is a comment. -interface Foo { -}; - -/* This is also a comment. */ -interface ?""" - try: - parser.parse(input) - results = parser.finish() - except WebIDL.WebIDLError as e: - threw = True - lines = str(e).split("\n") - - harness.check(len(lines), 3, "Expected number of lines in error message") - harness.ok( - lines[0].endswith("line 6:10"), - 'First line of error should end with "line 6:10", but was "%s".' % lines[0], - ) - harness.check( - lines[1], - "interface ?", - "Second line of error message is the line which caused the error.", - ) - harness.check( - lines[2], - " " * (len("interface ?") - 1) + "^", - "Correct column pointer in error message.", - ) - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py b/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py deleted file mode 100644 index c5ea8e4b88b..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py +++ /dev/null @@ -1,383 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global=(Bar, Bar1,Bar2), Exposed=Bar] interface Bar {}; - [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; - - [Exposed=(Foo,Bar1)] - interface Iface { - undefined method1(); - - [Exposed=Bar1] - readonly attribute any attr; - }; - - [Exposed=Foo] - partial interface Iface { - undefined method2(); - }; - """ - ) - - results = parser.finish() - - harness.check(len(results), 5, "Should know about five things") - iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") - members = iface.members - harness.check(len(members), 3, "Should have three members") - - harness.ok( - members[0].exposureSet == set(["Foo", "Bar"]), - "method1 should have the right exposure set", - ) - harness.ok( - members[0]._exposureGlobalNames == set(["Foo", "Bar1"]), - "method1 should have the right exposure global names", - ) - - harness.ok( - members[1].exposureSet == set(["Bar"]), - "attr should have the right exposure set", - ) - harness.ok( - members[1]._exposureGlobalNames == set(["Bar1"]), - "attr should have the right exposure global names", - ) - - harness.ok( - members[2].exposureSet == set(["Foo"]), - "method2 should have the right exposure set", - ) - harness.ok( - members[2]._exposureGlobalNames == set(["Foo"]), - "method2 should have the right exposure global names", - ) - - harness.ok( - iface.exposureSet == set(["Foo", "Bar"]), - "Iface should have the right exposure set", - ) - harness.ok( - iface._exposureGlobalNames == set(["Foo", "Bar1"]), - "Iface should have the right exposure global names", - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global=(Bar, Bar1, Bar2), Exposed=Bar] interface Bar {}; - [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; - - [Exposed=Foo] - interface Iface2 { - undefined method3(); - }; - """ - ) - results = parser.finish() - - harness.check(len(results), 4, "Should know about four things") - iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") - members = iface.members - harness.check(len(members), 1, "Should have one member") - - harness.ok( - members[0].exposureSet == set(["Foo"]), - "method3 should have the right exposure set", - ) - harness.ok( - members[0]._exposureGlobalNames == set(["Foo"]), - "method3 should have the right exposure global names", - ) - - harness.ok( - iface.exposureSet == set(["Foo"]), "Iface2 should have the right exposure set" - ) - harness.ok( - iface._exposureGlobalNames == set(["Foo"]), - "Iface2 should have the right exposure global names", - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global=(Bar, Bar1, Bar2), Exposed=Bar] interface Bar {}; - [Global=(Baz, Baz2), Exposed=Baz] interface Baz {}; - - [Exposed=Foo] - interface Iface3 { - undefined method4(); - }; - - [Exposed=(Foo,Bar1)] - interface mixin Mixin { - undefined method5(); - }; - - Iface3 includes Mixin; - """ - ) - results = parser.finish() - harness.check(len(results), 6, "Should know about six things") - iface = results[3] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") - members = iface.members - harness.check(len(members), 2, "Should have two members") - - harness.ok( - members[0].exposureSet == set(["Foo"]), - "method4 should have the right exposure set", - ) - harness.ok( - members[0]._exposureGlobalNames == set(["Foo"]), - "method4 should have the right exposure global names", - ) - - harness.ok( - members[1].exposureSet == set(["Foo", "Bar"]), - "method5 should have the right exposure set", - ) - harness.ok( - members[1]._exposureGlobalNames == set(["Foo", "Bar1"]), - "method5 should have the right exposure global names", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Exposed=Foo] - interface Bar { - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Should have thrown on invalid Exposed value on interface.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Bar { - [Exposed=Foo] - readonly attribute bool attr; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Should have thrown on invalid Exposed value on attribute.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Bar { - [Exposed=Foo] - undefined operation(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Should have thrown on invalid Exposed value on operation.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Bar { - [Exposed=Foo] - const long constant = 5; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Should have thrown on invalid Exposed value on constant.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global, Exposed=Bar] interface Bar {}; - - [Exposed=Foo] - interface Baz { - [Exposed=Bar] - undefined method(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok( - threw, "Should have thrown on member exposed where its interface is not." - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global, Exposed=Bar] interface Bar {}; - - [Exposed=Foo] - interface Baz { - undefined method(); - }; - - [Exposed=Bar] - interface mixin Mixin { - undefined otherMethod(); - }; - - Baz includes Mixin; - """ - ) - - results = parser.finish() - - harness.check(len(results), 5, "Should know about five things") - iface = results[2] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") - members = iface.members - harness.check(len(members), 2, "Should have two members") - - harness.ok( - members[0].exposureSet == set(["Foo"]), - "method should have the right exposure set", - ) - harness.ok( - members[0]._exposureGlobalNames == set(["Foo"]), - "method should have the right exposure global names", - ) - - harness.ok( - members[1].exposureSet == set(["Bar"]), - "otherMethod should have the right exposure set", - ) - harness.ok( - members[1]._exposureGlobalNames == set(["Bar"]), - "otherMethod should have the right exposure global names", - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global, Exposed=Bar] interface Bar {}; - - [Exposed=*] - interface Baz { - undefined methodWild(); - }; - - [Exposed=Bar] - interface mixin Mixin { - undefined methodNotWild(); - }; - - Baz includes Mixin; - """ - ) - - results = parser.finish() - - harness.check(len(results), 5, "Should know about five things") - iface = results[2] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should have an interface here") - members = iface.members - harness.check(len(members), 2, "Should have two members") - - harness.ok( - members[0].exposureSet == set(["Foo", "Bar"]), - "methodWild should have the right exposure set", - ) - harness.ok( - members[0]._exposureGlobalNames == set(["Foo", "Bar"]), - "methodWild should have the right exposure global names", - ) - - harness.ok( - members[1].exposureSet == set(["Bar"]), - "methodNotWild should have the right exposure set", - ) - harness.ok( - members[1]._exposureGlobalNames == set(["Bar"]), - "methodNotWild should have the right exposure global names", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global, Exposed=Bar] interface Bar {}; - - [Exposed=Foo] - interface Baz { - [Exposed=*] - undefined method(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok( - threw, "Should have thrown on member exposed where its interface is not." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] interface Foo {}; - [Global, Exposed=Bar] interface Bar {}; - - [Exposed=(Foo,*)] - interface Baz { - undefined method(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - - harness.ok(threw, "Should have thrown on a wildcard in an identifier list.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py b/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py deleted file mode 100644 index 423a67540c7..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_extended_attributes.py +++ /dev/null @@ -1,131 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - [LegacyNoInterfaceObject] - interface TestExtendedAttr { - [LegacyUnforgeable] readonly attribute byte b; - }; - """ - ) - - results = parser.finish() - - parser = parser.reset() - parser.parse( - """ - [Pref="foo.bar",Pref=flop] - interface TestExtendedAttr { - [Pref="foo.bar"] attribute byte b; - }; - """ - ) - - results = parser.finish() - - parser = parser.reset() - parser.parse( - """ - interface TestLegacyLenientThis { - [LegacyLenientThis] attribute byte b; - }; - """ - ) - - results = parser.finish() - harness.ok( - results[0].members[0].hasLegacyLenientThis(), "Should have a lenient this" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestLegacyLenientThis2 { - [LegacyLenientThis=something] attribute byte b; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "[LegacyLenientThis] must take no arguments") - - parser = parser.reset() - parser.parse( - """ - interface TestClamp { - undefined testClamp([Clamp] long foo); - undefined testNotClamp(long foo); - }; - """ - ) - - results = parser.finish() - # Pull out the first argument out of the arglist of the first (and - # only) signature. - harness.ok( - results[0].members[0].signatures()[0][1][0].type.hasClamp(), "Should be clamped" - ) - harness.ok( - not results[0].members[1].signatures()[0][1][0].type.hasClamp(), - "Should not be clamped", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestClamp2 { - undefined testClamp([Clamp=something] long foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "[Clamp] must take no arguments") - - parser = parser.reset() - parser.parse( - """ - interface TestEnforceRange { - undefined testEnforceRange([EnforceRange] long foo); - undefined testNotEnforceRange(long foo); - }; - """ - ) - - results = parser.finish() - # Pull out the first argument out of the arglist of the first (and - # only) signature. - harness.ok( - results[0].members[0].signatures()[0][1][0].type.hasEnforceRange(), - "Should be enforceRange", - ) - harness.ok( - not results[0].members[1].signatures()[0][1][0].type.hasEnforceRange(), - "Should not be enforceRange", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestEnforceRange2 { - undefined testEnforceRange([EnforceRange=something] long foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "[EnforceRange] must take no arguments") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_float_types.py b/components/script/dom/bindings/codegen/parser/tests/test_float_types.py deleted file mode 100644 index d37443819d8..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_float_types.py +++ /dev/null @@ -1,145 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - typedef float myFloat; - typedef unrestricted float myUnrestrictedFloat; - interface FloatTypes { - attribute float f; - attribute unrestricted float uf; - attribute double d; - attribute unrestricted double ud; - [LenientFloat] - attribute float lf; - [LenientFloat] - attribute double ld; - - undefined m1(float arg1, double arg2, float? arg3, double? arg4, - myFloat arg5, unrestricted float arg6, - unrestricted double arg7, unrestricted float? arg8, - unrestricted double? arg9, myUnrestrictedFloat arg10); - [LenientFloat] - undefined m2(float arg1, double arg2, float? arg3, double? arg4, - myFloat arg5, unrestricted float arg6, - unrestricted double arg7, unrestricted float? arg8, - unrestricted double? arg9, myUnrestrictedFloat arg10); - [LenientFloat] - undefined m3(float arg); - [LenientFloat] - undefined m4(double arg); - [LenientFloat] - undefined m5((float or FloatTypes) arg); - [LenientFloat] - undefined m6(sequence<float> arg); - }; - """ - ) - - results = parser.finish() - - harness.check(len(results), 3, "Should be two typedefs and one interface.") - iface = results[2] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - types = [a.type for a in iface.members if a.isAttr()] - harness.ok(types[0].isFloat(), "'float' is a float") - harness.ok(not types[0].isUnrestricted(), "'float' is not unrestricted") - harness.ok(types[1].isFloat(), "'unrestricted float' is a float") - harness.ok(types[1].isUnrestricted(), "'unrestricted float' is unrestricted") - harness.ok(types[2].isFloat(), "'double' is a float") - harness.ok(not types[2].isUnrestricted(), "'double' is not unrestricted") - harness.ok(types[3].isFloat(), "'unrestricted double' is a float") - harness.ok(types[3].isUnrestricted(), "'unrestricted double' is unrestricted") - - method = iface.members[6] - harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") - argtypes = [a.type for a in method.signatures()[0][1]] - for (idx, type) in enumerate(argtypes): - harness.ok(type.isFloat(), "Type %d should be float" % idx) - harness.check( - type.isUnrestricted(), - idx >= 5, - "Type %d should %sbe unrestricted" % (idx, "" if idx >= 4 else "not "), - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface FloatTypes { - [LenientFloat] - long m(float arg); - }; - """ - ) - except Exception as x: - threw = True - harness.ok(threw, "[LenientFloat] only allowed on methods returning undefined") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface FloatTypes { - [LenientFloat] - undefined m(unrestricted float arg); - }; - """ - ) - except Exception as x: - threw = True - harness.ok( - threw, "[LenientFloat] only allowed on methods with unrestricted float args" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface FloatTypes { - [LenientFloat] - undefined m(sequence<unrestricted float> arg); - }; - """ - ) - except Exception as x: - threw = True - harness.ok( - threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface FloatTypes { - [LenientFloat] - undefined m((unrestricted float or FloatTypes) arg); - }; - """ - ) - except Exception as x: - threw = True - harness.ok( - threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface FloatTypes { - [LenientFloat] - readonly attribute float foo; - }; - """ - ) - except Exception as x: - threw = True - harness.ok(threw, "[LenientFloat] only allowed on writable attributes") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py b/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py deleted file mode 100644 index 1c81718400a..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_forward_decl.py +++ /dev/null @@ -1,18 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface ForwardDeclared; - interface ForwardDeclared; - - interface TestForwardDecl { - attribute ForwardDeclared foo; - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestForwardDeclared interface parsed without error.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py deleted file mode 100644 index 9ee27efbc8d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py +++ /dev/null @@ -1,129 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - [Global, Exposed=Foo] - interface Foo : Bar { - getter any(DOMString name); - }; - [Exposed=Foo] - interface Bar {}; - """ - ) - - results = parser.finish() - - harness.ok( - results[0].isOnGlobalProtoChain(), - "[Global] interface should be on global's proto chain", - ) - harness.ok( - results[1].isOnGlobalProtoChain(), - "[Global] interface should be on global's proto chain", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] - interface Foo { - getter any(DOMString name); - setter undefined(DOMString name, any arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown for [Global] used on an interface with a " "named setter", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] - interface Foo { - getter any(DOMString name); - deleter undefined(DOMString name); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown for [Global] used on an interface with a " "named deleter", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, LegacyOverrideBuiltIns, Exposed=Foo] - interface Foo { - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown for [Global] used on an interface with a " - "[LegacyOverrideBuiltIns]", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] - interface Foo : Bar { - }; - [LegacyOverrideBuiltIns, Exposed=Foo] - interface Bar { - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown for [Global] used on an interface with an " - "[LegacyOverrideBuiltIns] ancestor", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Foo] - interface Foo { - }; - [Exposed=Foo] - interface Bar : Foo { - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown for [Global] used on an interface with a " "descendant", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py b/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py deleted file mode 100644 index 7404c86f944..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_identifier_conflict.py +++ /dev/null @@ -1,49 +0,0 @@ -# Import the WebIDL module, so we can do isinstance checks and whatnot -import WebIDL - - -def WebIDLTest(parser, harness): - try: - parser.parse( - """ - enum Foo { "a" }; - interface Foo; - """ - ) - results = parser.finish() - harness.ok(False, "Should fail to parse") - except Exception as e: - harness.ok( - "Name collision" in str(e), "Should have name collision for interface" - ) - - parser = parser.reset() - try: - parser.parse( - """ - dictionary Foo { long x; }; - enum Foo { "a" }; - """ - ) - results = parser.finish() - harness.ok(False, "Should fail to parse") - except Exception as e: - harness.ok( - "Name collision" in str(e), "Should have name collision for dictionary" - ) - - parser = parser.reset() - try: - parser.parse( - """ - enum Foo { "a" }; - enum Foo { "b" }; - """ - ) - results = parser.finish() - harness.ok(False, "Should fail to parse") - except Exception as e: - harness.ok( - "Multiple unresolvable definitions" in str(e), - "Should have name collision for dictionary", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py deleted file mode 100644 index ed476b8ed4c..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_parent.py +++ /dev/null @@ -1,21 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestIncompleteParent : NotYetDefined { - undefined foo(); - }; - - interface NotYetDefined : EvenHigherOnTheChain { - }; - - interface EvenHigherOnTheChain { - }; - """ - ) - - parser.finish() - - harness.ok(True, "TestIncompleteParent interface parsed without error.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py b/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py deleted file mode 100644 index 0d54f708bba..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_incomplete_types.py +++ /dev/null @@ -1,61 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestIncompleteTypes { - attribute FooInterface attr1; - - FooInterface method1(FooInterface arg); - }; - - interface FooInterface { - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestIncompleteTypes interface parsed without error.") - harness.check(len(results), 2, "Should be two productions.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), - "::TestIncompleteTypes", - "Interface has the right QName", - ) - harness.check( - iface.identifier.name, "TestIncompleteTypes", "Interface has the right name" - ) - harness.check(len(iface.members), 2, "Expect 2 members") - - attr = iface.members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - method = iface.members[1] - harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") - - harness.check( - attr.identifier.QName(), - "::TestIncompleteTypes::attr1", - "Attribute has the right QName", - ) - harness.check( - attr.type.name, "FooInterface", "Previously unresolved type has the right name" - ) - - harness.check( - method.identifier.QName(), - "::TestIncompleteTypes::method1", - "Attribute has the right QName", - ) - (returnType, args) = method.signatures()[0] - harness.check( - returnType.name, "FooInterface", "Previously unresolved type has the right name" - ) - harness.check( - args[0].type.name, - "FooInterface", - "Previously unresolved type has the right name", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_interface.py deleted file mode 100644 index 85748848e1b..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface.py +++ /dev/null @@ -1,459 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse("interface Foo { };") - results = parser.finish() - harness.ok(True, "Empty interface parsed without error.") - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - iface = results[0] - harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName") - harness.check(iface.identifier.name, "Foo", "Interface has the right name") - harness.check(iface.parent, None, "Interface has no parent") - - parser.parse("interface Bar : Foo { };") - results = parser.finish() - harness.ok(True, "Empty interface parsed without error.") - harness.check(len(results), 2, "Should be two productions") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") - iface = results[1] - harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName") - harness.check(iface.identifier.name, "Bar", "Interface has the right name") - harness.ok(isinstance(iface.parent, WebIDL.IDLInterface), "Interface has a parent") - - parser = parser.reset() - parser.parse( - """ - interface QNameBase { - attribute long foo; - }; - - interface QNameDerived : QNameBase { - attribute long long foo; - attribute byte bar; - }; - """ - ) - results = parser.finish() - harness.check(len(results), 2, "Should be two productions") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check(results[1].parent, results[0], "Inheritance chain is right") - harness.check(len(results[0].members), 1, "Expect 1 productions") - harness.check(len(results[1].members), 2, "Expect 2 productions") - base = results[0] - derived = results[1] - harness.check( - base.members[0].identifier.QName(), - "::QNameBase::foo", - "Member has the right QName", - ) - harness.check( - derived.members[0].identifier.QName(), - "::QNameDerived::foo", - "Member has the right QName", - ) - harness.check( - derived.members[1].identifier.QName(), - "::QNameDerived::bar", - "Member has the right QName", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A : B {}; - interface B : A {}; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow cycles in interface inheritance chains") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A : C {}; - interface C : B {}; - interface B : A {}; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, "Should not allow indirect cycles in interface inheritance chains" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A; - interface B : A {}; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should not allow inheriting from an interface that is only forward declared", - ) - - parser = parser.reset() - parser.parse( - """ - interface A { - constructor(); - constructor(long arg); - readonly attribute boolean x; - undefined foo(); - }; - partial interface A { - readonly attribute boolean y; - undefined foo(long arg); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 2, "Should have two results with partial interface") - iface = results[0] - harness.check( - len(iface.members), 3, "Should have three members with partial interface" - ) - harness.check( - iface.members[0].identifier.name, - "x", - "First member should be x with partial interface", - ) - harness.check( - iface.members[1].identifier.name, - "foo", - "Second member should be foo with partial interface", - ) - harness.check( - len(iface.members[1].signatures()), - 2, - "Should have two foo signatures with partial interface", - ) - harness.check( - iface.members[2].identifier.name, - "y", - "Third member should be y with partial interface", - ) - harness.check( - len(iface.ctor().signatures()), - 2, - "Should have two constructors with partial interface", - ) - - parser = parser.reset() - parser.parse( - """ - partial interface A { - readonly attribute boolean y; - undefined foo(long arg); - }; - interface A { - constructor(); - constructor(long arg); - readonly attribute boolean x; - undefined foo(); - }; - """ - ) - results = parser.finish() - harness.check( - len(results), 2, "Should have two results with reversed partial interface" - ) - iface = results[1] - harness.check( - len(iface.members), - 3, - "Should have three members with reversed partial interface", - ) - harness.check( - iface.members[0].identifier.name, - "x", - "First member should be x with reversed partial interface", - ) - harness.check( - iface.members[1].identifier.name, - "foo", - "Second member should be foo with reversed partial interface", - ) - harness.check( - len(iface.members[1].signatures()), - 2, - "Should have two foo signatures with reversed partial interface", - ) - harness.check( - iface.members[2].identifier.name, - "y", - "Third member should be y with reversed partial interface", - ) - harness.check( - len(iface.ctor().signatures()), - 2, - "Should have two constructors with reversed partial interface", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - readonly attribute boolean x; - }; - interface A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow two non-partial interfaces with the same name") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - partial interface A { - readonly attribute boolean x; - }; - partial interface A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Must have a non-partial interface for a given name") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - boolean x; - }; - partial interface A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between partial interface " - "and other object", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - boolean x; - }; - interface A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow a name collision between interface " "and other object" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - boolean x; - }; - interface A; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between external interface " - "and other object", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - readonly attribute boolean x; - }; - interface A; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between external interface " "and interface", - ) - - parser = parser.reset() - parser.parse( - """ - interface A; - interface A; - """ - ) - results = parser.finish() - harness.ok( - len(results) == 1 and isinstance(results[0], WebIDL.IDLExternalInterface), - "Should allow name collisions between external interface " "declarations", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SomeRandomAnnotation] - interface A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow unknown extended attributes on interfaces") - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Exposed=Window, LegacyWindowAlias=A] - interface B {}; - [Exposed=Window, LegacyWindowAlias=(C, D)] - interface E {}; - """ - ) - results = parser.finish() - harness.check( - results[1].legacyWindowAliases, ["A"], "Should support a single identifier" - ) - harness.check( - results[2].legacyWindowAliases, ["C", "D"], "Should support an identifier list" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyWindowAlias] - interface A {}; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow [LegacyWindowAlias] with no value") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Exposed=Worker, LegacyWindowAlias=B] - interface A {}; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow [LegacyWindowAlias] without Window exposure") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Exposed=Window] - interface A {}; - [Exposed=Window, LegacyWindowAlias=A] - interface B {}; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Exposed=Window, LegacyWindowAlias=A] - interface B {}; - [Exposed=Window] - interface A {}; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Exposed=Window, LegacyWindowAlias=A] - interface B {}; - [Exposed=Window, LegacyWindowAlias=A] - interface C {}; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers" - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py deleted file mode 100644 index 5750f87a6fc..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_const_identifier_conflicts.py +++ /dev/null @@ -1,17 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface IdentifierConflict { - const byte thing1 = 1; - const unsigned long thing1 = 1; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py deleted file mode 100644 index c1a544ce718..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_identifier_conflicts_across_members.py +++ /dev/null @@ -1,68 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface IdentifierConflictAcrossMembers1 { - const byte thing1 = 1; - readonly attribute long thing1; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface IdentifierConflictAcrossMembers2 { - readonly attribute long thing1; - const byte thing1 = 1; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface IdentifierConflictAcrossMembers3 { - getter boolean thing1(DOMString name); - readonly attribute long thing1; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface IdentifierConflictAcrossMembers1 { - const byte thing1 = 1; - long thing1(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py deleted file mode 100644 index 18c6023dd3b..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py +++ /dev/null @@ -1,912 +0,0 @@ -import WebIDL -import traceback - - -def WebIDLTest(parser, harness): - def shouldPass(prefix, iface, expectedMembers, numProductions=1): - p = parser.reset() - p.parse(iface) - results = p.finish() - harness.check( - len(results), - numProductions, - "%s - Should have production count %d" % (prefix, numProductions), - ) - harness.ok( - isinstance(results[0], WebIDL.IDLInterface), - "%s - Should be an IDLInterface" % (prefix), - ) - # Make a copy, since we plan to modify it - expectedMembers = list(expectedMembers) - for m in results[0].members: - name = m.identifier.name - if (name, type(m)) in expectedMembers: - harness.ok(True, "%s - %s - Should be a %s" % (prefix, name, type(m))) - expectedMembers.remove((name, type(m))) - else: - harness.ok( - False, - "%s - %s - Unknown symbol of type %s" % (prefix, name, type(m)), - ) - # A bit of a hoop because we can't generate the error string if we pass - if len(expectedMembers) == 0: - harness.ok(True, "Found all the members") - else: - harness.ok( - False, - "Expected member not found: %s of type %s" - % (expectedMembers[0][0], expectedMembers[0][1]), - ) - return results - - def shouldFail(prefix, iface): - try: - p = parser.reset() - p.parse(iface) - p.finish() - harness.ok(False, prefix + " - Interface passed when should've failed") - except WebIDL.WebIDLError as e: - harness.ok(True, prefix + " - Interface failed as expected") - except Exception as e: - harness.ok( - False, - prefix - + " - Interface failed but not as a WebIDLError exception: %s" % e, - ) - - iterableMembers = [ - (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values", "forEach"] - ] - setROMembers = ( - [(x, WebIDL.IDLMethod) for x in ["has"]] - + [("__setlike", WebIDL.IDLMaplikeOrSetlike)] - + iterableMembers - ) - setROMembers.extend([("size", WebIDL.IDLAttribute)]) - setRWMembers = [ - (x, WebIDL.IDLMethod) for x in ["add", "clear", "delete"] - ] + setROMembers - setROChromeMembers = [ - (x, WebIDL.IDLMethod) for x in ["__add", "__clear", "__delete"] - ] + setROMembers - setRWChromeMembers = [ - (x, WebIDL.IDLMethod) for x in ["__add", "__clear", "__delete"] - ] + setRWMembers - mapROMembers = ( - [(x, WebIDL.IDLMethod) for x in ["get", "has"]] - + [("__maplike", WebIDL.IDLMaplikeOrSetlike)] - + iterableMembers - ) - mapROMembers.extend([("size", WebIDL.IDLAttribute)]) - mapRWMembers = [ - (x, WebIDL.IDLMethod) for x in ["set", "clear", "delete"] - ] + mapROMembers - mapRWChromeMembers = [ - (x, WebIDL.IDLMethod) for x in ["__set", "__clear", "__delete"] - ] + mapRWMembers - - # OK, now that we've used iterableMembers to set up the above, append - # __iterable to it for the iterable<> case. - iterableMembers.append(("__iterable", WebIDL.IDLIterable)) - - asyncIterableMembers = [ - (x, WebIDL.IDLMethod) for x in ["entries", "keys", "values"] - ] - asyncIterableMembers.append(("__iterable", WebIDL.IDLAsyncIterable)) - - valueIterableMembers = [("__iterable", WebIDL.IDLIterable)] - valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod)) - valueIterableMembers.append(("length", WebIDL.IDLAttribute)) - - valueAsyncIterableMembers = [("__iterable", WebIDL.IDLAsyncIterable)] - valueAsyncIterableMembers.append(("values", WebIDL.IDLMethod)) - - disallowedIterableNames = ["keys", "entries", "values"] - disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames - mapDisallowedMemberNames = ["get"] + disallowedMemberNames - disallowedNonMethodNames = ["clear", "delete"] - mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames - setDisallowedNonMethodNames = ["add"] + disallowedNonMethodNames - unrelatedMembers = [ - ("unrelatedAttribute", WebIDL.IDLAttribute), - ("unrelatedMethod", WebIDL.IDLMethod), - ] - - # - # Simple Usage Tests - # - - shouldPass( - "Iterable (key only)", - """ - interface Foo1 { - iterable<long>; - readonly attribute unsigned long length; - getter long(unsigned long index); - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - valueIterableMembers + unrelatedMembers, - ) - - shouldPass( - "Iterable (key only) inheriting from parent", - """ - interface Foo1 : Foo2 { - iterable<long>; - readonly attribute unsigned long length; - getter long(unsigned long index); - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - valueIterableMembers, - numProductions=2, - ) - - shouldPass( - "Iterable (key and value)", - """ - interface Foo1 { - iterable<long, long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - iterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2, - ) - - shouldPass( - "Iterable (key and value) inheriting from parent", - """ - interface Foo1 : Foo2 { - iterable<long, long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - iterableMembers, - # numProductions == 3 because of the generated iterator iface, - numProductions=3, - ) - - shouldPass( - "Async iterable (key only)", - """ - interface Foo1 { - async iterable<long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - valueAsyncIterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2, - ) - - shouldPass( - "Async iterable (key only) inheriting from parent", - """ - interface Foo1 : Foo2 { - async iterable<long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - valueAsyncIterableMembers, - # numProductions == 3 because of the generated iterator iface, - numProductions=3, - ) - - shouldPass( - "Async iterable with argument (key only)", - """ - interface Foo1 { - async iterable<long>(optional long foo); - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - valueAsyncIterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2, - ) - - shouldPass( - "Async iterable (key and value)", - """ - interface Foo1 { - async iterable<long, long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - asyncIterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2, - ) - - shouldPass( - "Async iterable (key and value) inheriting from parent", - """ - interface Foo1 : Foo2 { - async iterable<long, long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - asyncIterableMembers, - # numProductions == 3 because of the generated iterator iface, - numProductions=3, - ) - - shouldPass( - "Async iterable with argument (key and value)", - """ - interface Foo1 { - async iterable<long, long>(optional long foo); - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - asyncIterableMembers + unrelatedMembers, - # numProductions == 2 because of the generated iterator iface, - numProductions=2, - ) - - shouldPass( - "Maplike (readwrite)", - """ - interface Foo1 { - maplike<long, long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapRWMembers + unrelatedMembers, - ) - - shouldPass( - "Maplike (readwrite) inheriting from parent", - """ - interface Foo1 : Foo2 { - maplike<long, long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldPass( - "Maplike (readwrite)", - """ - interface Foo1 { - maplike<long, long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapRWMembers + unrelatedMembers, - ) - - shouldPass( - "Maplike (readwrite) inheriting from parent", - """ - interface Foo1 : Foo2 { - maplike<long, long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldPass( - "Maplike (readonly)", - """ - interface Foo1 { - readonly maplike<long, long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapROMembers + unrelatedMembers, - ) - - shouldPass( - "Maplike (readonly) inheriting from parent", - """ - interface Foo1 : Foo2 { - readonly maplike<long, long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - mapROMembers, - numProductions=2, - ) - - shouldPass( - "Setlike (readwrite)", - """ - interface Foo1 { - setlike<long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - setRWMembers + unrelatedMembers, - ) - - shouldPass( - "Setlike (readwrite) inheriting from parent", - """ - interface Foo1 : Foo2 { - setlike<long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - setRWMembers, - numProductions=2, - ) - - shouldPass( - "Setlike (readonly)", - """ - interface Foo1 { - readonly setlike<long>; - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - setROMembers + unrelatedMembers, - ) - - shouldPass( - "Setlike (readonly) inheriting from parent", - """ - interface Foo1 : Foo2 { - readonly setlike<long>; - }; - interface Foo2 { - attribute long unrelatedAttribute; - long unrelatedMethod(); - }; - """, - setROMembers, - numProductions=2, - ) - - shouldPass( - "Inheritance of maplike/setlike", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldFail( - "JS Implemented maplike interface", - """ - [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] - interface Foo1 { - constructor(); - setlike<long>; - }; - """, - ) - - shouldFail( - "JS Implemented maplike interface", - """ - [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"] - interface Foo1 { - constructor(); - maplike<long, long>; - }; - """, - ) - - # - # Multiple maplike/setlike tests - # - - shouldFail( - "Two maplike/setlikes on same interface", - """ - interface Foo1 { - setlike<long>; - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Two iterable/setlikes on same interface", - """ - interface Foo1 { - iterable<long>; - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Two iterables on same interface", - """ - interface Foo1 { - iterable<long>; - iterable<long, long>; - }; - """, - ) - - shouldFail( - "Two iterables on same interface", - """ - interface Foo1 { - iterable<long>; - async iterable<long>; - }; - """, - ) - - shouldFail( - "Two iterables on same interface", - """ - interface Foo1 { - async iterable<long>; - async iterable<long, long>; - }; - """, - ) - - shouldFail( - "Async iterable with non-optional arguments", - """ - interface Foo1 { - async iterable<long>(long foo); - }; - """, - ) - - shouldFail( - "Async iterable with non-optional arguments", - """ - interface Foo1 { - async iterable<long>(optional long foo, long bar); - }; - """, - ) - - shouldFail( - "Async iterable with non-optional arguments", - """ - interface Foo1 { - async iterable<long, long>(long foo); - }; - """, - ) - - shouldFail( - "Two maplike/setlikes in partials", - """ - interface Foo1 { - maplike<long, long>; - }; - partial interface Foo1 { - setlike<long>; - }; - """, - ) - - shouldFail( - "Conflicting maplike/setlikes across inheritance", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - setlike<long>; - }; - """, - ) - - shouldFail( - "Conflicting maplike/iterable across inheritance", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - iterable<long>; - }; - """, - ) - - shouldFail( - "Conflicting maplike/setlikes across multistep inheritance", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - setlike<long>; - }; - """, - ) - - # - # Member name collision tests - # - - def testConflictingMembers(likeMember, conflictName, expectedMembers, methodPasses): - """ - Tests for maplike/setlike member generation against conflicting member - names. If methodPasses is True, this means we expect the interface to - pass in the case of method shadowing, and expectedMembers should be the - list of interface members to check against on the passing interface. - - """ - if methodPasses: - shouldPass( - "Conflicting method: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s; - [Throws] - undefined %s(long test1, double test2, double test3); - }; - """ - % (likeMember, conflictName), - expectedMembers, - ) - else: - shouldFail( - "Conflicting method: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s; - [Throws] - undefined %s(long test1, double test2, double test3); - }; - """ - % (likeMember, conflictName), - ) - # Inherited conflicting methods should ALWAYS fail - shouldFail( - "Conflicting inherited method: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - undefined %s(long test1, double test2, double test3); - }; - interface Foo2 : Foo1 { - %s; - }; - """ - % (conflictName, likeMember), - ) - shouldFail( - "Conflicting static method: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s; - static undefined %s(long test1, double test2, double test3); - }; - """ - % (likeMember, conflictName), - ) - shouldFail( - "Conflicting attribute: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s - attribute double %s; - }; - """ - % (likeMember, conflictName), - ) - shouldFail( - "Conflicting const: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s; - const double %s = 0; - }; - """ - % (likeMember, conflictName), - ) - shouldFail( - "Conflicting static attribute: %s and %s" % (likeMember, conflictName), - """ - interface Foo1 { - %s; - static attribute long %s; - }; - """ - % (likeMember, conflictName), - ) - - for member in disallowedIterableNames: - testConflictingMembers("iterable<long, long>", member, iterableMembers, False) - for member in mapDisallowedMemberNames: - testConflictingMembers("maplike<long, long>", member, mapRWMembers, False) - for member in disallowedMemberNames: - testConflictingMembers("setlike<long>", member, setRWMembers, False) - for member in mapDisallowedNonMethodNames: - testConflictingMembers("maplike<long, long>", member, mapRWMembers, True) - for member in setDisallowedNonMethodNames: - testConflictingMembers("setlike<long>", member, setRWMembers, True) - - shouldPass( - "Inheritance of maplike/setlike with child member collision", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - undefined entries(); - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldPass( - "Inheritance of multi-level maplike/setlike with child member collision", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - undefined entries(); - }; - """, - mapRWMembers, - numProductions=3, - ) - - shouldFail( - "Maplike interface with mixin member collision", - """ - interface Foo1 { - maplike<long, long>; - }; - interface mixin Foo2 { - undefined entries(); - }; - Foo1 includes Foo2; - """, - ) - - shouldPass( - "Inherited Maplike interface with consequential interface member collision", - """ - interface Foo1 { - maplike<long, long>; - }; - interface mixin Foo2 { - undefined entries(); - }; - interface Foo3 : Foo1 { - }; - Foo3 includes Foo2; - """, - mapRWMembers, - numProductions=4, - ) - - shouldFail( - "Inheritance of name collision with child maplike/setlike", - """ - interface Foo1 { - undefined entries(); - }; - interface Foo2 : Foo1 { - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Inheritance of multi-level name collision with child maplike/setlike", - """ - interface Foo1 { - undefined entries(); - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - maplike<long, long>; - }; - """, - ) - - shouldPass( - "Inheritance of attribute collision with parent maplike/setlike", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - attribute double size; - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldPass( - "Inheritance of multi-level attribute collision with parent maplike/setlike", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - attribute double size; - }; - """, - mapRWMembers, - numProductions=3, - ) - - shouldFail( - "Inheritance of attribute collision with child maplike/setlike", - """ - interface Foo1 { - attribute double size; - }; - interface Foo2 : Foo1 { - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Inheritance of multi-level attribute collision with child maplike/setlike", - """ - interface Foo1 { - attribute double size; - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Inheritance of attribute/rw function collision with child maplike/setlike", - """ - interface Foo1 { - attribute double set; - }; - interface Foo2 : Foo1 { - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Inheritance of const/rw function collision with child maplike/setlike", - """ - interface Foo1 { - const double set = 0; - }; - interface Foo2 : Foo1 { - maplike<long, long>; - }; - """, - ) - - shouldPass( - "Inheritance of rw function with same name in child maplike/setlike", - """ - interface Foo1 { - maplike<long, long>; - }; - interface Foo2 : Foo1 { - undefined clear(); - }; - """, - mapRWMembers, - numProductions=2, - ) - - shouldFail( - "Inheritance of unforgeable attribute collision with child maplike/setlike", - """ - interface Foo1 { - [LegacyUnforgeable] - attribute double size; - }; - interface Foo2 : Foo1 { - maplike<long, long>; - }; - """, - ) - - shouldFail( - "Inheritance of multi-level unforgeable attribute collision with child maplike/setlike", - """ - interface Foo1 { - [LegacyUnforgeable] - attribute double size; - }; - interface Foo2 : Foo1 { - }; - interface Foo3 : Foo2 { - maplike<long, long>; - }; - """, - ) - - shouldPass( - "Interface with readonly allowable overrides", - """ - interface Foo1 { - readonly setlike<long>; - readonly attribute boolean clear; - }; - """, - setROMembers + [("clear", WebIDL.IDLAttribute)], - ) - - r = shouldPass( - "Check proper override of clear/delete/set", - """ - interface Foo1 { - maplike<long, long>; - long clear(long a, long b, double c, double d); - long set(long a, long b, double c, double d); - long delete(long a, long b, double c, double d); - }; - """, - mapRWMembers, - ) - - for m in r[0].members: - if m.identifier.name in ["clear", "set", "delete"]: - harness.ok(m.isMethod(), "%s should be a method" % m.identifier.name) - harness.check( - m.maxArgCount, 4, "%s should have 4 arguments" % m.identifier.name - ) - harness.ok( - not m.isMaplikeOrSetlikeOrIterableMethod(), - "%s should not be a maplike/setlike function" % m.identifier.name, - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py b/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py deleted file mode 100644 index b3c8573fa59..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_interfacemixin.py +++ /dev/null @@ -1,534 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse("interface mixin Foo { };") - results = parser.finish() - harness.ok(True, "Empty interface mixin parsed without error.") - harness.check(len(results), 1, "Should be one production") - harness.ok( - isinstance(results[0], WebIDL.IDLInterfaceMixin), - "Should be an IDLInterfaceMixin", - ) - mixin = results[0] - harness.check( - mixin.identifier.QName(), "::Foo", "Interface mixin has the right QName" - ) - harness.check(mixin.identifier.name, "Foo", "Interface mixin has the right name") - - parser = parser.reset() - parser.parse( - """ - interface mixin QNameBase { - const long foo = 3; - }; - """ - ) - results = parser.finish() - harness.check(len(results), 1, "Should be one productions") - harness.ok( - isinstance(results[0], WebIDL.IDLInterfaceMixin), - "Should be an IDLInterfaceMixin", - ) - harness.check(len(results[0].members), 1, "Expect 1 productions") - mixin = results[0] - harness.check( - mixin.members[0].identifier.QName(), - "::QNameBase::foo", - "Member has the right QName", - ) - - parser = parser.reset() - parser.parse( - """ - interface mixin A { - readonly attribute boolean x; - undefined foo(); - }; - partial interface mixin A { - readonly attribute boolean y; - undefined foo(long arg); - }; - """ - ) - results = parser.finish() - harness.check( - len(results), 2, "Should have two results with partial interface mixin" - ) - mixin = results[0] - harness.check( - len(mixin.members), 3, "Should have three members with partial interface mixin" - ) - harness.check( - mixin.members[0].identifier.name, - "x", - "First member should be x with partial interface mixin", - ) - harness.check( - mixin.members[1].identifier.name, - "foo", - "Second member should be foo with partial interface mixin", - ) - harness.check( - len(mixin.members[1].signatures()), - 2, - "Should have two foo signatures with partial interface mixin", - ) - harness.check( - mixin.members[2].identifier.name, - "y", - "Third member should be y with partial interface mixin", - ) - - parser = parser.reset() - parser.parse( - """ - partial interface mixin A { - readonly attribute boolean y; - undefined foo(long arg); - }; - interface mixin A { - readonly attribute boolean x; - undefined foo(); - }; - """ - ) - results = parser.finish() - harness.check( - len(results), 2, "Should have two results with reversed partial interface mixin" - ) - mixin = results[1] - harness.check( - len(mixin.members), - 3, - "Should have three members with reversed partial interface mixin", - ) - harness.check( - mixin.members[0].identifier.name, - "x", - "First member should be x with reversed partial interface mixin", - ) - harness.check( - mixin.members[1].identifier.name, - "foo", - "Second member should be foo with reversed partial interface mixin", - ) - harness.check( - len(mixin.members[1].signatures()), - 2, - "Should have two foo signatures with reversed partial interface mixin", - ) - harness.check( - mixin.members[2].identifier.name, - "y", - "Third member should be y with reversed partial interface mixin", - ) - - parser = parser.reset() - parser.parse( - """ - interface Interface {}; - interface mixin Mixin { - attribute short x; - }; - Interface includes Mixin; - """ - ) - results = parser.finish() - iface = results[0] - harness.check(len(iface.members), 1, "Should merge members from mixins") - harness.check( - iface.members[0].identifier.name, "x", "Should merge members from mixins" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - readonly attribute boolean x; - }; - interface mixin A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow two non-partial interface mixins with the same name" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - partial interface mixin A { - readonly attribute boolean x; - }; - partial interface mixin A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Must have a non-partial interface mixin for a given name") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - boolean x; - }; - partial interface mixin A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between partial interface " - "mixin and other object", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary A { - boolean x; - }; - interface mixin A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between interface mixin " "and other object", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - readonly attribute boolean x; - }; - interface A; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a name collision between external interface " - "and interface mixin", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SomeRandomAnnotation] - interface mixin A { - readonly attribute boolean y; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow unknown extended attributes on interface mixins" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - getter double (DOMString propertyName); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow getters on interface mixins") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - setter undefined (DOMString propertyName, double propertyValue); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow setters on interface mixins") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - deleter undefined (DOMString propertyName); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow deleters on interface mixins") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - legacycaller double compute(double x); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow legacycallers on interface mixins") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin A { - inherit attribute x; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow inherited attribute on interface mixins") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Interface {}; - interface NotMixin { - attribute short x; - }; - Interface includes NotMixin; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should fail if the right side does not point an interface mixin") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin NotInterface {}; - interface mixin Mixin { - attribute short x; - }; - NotInterface includes Mixin; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should fail if the left side does not point an interface") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin Mixin { - iterable<DOMString>; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should fail if an interface mixin includes iterable") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin Mixin { - setlike<DOMString>; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should fail if an interface mixin includes setlike") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface mixin Mixin { - maplike<DOMString, DOMString>; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should fail if an interface mixin includes maplike") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Interface { - attribute short attr; - }; - interface mixin Mixin { - attribute short attr; - }; - Interface includes Mixin; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should fail if the included mixin interface has duplicated member" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Interface {}; - interface mixin Mixin1 { - attribute short attr; - }; - interface mixin Mixin2 { - attribute short attr; - }; - Interface includes Mixin1; - Interface includes Mixin2; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should fail if the included mixin interfaces have duplicated member" - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Global, Exposed=Worker] interface Worker {}; - [Exposed=Window] - interface Base {}; - interface mixin Mixin { - Base returnSelf(); - }; - Base includes Mixin; - """ - ) - results = parser.finish() - base = results[2] - attr = base.members[0] - harness.check( - attr.exposureSet, - set(["Window"]), - "Should expose on globals where the base interfaces are exposed", - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Global, Exposed=Worker] interface Worker {}; - [Exposed=Window] - interface Base {}; - [Exposed=Window] - interface mixin Mixin { - attribute short a; - }; - Base includes Mixin; - """ - ) - results = parser.finish() - base = results[2] - attr = base.members[0] - harness.check( - attr.exposureSet, set(["Window"]), "Should follow [Exposed] on interface mixin" - ) - - parser = parser.reset() - parser.parse( - """ - [Global, Exposed=Window] interface Window {}; - [Global, Exposed=Worker] interface Worker {}; - [Exposed=Window] - interface Base1 {}; - [Exposed=Worker] - interface Base2 {}; - interface mixin Mixin { - attribute short a; - }; - Base1 includes Mixin; - Base2 includes Mixin; - """ - ) - results = parser.finish() - base = results[2] - attr = base.members[0] - harness.check( - attr.exposureSet, - set(["Window", "Worker"]), - "Should expose on all globals where including interfaces are " "exposed", - ) - base = results[3] - attr = base.members[0] - harness.check( - attr.exposureSet, - set(["Window", "Worker"]), - "Should expose on all globals where including interfaces are " "exposed", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py b/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py deleted file mode 100644 index 9d2230c3bec..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_lenientSetter.py +++ /dev/null @@ -1,84 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -def should_throw(parser, harness, message, code): - parser = parser.reset() - threw = False - try: - parser.parse(code) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown: %s" % message) - - -def WebIDLTest(parser, harness): - # The [LegacyLenientSetter] extended attribute MUST take no arguments. - should_throw( - parser, - harness, - "no arguments", - """ - interface I { - [LegacyLenientSetter=X] readonly attribute long A; - }; - """, - ) - - # An attribute with the [LegacyLenientSetter] extended attribute MUST NOT - # also be declared with the [PutForwards] extended attribute. - should_throw( - parser, - harness, - "PutForwards", - """ - interface I { - [PutForwards=B, LegacyLenientSetter] readonly attribute J A; - }; - interface J { - attribute long B; - }; - """, - ) - - # An attribute with the [LegacyLenientSetter] extended attribute MUST NOT - # also be declared with the [Replaceable] extended attribute. - should_throw( - parser, - harness, - "Replaceable", - """ - interface I { - [Replaceable, LegacyLenientSetter] readonly attribute J A; - }; - """, - ) - - # The [LegacyLenientSetter] extended attribute MUST NOT be used on an - # attribute that is not read only. - should_throw( - parser, - harness, - "writable attribute", - """ - interface I { - [LegacyLenientSetter] attribute long A; - }; - """, - ) - - # The [LegacyLenientSetter] extended attribute MUST NOT be used on a - # static attribute. - should_throw( - parser, - harness, - "static attribute", - """ - interface I { - [LegacyLenientSetter] static readonly attribute long A; - }; - """, - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_method.py b/components/script/dom/bindings/codegen/parser/tests/test_method.py deleted file mode 100644 index 0ddfada28ac..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_method.py +++ /dev/null @@ -1,430 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestMethods { - undefined basic(); - static undefined basicStatic(); - undefined basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3); - boolean basicBoolean(); - static boolean basicStaticBoolean(); - boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3); - undefined optionalArg(optional byte? arg1, optional sequence<byte> arg2); - undefined variadicArg(byte?... arg1); - object getObject(); - undefined setObject(object arg1); - undefined setAny(any arg1); - float doFloats(float arg1); - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestMethods interface parsed without error.") - harness.check(len(results), 1, "Should be one production.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestMethods", "Interface has the right QName" - ) - harness.check(iface.identifier.name, "TestMethods", "Interface has the right name") - harness.check(len(iface.members), 12, "Expect 12 members") - - methods = iface.members - - def checkArgument(argument, QName, name, type, optional, variadic): - harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") - harness.check( - argument.identifier.QName(), QName, "Argument has the right QName" - ) - harness.check(argument.identifier.name, name, "Argument has the right name") - harness.check(str(argument.type), type, "Argument has the right return type") - harness.check( - argument.optional, optional, "Argument has the right optional value" - ) - harness.check( - argument.variadic, variadic, "Argument has the right variadic value" - ) - - def checkMethod( - method, - QName, - name, - signatures, - static=False, - getter=False, - setter=False, - deleter=False, - legacycaller=False, - stringifier=False, - ): - harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") - harness.ok(method.isMethod(), "Method is a method") - harness.ok(not method.isAttr(), "Method is not an attr") - harness.ok(not method.isConst(), "Method is not a const") - harness.check(method.identifier.QName(), QName, "Method has the right QName") - harness.check(method.identifier.name, name, "Method has the right name") - harness.check(method.isStatic(), static, "Method has the correct static value") - harness.check(method.isGetter(), getter, "Method has the correct getter value") - harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check( - method.isDeleter(), deleter, "Method has the correct deleter value" - ) - harness.check( - method.isLegacycaller(), - legacycaller, - "Method has the correct legacycaller value", - ) - harness.check( - method.isStringifier(), - stringifier, - "Method has the correct stringifier value", - ) - harness.check( - len(method.signatures()), - len(signatures), - "Method has the correct number of signatures", - ) - - sigpairs = zip(method.signatures(), signatures) - for (gotSignature, expectedSignature) in sigpairs: - (gotRetType, gotArgs) = gotSignature - (expectedRetType, expectedArgs) = expectedSignature - - harness.check( - str(gotRetType), expectedRetType, "Method has the expected return type." - ) - - for i in range(0, len(gotArgs)): - (QName, name, type, optional, variadic) = expectedArgs[i] - checkArgument(gotArgs[i], QName, name, type, optional, variadic) - - checkMethod(methods[0], "::TestMethods::basic", "basic", [("Undefined", [])]) - checkMethod( - methods[1], - "::TestMethods::basicStatic", - "basicStatic", - [("Undefined", [])], - static=True, - ) - checkMethod( - methods[2], - "::TestMethods::basicWithSimpleArgs", - "basicWithSimpleArgs", - [ - ( - "Undefined", - [ - ( - "::TestMethods::basicWithSimpleArgs::arg1", - "arg1", - "Boolean", - False, - False, - ), - ( - "::TestMethods::basicWithSimpleArgs::arg2", - "arg2", - "Byte", - False, - False, - ), - ( - "::TestMethods::basicWithSimpleArgs::arg3", - "arg3", - "UnsignedLong", - False, - False, - ), - ], - ) - ], - ) - checkMethod( - methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])] - ) - checkMethod( - methods[4], - "::TestMethods::basicStaticBoolean", - "basicStaticBoolean", - [("Boolean", [])], - static=True, - ) - checkMethod( - methods[5], - "::TestMethods::basicBooleanWithSimpleArgs", - "basicBooleanWithSimpleArgs", - [ - ( - "Boolean", - [ - ( - "::TestMethods::basicBooleanWithSimpleArgs::arg1", - "arg1", - "Boolean", - False, - False, - ), - ( - "::TestMethods::basicBooleanWithSimpleArgs::arg2", - "arg2", - "Byte", - False, - False, - ), - ( - "::TestMethods::basicBooleanWithSimpleArgs::arg3", - "arg3", - "UnsignedLong", - False, - False, - ), - ], - ) - ], - ) - checkMethod( - methods[6], - "::TestMethods::optionalArg", - "optionalArg", - [ - ( - "Undefined", - [ - ( - "::TestMethods::optionalArg::arg1", - "arg1", - "ByteOrNull", - True, - False, - ), - ( - "::TestMethods::optionalArg::arg2", - "arg2", - "ByteSequence", - True, - False, - ), - ], - ) - ], - ) - checkMethod( - methods[7], - "::TestMethods::variadicArg", - "variadicArg", - [ - ( - "Undefined", - [ - ( - "::TestMethods::variadicArg::arg1", - "arg1", - "ByteOrNull", - True, - True, - ) - ], - ) - ], - ) - checkMethod(methods[8], "::TestMethods::getObject", "getObject", [("Object", [])]) - checkMethod( - methods[9], - "::TestMethods::setObject", - "setObject", - [ - ( - "Undefined", - [("::TestMethods::setObject::arg1", "arg1", "Object", False, False)], - ) - ], - ) - checkMethod( - methods[10], - "::TestMethods::setAny", - "setAny", - [("Undefined", [("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])], - ) - checkMethod( - methods[11], - "::TestMethods::doFloats", - "doFloats", - [("Float", [("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])], - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - undefined foo(optional float bar = 1); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(not threw, "Should allow integer to float type corecion") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [GetterThrows] undefined foo(); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should not allow [GetterThrows] on methods") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [SetterThrows] undefined foo(); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should not allow [SetterThrows] on methods") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throw] undefined foo(); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should spell [Throws] correctly on methods") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - undefined __noSuchMethod__(); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should not allow __noSuchMethod__ methods") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throws, LenientFloat] - undefined foo(float myFloat); - [Throws] - undefined foo(); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(not threw, "Should allow LenientFloat to be only in a specific overload") - - parser = parser.reset() - parser.parse( - """ - interface A { - [Throws] - undefined foo(); - [Throws, LenientFloat] - undefined foo(float myFloat); - }; - """ - ) - results = parser.finish() - iface = results[0] - methods = iface.members - lenientFloat = methods[0].getExtendedAttribute("LenientFloat") - harness.ok( - lenientFloat is not None, - "LenientFloat in overloads must be added to the method", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throws, LenientFloat] - undefined foo(float myFloat); - [Throws] - undefined foo(float myFloat, float yourFloat); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, - "Should prevent overloads from getting different restricted float behavior", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throws] - undefined foo(float myFloat, float yourFloat); - [Throws, LenientFloat] - undefined foo(float myFloat); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, - "Should prevent overloads from getting different restricted float behavior (2)", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Throws, LenientFloat] - undefined foo(float myFloat); - [Throws, LenientFloat] - undefined foo(short myShort); - }; - """ - ) - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should prevent overloads from getting redundant [LenientFloat]") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_namespace.py b/components/script/dom/bindings/codegen/parser/tests/test_namespace.py deleted file mode 100644 index 247c5b22232..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_namespace.py +++ /dev/null @@ -1,232 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - namespace MyNamespace { - attribute any foo; - any bar(); - }; - """ - ) - - results = parser.finish() - harness.check(len(results), 1, "Should have a thing.") - harness.ok(results[0].isNamespace(), "Our thing should be a namespace") - harness.check(len(results[0].members), 2, "Should have two things in our namespace") - harness.ok(results[0].members[0].isAttr(), "First member is attribute") - harness.ok(results[0].members[0].isStatic(), "Attribute should be static") - harness.ok(results[0].members[1].isMethod(), "Second member is method") - harness.ok(results[0].members[1].isStatic(), "Operation should be static") - - parser = parser.reset() - parser.parse( - """ - namespace MyNamespace { - attribute any foo; - }; - partial namespace MyNamespace { - any bar(); - }; - """ - ) - - results = parser.finish() - harness.check(len(results), 2, "Should have things.") - harness.ok(results[0].isNamespace(), "Our thing should be a namespace") - harness.check(len(results[0].members), 2, "Should have two things in our namespace") - harness.ok(results[0].members[0].isAttr(), "First member is attribute") - harness.ok(results[0].members[0].isStatic(), "Attribute should be static") - harness.ok(results[0].members[1].isMethod(), "Second member is method") - harness.ok(results[0].members[1].isStatic(), "Operation should be static") - - parser = parser.reset() - parser.parse( - """ - partial namespace MyNamespace { - any bar(); - }; - namespace MyNamespace { - attribute any foo; - }; - """ - ) - - results = parser.finish() - harness.check(len(results), 2, "Should have things.") - harness.ok(results[1].isNamespace(), "Our thing should be a namespace") - harness.check(len(results[1].members), 2, "Should have two things in our namespace") - harness.ok(results[1].members[0].isAttr(), "First member is attribute") - harness.ok(results[1].members[0].isStatic(), "Attribute should be static") - harness.ok(results[1].members[1].isMethod(), "Second member is method") - harness.ok(results[1].members[1].isStatic(), "Operation should be static") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - namespace MyNamespace { - static attribute any foo; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - namespace MyNamespace { - static any bar(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - namespace MyNamespace { - any bar(); - }; - - interface MyNamespace { - any baz(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface MyNamespace { - any baz(); - }; - - namespace MyNamespace { - any bar(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - namespace MyNamespace { - any baz(); - }; - - namespace MyNamespace { - any bar(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - partial namespace MyNamespace { - any baz(); - }; - - interface MyNamespace { - any bar(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - namespace MyNamespace { - any bar(); - }; - - partial interface MyNamespace { - any baz(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - partial interface MyNamespace { - any baz(); - }; - - namespace MyNamespace { - any bar(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface MyNamespace { - any bar(); - }; - - partial namespace MyNamespace { - any baz(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_newobject.py b/components/script/dom/bindings/codegen/parser/tests/test_newobject.py deleted file mode 100644 index c12995a0e86..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_newobject.py +++ /dev/null @@ -1,76 +0,0 @@ -# Import the WebIDL module, so we can do isinstance checks and whatnot -import WebIDL - - -def WebIDLTest(parser, harness): - # Basic functionality - parser.parse( - """ - interface Iface { - [NewObject] readonly attribute Iface attr; - [NewObject] Iface method(); - }; - """ - ) - results = parser.finish() - harness.ok(results, "Should not have thrown on basic [NewObject] usage") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Iface { - [Pure, NewObject] readonly attribute Iface attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[NewObject] attributes must depend on something") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Iface { - [Pure, NewObject] Iface method(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[NewObject] methods must depend on something") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Iface { - [Cached, NewObject, Affects=Nothing] readonly attribute Iface attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[NewObject] attributes must not be [Cached]") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Iface { - [StoreInSlot, NewObject, Affects=Nothing] readonly attribute Iface attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[NewObject] attributes must not be [StoreInSlot]") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py deleted file mode 100644 index 012c5fcff7c..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py +++ /dev/null @@ -1,141 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestNullableEquivalency1 { - attribute long a; - attribute long? b; - }; - - interface TestNullableEquivalency2 { - attribute ArrayBuffer a; - attribute ArrayBuffer? b; - }; - - /* Can't have dictionary-valued attributes, so can't test that here */ - - enum TestNullableEquivalency4Enum { - "Foo", - "Bar" - }; - - interface TestNullableEquivalency4 { - attribute TestNullableEquivalency4Enum a; - attribute TestNullableEquivalency4Enum? b; - }; - - interface TestNullableEquivalency5 { - attribute TestNullableEquivalency4 a; - attribute TestNullableEquivalency4? b; - }; - - interface TestNullableEquivalency6 { - attribute boolean a; - attribute boolean? b; - }; - - interface TestNullableEquivalency7 { - attribute DOMString a; - attribute DOMString? b; - }; - - interface TestNullableEquivalency8 { - attribute float a; - attribute float? b; - }; - - interface TestNullableEquivalency9 { - attribute double a; - attribute double? b; - }; - - interface TestNullableEquivalency10 { - attribute object a; - attribute object? b; - }; - """ - ) - - for decl in parser.finish(): - if decl.isInterface(): - checkEquivalent(decl, harness) - - -def checkEquivalent(iface, harness): - type1 = iface.members[0].type - type2 = iface.members[1].type - - harness.check(type1.nullable(), False, "attr1 should not be nullable") - harness.check(type2.nullable(), True, "attr2 should be nullable") - - # We don't know about type1, but type2, the nullable type, definitely - # shouldn't be builtin. - harness.check(type2.builtin, False, "attr2 should not be builtin") - - # Ensure that all attributes of type2 match those in type1, except for: - # - names on an ignore list, - # - names beginning with '_', - # - functions which throw when called with no args, and - # - class-level non-callables ("static variables"). - # - # Yes, this is an ugly, fragile hack. But it finds bugs... - for attr in dir(type1): - if ( - attr.startswith("_") - or attr - in [ - "nullable", - "builtin", - "filename", - "location", - "inner", - "QName", - "getDeps", - "name", - "prettyName", - ] - or (hasattr(type(type1), attr) and not callable(getattr(type1, attr))) - ): - continue - - a1 = getattr(type1, attr) - - if callable(a1): - try: - v1 = a1() - except: - # Can't call a1 with no args, so skip this attriute. - continue - - try: - a2 = getattr(type2, attr) - except: - harness.ok( - False, - "Missing %s attribute on type %s in %s" % (attr, type2, iface), - ) - continue - - if not callable(a2): - harness.ok( - False, - "%s attribute on type %s in %s wasn't callable" - % (attr, type2, iface), - ) - continue - - v2 = a2() - harness.check(v2, v1, "%s method return value" % attr) - else: - try: - a2 = getattr(type2, attr) - except: - harness.ok( - False, - "Missing %s attribute on type %s in %s" % (attr, type2, iface), - ) - continue - - harness.check(a2, a1, "%s attribute should match" % attr) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py b/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py deleted file mode 100644 index 601f626bcf4..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_observableArray.py +++ /dev/null @@ -1,288 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -def WebIDLTest(parser, harness): - - # Test dictionary as inner type - harness.should_throw( - parser, - """ - dictionary A { - boolean member; - }; - interface B { - attribute ObservableArray<A> foo; - }; - """, - "use dictionary as inner type", - ) - - # Test sequence as inner type - harness.should_throw( - parser, - """ - interface A { - attribute ObservableArray<sequence<boolean>> foo; - }; - """, - "use sequence as inner type", - ) - - # Test sequence<dictionary> as inner type - harness.should_throw( - parser, - """ - dictionary A { - boolean member; - }; - interface B { - attribute ObservableArray<sequence<A>> foo; - }; - """, - "use sequence<dictionary> as inner type", - ) - - # Test record as inner type - harness.should_throw( - parser, - """ - interface A { - attribute ObservableArray<record<DOMString, boolean>> foo; - }; - """, - "use record as inner type", - ) - - # Test record<dictionary> as inner type - harness.should_throw( - parser, - """ - dictionary A { - boolean member; - }; - interface B { - attribute ObservableArray<record<DOMString, A>> foo; - }; - """, - "use record<dictionary> as inner type", - ) - - # Test observable array as inner type - harness.should_throw( - parser, - """ - interface A { - attribute ObservableArray<ObservableArray<boolean>> foo; - }; - """, - "use ObservableArray as inner type", - ) - - # Test nullable attribute - harness.should_throw( - parser, - """ - interface A { - attribute ObservableArray<boolean>? foo; - }; - """, - "nullable", - ) - - # Test sequence - harness.should_throw( - parser, - """ - interface A { - undefined foo(sequence<ObservableArray<boolean>> foo); - }; - """, - "used in sequence", - ) - - # Test record - harness.should_throw( - parser, - """ - interface A { - undefined foo(record<DOMString, ObservableArray<boolean>> foo); - }; - """, - "used in record", - ) - - # Test promise - harness.should_throw( - parser, - """ - interface A { - Promise<ObservableArray<boolean>> foo(); - }; - """, - "used in promise", - ) - - # Test union - harness.should_throw( - parser, - """ - interface A { - attribute (DOMString or ObservableArray<boolean>>) foo; - }; - """, - "used in union", - ) - - # Test dictionary member - harness.should_throw( - parser, - """ - dictionary A { - ObservableArray<boolean> foo; - }; - """, - "used on dictionary member type", - ) - - # Test argument - harness.should_throw( - parser, - """ - interface A { - undefined foo(ObservableArray<boolean> foo); - }; - """, - "used on argument", - ) - - # Test static attribute - harness.should_throw( - parser, - """ - interface A { - static attribute ObservableArray<boolean> foo; - }; - """, - "used on static attribute type", - ) - - # Test iterable - harness.should_throw( - parser, - """ - interface A { - iterable<ObservableArray<boolean>>; - }; - """, - "used in iterable", - ) - - # Test maplike - harness.should_throw( - parser, - """ - interface A { - maplike<long, ObservableArray<boolean>>; - }; - """, - "used in maplike", - ) - - # Test setlike - harness.should_throw( - parser, - """ - interface A { - setlike<ObservableArray<boolean>>; - }; - """, - "used in setlike", - ) - - # Test JS implemented interface - harness.should_throw( - parser, - """ - [JSImplementation="@mozilla.org/dom/test-interface-js;1"] - interface A { - readonly attribute ObservableArray<boolean> foo; - }; - """, - "used in JS implemented interface", - ) - - # Test namespace - harness.should_throw( - parser, - """ - namespace A { - readonly attribute ObservableArray<boolean> foo; - }; - """, - "used in namespaces", - ) - - # Test [Cached] extended attribute - harness.should_throw( - parser, - """ - interface A { - [Cached, Pure] - readonly attribute ObservableArray<boolean> foo; - }; - """, - "have Cached extended attribute", - ) - - # Test [StoreInSlot] extended attribute - harness.should_throw( - parser, - """ - interface A { - [StoreInSlot, Pure] - readonly attribute ObservableArray<boolean> foo; - }; - """, - "have StoreInSlot extended attribute", - ) - - # Test regular attribute - parser = parser.reset() - parser.parse( - """ - interface A { - readonly attribute ObservableArray<boolean> foo; - attribute ObservableArray<[Clamp] octet> bar; - attribute ObservableArray<long?> baz; - attribute ObservableArray<(boolean or long)> qux; - }; - """ - ) - results = parser.finish() - A = results[0] - foo = A.members[0] - harness.ok(foo.readonly, "A.foo is readonly attribute") - harness.ok(foo.type.isObservableArray(), "A.foo is ObservableArray type") - harness.check( - foo.slotIndices[A.identifier.name], 0, "A.foo should be stored in slot" - ) - bar = A.members[1] - harness.ok(bar.type.isObservableArray(), "A.bar is ObservableArray type") - harness.check( - bar.slotIndices[A.identifier.name], 1, "A.bar should be stored in slot" - ) - harness.ok(bar.type.inner.hasClamp(), "A.bar's inner type should be clamped") - baz = A.members[2] - harness.ok(baz.type.isObservableArray(), "A.baz is ObservableArray type") - harness.check( - baz.slotIndices[A.identifier.name], 2, "A.baz should be stored in slot" - ) - harness.ok(baz.type.inner.nullable(), "A.baz's inner type should be nullable") - qux = A.members[3] - harness.ok(qux.type.isObservableArray(), "A.qux is ObservableArray type") - harness.check( - qux.slotIndices[A.identifier.name], 3, "A.qux should be stored in slot" - ) - harness.ok(qux.type.inner.isUnion(), "A.qux's inner type should be union") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py b/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py deleted file mode 100644 index 2044c6362c3..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_optional_constraints.py +++ /dev/null @@ -1,35 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface OptionalConstraints1 { - undefined foo(optional byte arg1, byte arg2); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - not threw, - "Should not have thrown on non-optional argument following " - "optional argument.", - ) - - parser = parser.reset() - parser.parse( - """ - interface OptionalConstraints2 { - undefined foo(optional byte arg1 = 1, optional byte arg2 = 2, - optional byte arg3, optional byte arg4 = 4, - optional byte arg5, optional byte arg6 = 9); - }; - """ - ) - results = parser.finish() - args = results[0].members[0].signatures()[0][1] - harness.check(len(args), 6, "Should have 6 arguments") - harness.check(args[5].defaultValue.value, 9, "Should have correct default value") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_overload.py b/components/script/dom/bindings/codegen/parser/tests/test_overload.py deleted file mode 100644 index 7816276aa6d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_overload.py +++ /dev/null @@ -1,74 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestOverloads { - undefined basic(); - undefined basic(long arg1); - boolean abitharder(TestOverloads foo); - boolean abitharder(boolean foo); - undefined abitharder(ArrayBuffer? foo); - undefined withVariadics(long... numbers); - undefined withVariadics(TestOverloads iface); - undefined withVariadics(long num, TestOverloads iface); - undefined optionalTest(); - undefined optionalTest(optional long num1, long num2); - }; - """ - ) - - results = parser.finish() - - harness.ok(True, "TestOverloads interface parsed without error.") - harness.check(len(results), 1, "Should be one production.") - iface = results[0] - harness.ok(isinstance(iface, WebIDL.IDLInterface), "Should be an IDLInterface") - harness.check( - iface.identifier.QName(), "::TestOverloads", "Interface has the right QName" - ) - harness.check( - iface.identifier.name, "TestOverloads", "Interface has the right name" - ) - harness.check(len(iface.members), 4, "Expect %s members" % 4) - - member = iface.members[0] - harness.check( - member.identifier.QName(), - "::TestOverloads::basic", - "Method has the right QName", - ) - harness.check(member.identifier.name, "basic", "Method has the right name") - harness.check(member.hasOverloads(), True, "Method has overloads") - - signatures = member.signatures() - harness.check(len(signatures), 2, "Method should have 2 signatures") - - (retval, argumentSet) = signatures[0] - - harness.check(str(retval), "Undefined", "Expect an undefined retval") - harness.check(len(argumentSet), 0, "Expect an empty argument set") - - (retval, argumentSet) = signatures[1] - harness.check(str(retval), "Undefined", "Expect an undefined retval") - harness.check(len(argumentSet), 1, "Expect an argument set with one argument") - - argument = argumentSet[0] - harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") - harness.check( - argument.identifier.QName(), - "::TestOverloads::basic::arg1", - "Argument has the right QName", - ) - harness.check(argument.identifier.name, "arg1", "Argument has the right name") - harness.check(str(argument.type), "Long", "Argument has the right type") - - member = iface.members[3] - harness.check( - len(member.overloadsForArgCount(0)), 1, "Only one overload for no args" - ) - harness.check(len(member.overloadsForArgCount(1)), 0, "No overloads for one arg") - harness.check( - len(member.overloadsForArgCount(2)), 1, "Only one overload for two args" - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_promise.py b/components/script/dom/bindings/codegen/parser/tests/test_promise.py deleted file mode 100644 index 9b418d51afe..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_promise.py +++ /dev/null @@ -1,177 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface A { - legacycaller Promise<any> foo(); - }; - """ - ) - results = parser.finish() - - except: - threw = True - harness.ok(threw, "Should not allow Promise return values for legacycaller.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - Promise<any> foo(); - long foo(long arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow overloads which have both Promise and " - "non-Promise return types.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - long foo(long arg); - Promise<any> foo(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow overloads which have both Promise and " - "non-Promise return types.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - Promise<any>? foo(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow nullable Promise return values.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - undefined foo(Promise<any>? arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow nullable Promise arguments.") - - parser = parser.reset() - parser.parse( - """ - interface A { - Promise<any> foo(); - Promise<any> foo(long arg); - }; - """ - ) - results = parser.finish() - - harness.ok( - True, "Should allow overloads which only have Promise and return " "types." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - attribute Promise<any> attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow writable Promise-typed attributes.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [LegacyLenientSetter] readonly attribute Promise<any> attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "Should not allow [LegacyLenientSetter] Promise-typed attributes." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [PutForwards=bar] readonly attribute Promise<any> attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow [PutForwards] Promise-typed attributes.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [Replaceable] readonly attribute Promise<any> attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow [Replaceable] Promise-typed attributes.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface A { - [SameObject] readonly attribute Promise<any> attr; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow [SameObject] Promise-typed attributes.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py b/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py deleted file mode 100644 index 5a806bf2a2d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py +++ /dev/null @@ -1,107 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface TestIface { - static attribute boolean prototype; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "The identifier of a static attribute must not be 'prototype'") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestIface { - static boolean prototype(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "The identifier of a static operation must not be 'prototype'") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestIface { - const boolean prototype = true; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "The identifier of a constant must not be 'prototype'") - - # Make sure that we can parse non-static attributes with 'prototype' as identifier. - parser = parser.reset() - parser.parse( - """ - interface TestIface { - attribute boolean prototype; - }; - """ - ) - results = parser.finish() - - testIface = results[0] - harness.check( - testIface.members[0].isStatic(), False, "Attribute should not be static" - ) - harness.check( - testIface.members[0].identifier.name, - "prototype", - "Attribute identifier should be 'prototype'", - ) - - # Make sure that we can parse non-static operations with 'prototype' as identifier. - parser = parser.reset() - parser.parse( - """ - interface TestIface { - boolean prototype(); - }; - """ - ) - results = parser.finish() - - testIface = results[0] - harness.check( - testIface.members[0].isStatic(), False, "Operation should not be static" - ) - harness.check( - testIface.members[0].identifier.name, - "prototype", - "Operation identifier should be 'prototype'", - ) - - # Make sure that we can parse dictionary members with 'prototype' as identifier. - parser = parser.reset() - parser.parse( - """ - dictionary TestDict { - boolean prototype; - }; - """ - ) - results = parser.finish() - - testDict = results[0] - harness.check( - testDict.members[0].identifier.name, - "prototype", - "Dictionary member should be 'prototype'", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py b/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py deleted file mode 100644 index 5ec4dde280e..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py +++ /dev/null @@ -1,119 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface I { - [PutForwards=B] readonly attribute long A; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface I { - [PutForwards=B] readonly attribute J A; - }; - interface J { - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface I { - [PutForwards=B] attribute J A; - }; - interface J { - attribute long B; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface I { - [PutForwards=B] static readonly attribute J A; - }; - interface J { - attribute long B; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - callback interface I { - [PutForwards=B] readonly attribute J A; - }; - interface J { - attribute long B; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface I { - [PutForwards=C] readonly attribute J A; - [PutForwards=C] readonly attribute J B; - }; - interface J { - [PutForwards=D] readonly attribute K C; - }; - interface K { - [PutForwards=A] readonly attribute I D; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_record.py b/components/script/dom/bindings/codegen/parser/tests/test_record.py deleted file mode 100644 index 3a31d721b27..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_record.py +++ /dev/null @@ -1,61 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - dictionary Dict {}; - interface RecordArg { - undefined foo(record<DOMString, Dict> arg); - }; - """ - ) - - results = parser.finish() - - harness.check(len(results), 2, "Should know about two things") - harness.ok( - isinstance(results[1], WebIDL.IDLInterface), "Should have an interface here" - ) - members = results[1].members - harness.check(len(members), 1, "Should have one member") - harness.ok(members[0].isMethod(), "Should have method") - signature = members[0].signatures()[0] - args = signature[1] - harness.check(len(args), 1, "Should have one arg") - harness.ok(args[0].type.isRecord(), "Should have a record type here") - harness.ok(args[0].type.inner.isDictionary(), "Should have a dictionary inner type") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface RecordUndefinedArg { - undefined foo(record<DOMString, undefined> arg); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, "Should have thrown because record can't have undefined as value type." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - dictionary Dict { - record<DOMString, Dict> val; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown on dictionary containing itself via record.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py b/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py deleted file mode 100644 index 06ea6a47239..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py +++ /dev/null @@ -1,84 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -def should_throw(parser, harness, message, code): - parser = parser.reset() - threw = False - try: - parser.parse(code) - parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown: %s" % message) - - -def WebIDLTest(parser, harness): - # The [Replaceable] extended attribute MUST take no arguments. - should_throw( - parser, - harness, - "no arguments", - """ - interface I { - [Replaceable=X] readonly attribute long A; - }; - """, - ) - - # An attribute with the [Replaceable] extended attribute MUST NOT also be - # declared with the [PutForwards] extended attribute. - should_throw( - parser, - harness, - "PutForwards", - """ - interface I { - [PutForwards=B, Replaceable] readonly attribute J A; - }; - interface J { - attribute long B; - }; - """, - ) - - # The [Replaceable] extended attribute MUST NOT be used on an attribute - # that is not read only. - should_throw( - parser, - harness, - "writable attribute", - """ - interface I { - [Replaceable] attribute long A; - }; - """, - ) - - # The [Replaceable] extended attribute MUST NOT be used on a static - # attribute. - should_throw( - parser, - harness, - "static attribute", - """ - interface I { - [Replaceable] static readonly attribute long A; - }; - """, - ) - - # The [Replaceable] extended attribute MUST NOT be used on an attribute - # declared on a callback interface. - should_throw( - parser, - harness, - "callback interface", - """ - callback interface I { - [Replaceable] readonly attribute long A; - }; - """, - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_sanity.py b/components/script/dom/bindings/codegen/parser/tests/test_sanity.py deleted file mode 100644 index d3184c00731..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_sanity.py +++ /dev/null @@ -1,7 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse("") - parser.finish() - harness.ok(True, "Parsing nothing doesn't throw.") - parser.parse("interface Foo {};") - parser.finish() - harness.ok(True, "Parsing a silly interface doesn't throw.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py b/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py deleted file mode 100644 index e0e967dd420..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py +++ /dev/null @@ -1,499 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - [SecureContext] - interface TestSecureContextOnInterface { - const octet TEST_CONSTANT = 0; - readonly attribute byte testAttribute; - undefined testMethod(byte foo); - }; - partial interface TestSecureContextOnInterface { - const octet TEST_CONSTANT_2 = 0; - readonly attribute byte testAttribute2; - undefined testMethod2(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 6, - "TestSecureContextOnInterface should have six members", - ) - harness.ok( - results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members", - ) - harness.ok( - results[0].members[1].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members", - ) - harness.ok( - results[0].members[2].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members", - ) - harness.ok( - results[0].members[3].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members from partial interface", - ) - harness.ok( - results[0].members[4].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members from partial interface", - ) - harness.ok( - results[0].members[5].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members from partial interface", - ) - - # Same thing, but with the partial interface specified first: - parser = parser.reset() - parser.parse( - """ - partial interface TestSecureContextOnInterfaceAfterPartialInterface { - const octet TEST_CONSTANT_2 = 0; - readonly attribute byte testAttribute2; - undefined testMethod2(byte foo); - }; - [SecureContext] - interface TestSecureContextOnInterfaceAfterPartialInterface { - const octet TEST_CONSTANT = 0; - readonly attribute byte testAttribute; - undefined testMethod(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[1].members), - 6, - "TestSecureContextOnInterfaceAfterPartialInterface should have six members", - ) - harness.ok( - results[1].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[1].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members", - ) - harness.ok( - results[1].members[1].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members", - ) - harness.ok( - results[1].members[2].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members", - ) - harness.ok( - results[1].members[3].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members from partial interface", - ) - harness.ok( - results[1].members[4].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to attribute members from partial interface", - ) - harness.ok( - results[1].members[5].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to method members from partial interface", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestSecureContextOnPartialInterface { - const octet TEST_CONSTANT = 0; - readonly attribute byte testAttribute; - undefined testMethod(byte foo); - }; - [SecureContext] - partial interface TestSecureContextOnPartialInterface { - const octet TEST_CONSTANT_2 = 0; - readonly attribute byte testAttribute2; - undefined testMethod2(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 6, - "TestSecureContextOnPartialInterface should have six members", - ) - harness.ok( - results[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's constant members", - ) - harness.ok( - results[0].members[1].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's attribute members", - ) - harness.ok( - results[0].members[2].getExtendedAttribute("SecureContext") is None, - "[SecureContext] should not propagate from a partial interface to the interface's method members", - ) - harness.ok( - results[0].members[3].getExtendedAttribute("SecureContext"), - "Constant members from [SecureContext] partial interface should be [SecureContext]", - ) - harness.ok( - results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute members from [SecureContext] partial interface should be [SecureContext]", - ) - harness.ok( - results[0].members[5].getExtendedAttribute("SecureContext"), - "Method members from [SecureContext] partial interface should be [SecureContext]", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestSecureContextOnInterfaceMembers { - const octet TEST_NON_SECURE_CONSTANT_1 = 0; - [SecureContext] - const octet TEST_SECURE_CONSTANT = 1; - const octet TEST_NON_SECURE_CONSTANT_2 = 2; - readonly attribute byte testNonSecureAttribute1; - [SecureContext] - readonly attribute byte testSecureAttribute; - readonly attribute byte testNonSecureAttribute2; - undefined testNonSecureMethod1(byte foo); - [SecureContext] - undefined testSecureMethod(byte foo); - undefined testNonSecureMethod2(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 9, - "TestSecureContextOnInterfaceMembers should have nine members", - ) - harness.ok( - results[0].getExtendedAttribute("SecureContext") is None, - "[SecureContext] on members should not propagate up to the interface", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext") is None, - "Constant should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[1].getExtendedAttribute("SecureContext"), - "Constant should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Constant should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Attribute should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[5].getExtendedAttribute("SecureContext") is None, - "Attribute should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[6].getExtendedAttribute("SecureContext") is None, - "Method should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[7].getExtendedAttribute("SecureContext"), - "Method should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[8].getExtendedAttribute("SecureContext") is None, - "Method should not have [SecureContext] extended attribute", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestSecureContextOnPartialInterfaceMembers { - }; - partial interface TestSecureContextOnPartialInterfaceMembers { - const octet TEST_NON_SECURE_CONSTANT_1 = 0; - [SecureContext] - const octet TEST_SECURE_CONSTANT = 1; - const octet TEST_NON_SECURE_CONSTANT_2 = 2; - readonly attribute byte testNonSecureAttribute1; - [SecureContext] - readonly attribute byte testSecureAttribute; - readonly attribute byte testNonSecureAttribute2; - undefined testNonSecureMethod1(byte foo); - [SecureContext] - undefined testSecureMethod(byte foo); - undefined testNonSecureMethod2(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 9, - "TestSecureContextOnPartialInterfaceMembers should have nine members", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext") is None, - "Constant from partial interface should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[1].getExtendedAttribute("SecureContext"), - "Constant from partial interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Constant from partial interface should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Attribute from partial interface should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[4].getExtendedAttribute("SecureContext"), - "Attribute from partial interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[5].getExtendedAttribute("SecureContext") is None, - "Attribute from partial interface should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[6].getExtendedAttribute("SecureContext") is None, - "Method from partial interface should not have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[7].getExtendedAttribute("SecureContext"), - "Method from partial interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[8].getExtendedAttribute("SecureContext") is None, - "Method from partial interface should not have [SecureContext] extended attribute", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SecureContext=something] - interface TestSecureContextTakesNoValue1 { - const octet TEST_SECURE_CONSTANT = 0; - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "[SecureContext] must take no arguments (testing on interface)") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestSecureContextForOverloads1 { - [SecureContext] - undefined testSecureMethod(byte foo); - }; - partial interface TestSecureContextForOverloads1 { - undefined testSecureMethod(byte foo, byte bar); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "If [SecureContext] appears on an overloaded operation, then it MUST appear on all overloads", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestSecureContextForOverloads2 { - [SecureContext] - undefined testSecureMethod(byte foo); - }; - partial interface TestSecureContextForOverloads2 { - [SecureContext] - undefined testSecureMethod(byte foo, byte bar); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - not threw, - "[SecureContext] can appear on an overloaded operation if it appears on all overloads", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SecureContext] - interface TestSecureContextOnInterfaceAndMember { - [SecureContext] - undefined testSecureMethod(byte foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, "[SecureContext] must not appear on an interface and interface member" - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestSecureContextOnPartialInterfaceAndMember { - }; - [SecureContext] - partial interface TestSecureContextOnPartialInterfaceAndMember { - [SecureContext] - undefined testSecureMethod(byte foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "[SecureContext] must not appear on a partial interface and one of the partial interface's member's", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SecureContext] - interface TestSecureContextOnInterfaceAndPartialInterfaceMember { - }; - partial interface TestSecureContextOnInterfaceAndPartialInterfaceMember { - [SecureContext] - undefined testSecureMethod(byte foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "[SecureContext] must not appear on an interface and one of its partial interface's member's", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [SecureContext] - interface TestSecureContextOnInheritedInterface { - }; - interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface { - undefined testSecureMethod(byte foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "[SecureContext] must appear on interfaces that inherit from another [SecureContext] interface", - ) - - # Test 'includes'. - parser = parser.reset() - parser.parse( - """ - [SecureContext] - interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin { - const octet TEST_CONSTANT = 0; - }; - interface mixin TestNonSecureContextMixin { - const octet TEST_CONSTANT_2 = 0; - readonly attribute byte testAttribute2; - undefined testMethod2(byte foo); - }; - TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 4, - "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four members", - ) - harness.ok( - results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext"), - "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface", - ) - harness.ok( - results[0].members[1].getExtendedAttribute("SecureContext") is None, - "Constants copied from non-[SecureContext] mixin should not be [SecureContext]", - ) - harness.ok( - results[0].members[2].getExtendedAttribute("SecureContext") is None, - "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]", - ) - harness.ok( - results[0].members[3].getExtendedAttribute("SecureContext") is None, - "Methods copied from non-[SecureContext] mixin should not be [SecureContext]", - ) - - # Test SecureContext and LegacyNoInterfaceObject - parser = parser.reset() - parser.parse( - """ - [LegacyNoInterfaceObject, SecureContext] - interface TestSecureContextLegacyNoInterfaceObject { - undefined testSecureMethod(byte foo); - }; - """ - ) - results = parser.finish() - harness.check( - len(results[0].members), - 1, - "TestSecureContextLegacyNoInterfaceObject should have only one member", - ) - harness.ok( - results[0].getExtendedAttribute("SecureContext"), - "Interface should have [SecureContext] extended attribute", - ) - harness.ok( - results[0].members[0].getExtendedAttribute("SecureContext"), - "Interface member should have [SecureContext] extended attribute", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py b/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py deleted file mode 100644 index a11860b3728..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_method_signature_mismatch.py +++ /dev/null @@ -1,256 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch1 { - getter long long foo(long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch2 { - getter undefined foo(unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch3 { - getter boolean foo(unsigned long index, boolean extraArg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch4 { - getter boolean foo(unsigned long... index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch5 { - getter boolean foo(optional unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch6 { - getter boolean foo(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch7 { - deleter long long foo(long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch9 { - deleter boolean foo(unsigned long index, boolean extraArg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch10 { - deleter boolean foo(unsigned long... index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch11 { - deleter boolean foo(optional unsigned long index); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch12 { - deleter boolean foo(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch13 { - setter long long foo(long index, long long value); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch15 { - setter boolean foo(unsigned long index, boolean value, long long extraArg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch16 { - setter boolean foo(unsigned long index, boolean... value); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch17 { - setter boolean foo(unsigned long index, optional boolean value); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodSignatureMismatch18 { - setter boolean foo(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py b/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py deleted file mode 100644 index 9601a0a968f..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_methods.py +++ /dev/null @@ -1,117 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface SpecialMethods { - getter long long (unsigned long index); - setter long long (unsigned long index, long long value); - getter boolean (DOMString name); - setter boolean (DOMString name, boolean value); - deleter boolean (DOMString name); - readonly attribute unsigned long length; - }; - - interface SpecialMethodsCombination { - getter deleter boolean (DOMString name); - }; - """ - ) - - results = parser.finish() - - def checkMethod( - method, - QName, - name, - static=False, - getter=False, - setter=False, - deleter=False, - legacycaller=False, - stringifier=False, - ): - harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") - harness.check(method.identifier.QName(), QName, "Method has the right QName") - harness.check(method.identifier.name, name, "Method has the right name") - harness.check(method.isStatic(), static, "Method has the correct static value") - harness.check(method.isGetter(), getter, "Method has the correct getter value") - harness.check(method.isSetter(), setter, "Method has the correct setter value") - harness.check( - method.isDeleter(), deleter, "Method has the correct deleter value" - ) - harness.check( - method.isLegacycaller(), - legacycaller, - "Method has the correct legacycaller value", - ) - harness.check( - method.isStringifier(), - stringifier, - "Method has the correct stringifier value", - ) - - harness.check(len(results), 2, "Expect 2 interfaces") - - iface = results[0] - harness.check(len(iface.members), 6, "Expect 6 members") - - checkMethod( - iface.members[0], - "::SpecialMethods::__indexedgetter", - "__indexedgetter", - getter=True, - ) - checkMethod( - iface.members[1], - "::SpecialMethods::__indexedsetter", - "__indexedsetter", - setter=True, - ) - checkMethod( - iface.members[2], - "::SpecialMethods::__namedgetter", - "__namedgetter", - getter=True, - ) - checkMethod( - iface.members[3], - "::SpecialMethods::__namedsetter", - "__namedsetter", - setter=True, - ) - checkMethod( - iface.members[4], - "::SpecialMethods::__nameddeleter", - "__nameddeleter", - deleter=True, - ) - - iface = results[1] - harness.check(len(iface.members), 1, "Expect 1 member") - - checkMethod( - iface.members[0], - "::SpecialMethodsCombination::__namedgetterdeleter", - "__namedgetterdeleter", - getter=True, - deleter=True, - ) - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - interface IndexedDeleter { - deleter undefined(unsigned long index); - }; - """ - ) - parser.finish() - except: - threw = True - - harness.ok(threw, "There are no indexed deleters") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py b/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py deleted file mode 100644 index 014737e8168..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_special_methods_uniqueness.py +++ /dev/null @@ -1,54 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface SpecialMethodUniqueness1 { - getter deleter boolean (DOMString name); - getter boolean (DOMString name); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodUniqueness1 { - deleter boolean (DOMString name); - getter deleter boolean (DOMString name); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - threw = False - try: - parser.parse( - """ - interface SpecialMethodUniqueness1 { - setter boolean (DOMString name); - setter boolean (DOMString name); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py b/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py deleted file mode 100644 index 948be71e4dd..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py +++ /dev/null @@ -1,196 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestStringifier { - stringifier; - }; - """ - ) - - results = parser.finish() - - harness.ok( - isinstance(results[0].members[0], WebIDL.IDLMethod), - "Stringifer should be method", - ) - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - interface TestStringifier { - stringifier; - stringifier; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow two 'stringifier;'") - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - interface TestStringifier { - stringifier; - stringifier DOMString foo(); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow a 'stringifier;' and a 'stringifier()'") - - parser = parser.reset() - parser.parse( - """ - interface TestStringifier { - stringifier attribute DOMString foo; - }; - """ - ) - results = parser.finish() - harness.ok( - isinstance(results[0].members[0], WebIDL.IDLAttribute), - "Stringifier attribute should be an attribute", - ) - stringifier = results[0].members[1] - harness.ok( - isinstance(stringifier, WebIDL.IDLMethod), - "Stringifier attribute should insert a method", - ) - harness.ok(stringifier.isStringifier(), "Inserted method should be a stringifier") - - parser = parser.reset() - parser.parse( - """ - interface TestStringifier {}; - interface mixin TestStringifierMixin { - stringifier attribute DOMString foo; - }; - TestStringifier includes TestStringifierMixin; - """ - ) - results = parser.finish() - harness.ok( - isinstance(results[0].members[0], WebIDL.IDLAttribute), - "Stringifier attribute should be an attribute", - ) - stringifier = results[0].members[1] - harness.ok( - isinstance(stringifier, WebIDL.IDLMethod), - "Stringifier attribute should insert a method", - ) - harness.ok(stringifier.isStringifier(), "Inserted method should be a stringifier") - - parser = parser.reset() - parser.parse( - """ - interface TestStringifier { - stringifier attribute USVString foo; - }; - """ - ) - results = parser.finish() - stringifier = results[0].members[1] - harness.ok( - stringifier.signatures()[0][0].isUSVString(), - "Stringifier attributes should allow USVString", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestStringifier { - [Throws, NeedsSubjectPrincipal] - stringifier attribute USVString foo; - }; - """ - ) - results = parser.finish() - stringifier = results[0].members[1] - harness.ok( - stringifier.getExtendedAttribute("Throws"), - "Stringifier attributes should support [Throws]", - ) - harness.ok( - stringifier.getExtendedAttribute("NeedsSubjectPrincipal"), - "Stringifier attributes should support [NeedsSubjectPrincipal]", - ) - - parser = parser.reset() - parser.parse( - """ - interface TestStringifier { - stringifier attribute UTF8String foo; - }; - """ - ) - results = parser.finish() - stringifier = results[0].members[1] - harness.ok( - stringifier.signatures()[0][0].isUTF8String(), - "Stringifier attributes should allow UTF8String", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestStringifier { - stringifier attribute ByteString foo; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow ByteString") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestStringifier { - stringifier; - stringifier attribute DOMString foo; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow a 'stringifier;' and a stringifier attribute") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface TestStringifier { - stringifier attribute DOMString foo; - stringifier attribute DOMString bar; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should not allow multiple stringifier attributes") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py b/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py deleted file mode 100644 index f312667ec4d..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_toJSON.py +++ /dev/null @@ -1,309 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface Test { - object toJSON(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(not threw, "Should allow a toJSON method.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Test { - object toJSON(object arg); - object toJSON(long arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow overloads of a toJSON method.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Test { - object toJSON(object arg); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(threw, "Should not allow a toJSON method with arguments.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Test { - long toJSON(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok(not threw, "Should allow a toJSON method with 'long' as return type.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Test { - [Default] object toJSON(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - not threw, "Should allow a default toJSON method with 'object' as return type." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Test { - [Default] long toJSON(); - }; - """ - ) - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should not allow a default toJSON method with non-'object' as return type.", - ) - - JsonTypes = [ - "byte", - "octet", - "short", - "unsigned short", - "long", - "unsigned long", - "long long", - "unsigned long long", - "float", - "unrestricted float", - "double", - "unrestricted double", - "boolean", - "DOMString", - "ByteString", - "UTF8String", - "USVString", - "Enum", - "InterfaceWithToJSON", - "object", - ] - - nonJsonTypes = [ - "InterfaceWithoutToJSON", - "any", - "Int8Array", - "Int16Array", - "Int32Array", - "Uint8Array", - "Uint16Array", - "Uint32Array", - "Uint8ClampedArray", - "Float32Array", - "Float64Array", - "ArrayBuffer", - ] - - def doTest(testIDL, shouldThrow, description): - p = parser.reset() - threw = False - try: - p.parse( - testIDL - + """ - enum Enum { "a", "b", "c" }; - interface InterfaceWithToJSON { long toJSON(); }; - interface InterfaceWithoutToJSON {}; - """ - ) - p.finish() - except Exception as x: - threw = True - harness.ok(x.message == "toJSON method has non-JSON return type", x) - harness.check(threw, shouldThrow, description) - - for type in JsonTypes: - doTest( - "interface Test { %s toJSON(); };" % type, - False, - "%s should be a JSON type" % type, - ) - - doTest( - "interface Test { sequence<%s> toJSON(); };" % type, - False, - "sequence<%s> should be a JSON type" % type, - ) - - doTest( - "dictionary Foo { %s foo; }; " "interface Test { Foo toJSON(); }; " % type, - False, - "dictionary containing only JSON type (%s) should be a JSON type" % type, - ) - - doTest( - "dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " - "interface Test { Bar toJSON(); }; " % type, - False, - "dictionary whose ancestors only contain JSON types should be a JSON type", - ) - - doTest( - "dictionary Foo { any foo; }; dictionary Bar : Foo { %s bar; };" - "interface Test { Bar toJSON(); };" % type, - True, - "dictionary whose ancestors contain non-JSON types should not be a JSON type", - ) - - doTest( - "interface Test { record<DOMString, %s> toJSON(); };" % type, - False, - "record<DOMString, %s> should be a JSON type" % type, - ) - - doTest( - "interface Test { record<ByteString, %s> toJSON(); };" % type, - False, - "record<ByteString, %s> should be a JSON type" % type, - ) - - doTest( - "interface Test { record<UTF8String, %s> toJSON(); };" % type, - False, - "record<UTF8String, %s> should be a JSON type" % type, - ) - - doTest( - "interface Test { record<USVString, %s> toJSON(); };" % type, - False, - "record<USVString, %s> should be a JSON type" % type, - ) - - otherUnionType = "Foo" if type != "object" else "long" - doTest( - "interface Foo { object toJSON(); };" - "interface Test { (%s or %s) toJSON(); };" % (otherUnionType, type), - False, - "union containing only JSON types (%s or %s) should be a JSON type" - % (otherUnionType, type), - ) - - doTest( - "interface test { %s? toJSON(); };" % type, - False, - "Nullable type (%s) should be a JSON type" % type, - ) - - doTest( - "interface Foo : InterfaceWithoutToJSON { %s toJSON(); };" - "interface Test { Foo toJSON(); };" % type, - False, - "interface with toJSON should be a JSON type", - ) - - doTest( - "interface Foo : InterfaceWithToJSON { };" "interface Test { Foo toJSON(); };", - False, - "inherited interface with toJSON should be a JSON type", - ) - - for type in nonJsonTypes: - doTest( - "interface Test { %s toJSON(); };" % type, - True, - "%s should not be a JSON type" % type, - ) - - doTest( - "interface Test { sequence<%s> toJSON(); };" % type, - True, - "sequence<%s> should not be a JSON type" % type, - ) - - doTest( - "dictionary Foo { %s foo; }; " "interface Test { Foo toJSON(); }; " % type, - True, - "Dictionary containing a non-JSON type (%s) should not be a JSON type" - % type, - ) - - doTest( - "dictionary Foo { %s foo; }; dictionary Bar : Foo { }; " - "interface Test { Bar toJSON(); }; " % type, - True, - "dictionary whose ancestors only contain non-JSON types should not be a JSON type", - ) - - doTest( - "interface Test { record<DOMString, %s> toJSON(); };" % type, - True, - "record<DOMString, %s> should not be a JSON type" % type, - ) - - doTest( - "interface Test { record<ByteString, %s> toJSON(); };" % type, - True, - "record<ByteString, %s> should not be a JSON type" % type, - ) - - doTest( - "interface Test { record<USVString, %s> toJSON(); };" % type, - True, - "record<USVString, %s> should not be a JSON type" % type, - ) - - if type != "any": - doTest( - "interface Foo { object toJSON(); }; " - "interface Test { (Foo or %s) toJSON(); };" % type, - True, - "union containing a non-JSON type (%s) should not be a JSON type" - % type, - ) - - doTest( - "interface test { %s? toJSON(); };" % type, - True, - "Nullable type (%s) should not be a JSON type" % type, - ) - - doTest( - "dictionary Foo { long foo; any bar; };" "interface Test { Foo toJSON(); };", - True, - "dictionary containing a non-JSON type should not be a JSON type", - ) - - doTest( - "interface Foo : InterfaceWithoutToJSON { }; " - "interface Test { Foo toJSON(); };", - True, - "interface without toJSON should not be a JSON type", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py b/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py deleted file mode 100644 index 7becfdca1f3..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_treatNonCallableAsNull.py +++ /dev/null @@ -1,80 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - [TreatNonCallableAsNull] callback Function = any(any... arguments); - - interface TestTreatNonCallableAsNull1 { - attribute Function? onfoo; - attribute Function onbar; - }; - """ - ) - - results = parser.finish() - - iface = results[1] - attr = iface.members[0] - harness.check(attr.type.treatNonCallableAsNull(), True, "Got the expected value") - attr = iface.members[1] - harness.check(attr.type.treatNonCallableAsNull(), False, "Got the expected value") - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - callback Function = any(any... arguments); - - interface TestTreatNonCallableAsNull2 { - [TreatNonCallableAsNull] attribute Function onfoo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - callback Function = any(any... arguments); - - [TreatNonCallableAsNull] - interface TestTreatNonCallableAsNull3 { - attribute Function onfoo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - - threw = False - try: - parser.parse( - """ - [TreatNonCallableAsNull, LegacyTreatNonObjectAsNull] - callback Function = any(any... arguments); - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_typedef.py b/components/script/dom/bindings/codegen/parser/tests/test_typedef.py deleted file mode 100644 index c19d064efff..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_typedef.py +++ /dev/null @@ -1,94 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - typedef long mylong; - typedef long? mynullablelong; - interface Foo { - const mylong X = 5; - undefined foo(optional mynullablelong arg = 7); - undefined bar(optional mynullablelong arg = null); - undefined baz(mylong arg); - }; - """ - ) - - results = parser.finish() - - harness.check( - results[2].members[1].signatures()[0][1][0].type.name, - "LongOrNull", - "Should expand typedefs", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef long? mynullablelong; - interface Foo { - undefined foo(mynullablelong? Y); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown on nullable inside nullable arg.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - typedef long? mynullablelong; - interface Foo { - const mynullablelong? X = 5; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown on nullable inside nullable const.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Foo { - const mynullablelong? X = 5; - }; - typedef long? mynullablelong; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown on nullable inside nullable const typedef " - "after interface.", - ) - - parser = parser.reset() - parser.parse( - """ - interface Foo { - const mylong X = 5; - }; - typedef long mylong; - """ - ) - - results = parser.finish() - - harness.check( - results[0].members[0].type.name, - "Long", - "Should expand typedefs that come before interface", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py b/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py deleted file mode 100644 index 2aab3a8a91f..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_typedef_identifier_conflict.py +++ /dev/null @@ -1,19 +0,0 @@ -def WebIDLTest(parser, harness): - exception = None - try: - parser.parse( - """ - typedef long foo; - typedef long foo; - """ - ) - - results = parser.finish() - except Exception as e: - exception = e - - harness.ok(exception, "Should have thrown.") - harness.ok( - "Multiple unresolvable definitions of identifier 'foo'" in str(exception), - "Should have a sane exception message", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_undefined.py b/components/script/dom/bindings/codegen/parser/tests/test_undefined.py deleted file mode 100644 index 4731ee1bcd7..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_undefined.py +++ /dev/null @@ -1,246 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - try: - parser.parse( - """ - dictionary Dict { - undefined undefinedMember; - double bar; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "undefined must not be used as the type of a dictionary member") - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - dictionary Dict { - (undefined or double) undefinedMemberOfUnionInDict; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of a dictionary member, " - "whether directly or in a union", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - double bar(undefined foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a regular operation)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - getter double(undefined name); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a getter)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - setter undefined(DOMString name, undefined value); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a setter)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - deleter undefined (undefined name); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a deleter)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - constructor (undefined foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a constructor)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - callback Callback = undefined (undefined foo); - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a callback)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - async iterable(undefined name); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of an async iterable " - "iterator)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - static double bar(undefined foo); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined must not be used as the type of an argument in any " - "circumstance (so not as the argument of a static operation)", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - const undefined FOO = undefined; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined is not a valid type for a constant", - ) - - parser = parser.reset() - threw = False - - try: - parser.parse( - """ - interface Foo { - const any FOO = undefined; - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "undefined is not a valid value for a constant", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py b/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py deleted file mode 100644 index b024d317492..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_unenumerable_own_properties.py +++ /dev/null @@ -1,71 +0,0 @@ -def WebIDLTest(parser, harness): - - parser.parse( - """ - interface Foo {}; - [LegacyUnenumerableNamedProperties] - interface Bar : Foo { - getter long(DOMString name); - }; - interface Baz : Bar { - getter long(DOMString name); - }; - """ - ) - results = parser.finish() - harness.check(len(results), 3, "Should have three interfaces") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyUnenumerableNamedProperties] - interface NoNamedGetter { - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyUnenumerableNamedProperties=Foo] - interface ShouldNotHaveArg { - getter long(DOMString name); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - [LegacyUnenumerableNamedProperties] - interface Foo { - getter long(DOMString name); - }; - interface Bar : Foo {}; - [LegacyUnenumerableNamedProperties] - interface Baz : Bar { - getter long(DOMString name); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py b/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py deleted file mode 100644 index 500d123ddb2..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py +++ /dev/null @@ -1,311 +0,0 @@ -def WebIDLTest(parser, harness): - parser.parse( - """ - interface Child : Parent { - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - harness.check( - len(results), - 2, - "Should be able to inherit from an interface with " - "[LegacyUnforgeable] properties.", - ) - - parser = parser.reset() - parser.parse( - """ - interface Child : Parent { - const short foo = 10; - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - harness.check( - len(results), - 2, - "Should be able to inherit from an interface with " - "[LegacyUnforgeable] properties even if we have a constant with " - "the same name.", - ) - - parser = parser.reset() - parser.parse( - """ - interface Child : Parent { - static attribute short foo; - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - harness.check( - len(results), - 2, - "Should be able to inherit from an interface with " - "[LegacyUnforgeable] properties even if we have a static attribute " - "with the same name.", - ) - - parser = parser.reset() - parser.parse( - """ - interface Child : Parent { - static undefined foo(); - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - harness.check( - len(results), - 2, - "Should be able to inherit from an interface with " - "[LegacyUnforgeable] properties even if we have a static operation " - "with the same name.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - undefined foo(); - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should have thrown when shadowing unforgeable attribute on " - "parent with operation.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - undefined foo(); - }; - interface Parent { - [LegacyUnforgeable] undefined foo(); - }; - """ - ) - - results = parser.finish() - except: - threw = True - harness.ok( - threw, - "Should have thrown when shadowing unforgeable operation on " - "parent with operation.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - attribute short foo; - }; - interface Parent { - [LegacyUnforgeable] readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, - "Should have thrown when shadowing unforgeable attribute on " - "parent with attribute.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - attribute short foo; - }; - interface Parent { - [LegacyUnforgeable] undefined foo(); - }; - """ - ) - - results = parser.finish() - except Exception as x: - threw = True - harness.ok( - threw, - "Should have thrown when shadowing unforgeable operation on " - "parent with attribute.", - ) - - parser = parser.reset() - parser.parse( - """ - interface Child : Parent { - }; - interface Parent {}; - interface mixin Mixin { - [LegacyUnforgeable] readonly attribute long foo; - }; - Parent includes Mixin; - """ - ) - - results = parser.finish() - harness.check( - len(results), - 4, - "Should be able to inherit from an interface with a " - "mixin with [LegacyUnforgeable] properties.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - undefined foo(); - }; - interface Parent {}; - interface mixin Mixin { - [LegacyUnforgeable] readonly attribute long foo; - }; - Parent includes Mixin; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown when shadowing unforgeable attribute " - "of parent's consequential interface.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - }; - interface Parent : GrandParent {}; - interface GrandParent {}; - interface mixin Mixin { - [LegacyUnforgeable] readonly attribute long foo; - }; - GrandParent includes Mixin; - interface mixin ChildMixin { - undefined foo(); - }; - Child includes ChildMixin; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown when our consequential interface shadows unforgeable attribute " - "of ancestor's consequential interface.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface Child : Parent { - }; - interface Parent : GrandParent {}; - interface GrandParent {}; - interface mixin Mixin { - [LegacyUnforgeable] undefined foo(); - }; - GrandParent includes Mixin; - interface mixin ChildMixin { - undefined foo(); - }; - Child includes ChildMixin; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown when our consequential interface shadows unforgeable operation " - "of ancestor's consequential interface.", - ) - - parser = parser.reset() - parser.parse( - """ - interface iface { - [LegacyUnforgeable] attribute long foo; - }; - """ - ) - - results = parser.finish() - harness.check( - len(results), 1, "Should allow writable [LegacyUnforgeable] attribute." - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface iface { - [LegacyUnforgeable] static readonly attribute long foo; - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown for static [LegacyUnforgeable] attribute.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union.py b/components/script/dom/bindings/codegen/parser/tests/test_union.py deleted file mode 100644 index 7fc1236d54e..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_union.py +++ /dev/null @@ -1,198 +0,0 @@ -import WebIDL -import itertools -import string - -# We'd like to use itertools.chain but it's 2.6 or higher. - - -def chain(*iterables): - # chain('ABC', 'DEF') --> A B C D E F - for it in iterables: - for element in it: - yield element - - -# We'd like to use itertools.combinations but it's 2.6 or higher. -def combinations(iterable, r): - # combinations('ABCD', 2) --> AB AC AD BC BD CD - # combinations(range(4), 3) --> 012 013 023 123 - pool = tuple(iterable) - n = len(pool) - if r > n: - return - indices = list(range(r)) - yield tuple(pool[i] for i in indices) - while True: - for i in reversed(range(r)): - if indices[i] != i + n - r: - break - else: - return - indices[i] += 1 - for j in range(i + 1, r): - indices[j] = indices[j - 1] + 1 - yield tuple(pool[i] for i in indices) - - -# We'd like to use itertools.combinations_with_replacement but it's 2.7 or -# higher. -def combinations_with_replacement(iterable, r): - # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC - pool = tuple(iterable) - n = len(pool) - if not n and r: - return - indices = [0] * r - yield tuple(pool[i] for i in indices) - while True: - for i in reversed(range(r)): - if indices[i] != n - 1: - break - else: - return - indices[i:] = [indices[i] + 1] * (r - i) - yield tuple(pool[i] for i in indices) - - -def WebIDLTest(parser, harness): - types = [ - "float", - "double", - "short", - "unsigned short", - "long", - "unsigned long", - "long long", - "unsigned long long", - "boolean", - "byte", - "octet", - "DOMString", - "ByteString", - "USVString", - # "sequence<float>", - "object", - "ArrayBuffer", - # "Date", - "TestInterface1", - "TestInterface2", - ] - - testPre = """ - interface TestInterface1 { - }; - interface TestInterface2 { - }; - """ - - interface = ( - testPre - + """ - interface PrepareForTest { - """ - ) - for (i, type) in enumerate(types): - interface += string.Template( - """ - readonly attribute ${type} attr${i}; - """ - ).substitute(i=i, type=type) - interface += """ - }; - """ - - parser.parse(interface) - results = parser.finish() - - iface = results[2] - - parser = parser.reset() - - def typesAreDistinguishable(t): - return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) - - def typesAreNotDistinguishable(t): - return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2)) - - def unionTypeName(t): - if len(t) > 2: - t[0:2] = [unionTypeName(t[0:2])] - return "(" + " or ".join(t) + ")" - - # typeCombinations is an iterable of tuples containing the name of the type - # as a string and the parsed IDL type. - def unionTypes(typeCombinations, predicate): - for c in typeCombinations: - if predicate(t[1] for t in c): - yield unionTypeName([t[0] for t in c]) - - # We limit invalid union types with a union member type to the subset of 3 - # types with one invalid combination. - # typeCombinations is an iterable of tuples containing the name of the type - # as a string and the parsed IDL type. - def invalidUnionWithUnion(typeCombinations): - for c in typeCombinations: - if ( - typesAreNotDistinguishable((c[0][1], c[1][1])) - and typesAreDistinguishable((c[1][1], c[2][1])) - and typesAreDistinguishable((c[0][1], c[2][1])) - ): - yield unionTypeName([t[0] for t in c]) - - # Create a list of tuples containing the name of the type as a string and - # the parsed IDL type. - types = zip(types, (a.type for a in iface.members)) - - validUnionTypes = chain( - unionTypes(combinations(types, 2), typesAreDistinguishable), - unionTypes(combinations(types, 3), typesAreDistinguishable), - ) - invalidUnionTypes = chain( - unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable), - invalidUnionWithUnion(combinations(types, 3)), - ) - interface = ( - testPre - + """ - interface TestUnion { - """ - ) - for (i, type) in enumerate(validUnionTypes): - interface += string.Template( - """ - undefined method${i}(${type} arg); - ${type} returnMethod${i}(); - attribute ${type} attr${i}; - undefined optionalMethod${i}(${type}? arg); - """ - ).substitute(i=i, type=type) - interface += """ - }; - """ - parser.parse(interface) - results = parser.finish() - - parser = parser.reset() - - for invalid in invalidUnionTypes: - interface = ( - testPre - + string.Template( - """ - interface TestUnion { - undefined method(${type} arg); - }; - """ - ).substitute(type=invalid) - ) - - threw = False - try: - parser.parse(interface) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") - - parser = parser.reset() diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union_any.py b/components/script/dom/bindings/codegen/parser/tests/test_union_any.py deleted file mode 100644 index caba44b55f9..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_union_any.py +++ /dev/null @@ -1,16 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface AnyNotInUnion { - undefined foo((any or DOMString) arg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py b/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py deleted file mode 100644 index d15ed4cfb54..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_union_nullable.py +++ /dev/null @@ -1,60 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface OneNullableInUnion { - undefined foo((object? or DOMString?) arg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Two nullable member types of a union should have thrown.") - - parser.reset() - threw = False - - try: - parser.parse( - """ - interface NullableInNullableUnion { - undefined foo((object? or DOMString)? arg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "A nullable union type with a nullable member type should have " "thrown.", - ) - - parser.reset() - threw = False - - try: - parser.parse( - """ - interface NullableInUnionNullableUnionHelper { - }; - interface NullableInUnionNullableUnion { - undefined foo(((object? or DOMString) or NullableInUnionNullableUnionHelper)? arg); - }; - """ - ) - - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "A nullable union type with a nullable member type should have " "thrown.", - ) diff --git a/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py b/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py deleted file mode 100644 index effede391cb..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: UTF-8 -*- - -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - interface TestUSVString { - attribute USVString svs; - }; - """ - ) - - results = parser.finish() - - harness.check(len(results), 1, "Should be one production") - harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") - iface = results[0] - harness.check( - iface.identifier.QName(), "::TestUSVString", "Interface has the right QName" - ) - harness.check( - iface.identifier.name, "TestUSVString", "Interface has the right name" - ) - harness.check(iface.parent, None, "Interface has no parent") - - members = iface.members - harness.check(len(members), 1, "Should be one member") - - attr = members[0] - harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") - harness.check( - attr.identifier.QName(), "::TestUSVString::svs", "Attr has correct QName" - ) - harness.check(attr.identifier.name, "svs", "Attr has correct name") - harness.check(str(attr.type), "USVString", "Attr type is the correct name") - harness.ok(attr.type.isUSVString(), "Should be USVString type") - harness.ok(attr.type.isString(), "Should be String collective type") - harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py b/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py deleted file mode 100644 index 3fd3dccd37a..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_variadic_callback.py +++ /dev/null @@ -1,13 +0,0 @@ -import WebIDL - - -def WebIDLTest(parser, harness): - parser.parse( - """ - callback TestVariadicCallback = any(any... arguments); - """ - ) - - results = parser.finish() - - harness.ok(True, "TestVariadicCallback callback parsed without error.") diff --git a/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py b/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py deleted file mode 100644 index 06ce09d8236..00000000000 --- a/components/script/dom/bindings/codegen/parser/tests/test_variadic_constraints.py +++ /dev/null @@ -1,74 +0,0 @@ -def WebIDLTest(parser, harness): - threw = False - try: - parser.parse( - """ - interface VariadicConstraints1 { - undefined foo(byte... arg1, byte arg2); - }; - """ - ) - results = parser.finish() - - except: - threw = True - - harness.ok( - threw, - "Should have thrown on variadic argument followed by required " "argument.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface VariadicConstraints2 { - undefined foo(byte... arg1, optional byte arg2); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok( - threw, - "Should have thrown on variadic argument followed by optional " "argument.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface VariadicConstraints3 { - undefined foo(optional byte... arg1); - }; - """ - ) - results = parser.finish() - - except: - threw = True - - harness.ok( - threw, - "Should have thrown on variadic argument explicitly flagged as " "optional.", - ) - - parser = parser.reset() - threw = False - try: - parser.parse( - """ - interface VariadicConstraints4 { - undefined foo(byte... arg1 = 0); - }; - """ - ) - results = parser.finish() - except: - threw = True - - harness.ok(threw, "Should have thrown on variadic argument with default value.") diff --git a/components/script/dom/bindings/codegen/parser/union-typedef.patch b/components/script/dom/bindings/codegen/parser/union-typedef.patch deleted file mode 100644 index 20efea8e129..00000000000 --- a/components/script/dom/bindings/codegen/parser/union-typedef.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- WebIDL.py -+++ WebIDL.py -@@ -2624,10 +2624,18 @@ class IDLUnionType(IDLType): - return type.name - - for (i, type) in enumerate(self.memberTypes): -- if not type.isComplete(): -+ # 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): -+ if not type.isComplete(): -+ self.memberTypes[i] = type.complete(scope) -+ - self.flatMemberTypes = list(self.memberTypes) - i = 0 - while i < len(self.flatMemberTypes): diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh deleted file mode 100755 index cec4d6a378e..00000000000 --- a/components/script/dom/bindings/codegen/parser/update.sh +++ /dev/null @@ -1,13 +0,0 @@ -wget https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/bindings/parser/WebIDL.py -O WebIDL.py -patch < abstract.patch -patch < debug.patch -patch < callback-location.patch -patch < union-typedef.patch -patch < inline.patch -patch < readable-stream.patch - -wget https://hg.mozilla.org/mozilla-central/archive/tip.zip/dom/bindings/parser/tests/ -O tests.zip -rm -r tests -mkdir tests -unzip -d tests -j tests.zip -rm tests.zip WebIDL.py.orig |