Sync WebIDL.py with gecko

This commit is contained in:
Kagami Sascha Rosylight 2019-07-11 13:16:10 +09:00
parent 5fdc7c0d2c
commit 56f31c85ef
35 changed files with 727 additions and 221 deletions

View file

@ -1,16 +1,18 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
""" A WebIDL parser. """ """ A WebIDL parser. """
from __future__ import print_function
from ply import lex, yacc from ply import lex, yacc
import re import re
import os import os
import traceback import traceback
import math import math
import string import string
from collections import defaultdict from collections import defaultdict, OrderedDict
from itertools import chain
# Machinery # Machinery
@ -40,32 +42,22 @@ def parseInt(literal):
return value * sign return value * sign
# Magic for creating enums
def M_add_class_attribs(attribs, start):
def foo(name, bases, dict_):
for v, k in enumerate(attribs):
dict_[k] = start + v
assert 'length' not in dict_
dict_['length'] = start + len(attribs)
return type(name, bases, dict_)
return foo
def enum(*names, **kw): def enum(*names, **kw):
if len(kw) == 1: class Foo(object):
base = kw['base'].__class__ attrs = OrderedDict()
start = base.length def __init__(self, names):
else: for v, k in enumerate(names):
assert len(kw) == 0 self.attrs[k] = v
base = object def __getattr__(self, attr):
start = 0 if attr in self.attrs:
return self.attrs[attr]
class Foo(base): raise AttributeError
__metaclass__ = M_add_class_attribs(names, start)
def __setattr__(self, name, value): # this makes it read-only def __setattr__(self, name, value): # this makes it read-only
raise NotImplementedError raise NotImplementedError
return Foo()
if "base" not in kw:
return Foo(names)
return Foo(chain(kw["base"].attrs.keys(), names))
class WebIDLError(Exception): class WebIDLError(Exception):
@ -482,9 +474,6 @@ class IDLExposureMixins():
def isExposedOnMainThread(self): def isExposedOnMainThread(self):
return self.isExposedInWindow() return self.isExposedInWindow()
def isExposedOffMainThread(self):
return len(self.exposureSet - {'Window', 'FakeTestPrimaryGlobal'}) > 0
def isExposedInAnyWorker(self): def isExposedInAnyWorker(self):
return len(self.getWorkerExposureSet()) > 0 return len(self.getWorkerExposureSet()) > 0
@ -568,6 +557,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def isNavigatorProperty(self): def isNavigatorProperty(self):
return False return False
def isSerializable(self):
return False
def _getDependentObjects(self): def _getDependentObjects(self):
return set() return set()
@ -704,6 +696,7 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
# outputs the constructs in the order that namedConstructors enumerates # outputs the constructs in the order that namedConstructors enumerates
# them. # them.
self.namedConstructors = list() self.namedConstructors = list()
self.legacyWindowAliases = []
self.implementedInterfaces = set() self.implementedInterfaces = set()
self._consequential = False self._consequential = False
self._isKnownNonPartial = False self._isKnownNonPartial = False
@ -774,6 +767,16 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
IDLExposureMixins.finish(self, scope) IDLExposureMixins.finish(self, scope)
if len(self.legacyWindowAliases) > 0:
if not self.hasInterfaceObject():
raise WebIDLError("Interface %s unexpectedly has [LegacyWindowAlias] "
"and [NoInterfaceObject] 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])
# Now go ahead and merge in our partial interfaces. # Now go ahead and merge in our partial interfaces.
for partial in self._partialInterfaces: for partial in self._partialInterfaces:
partial.finish(scope) partial.finish(scope)
@ -962,7 +965,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
# self.members. Sort our consequential interfaces by name # self.members. Sort our consequential interfaces by name
# just so we have a consistent order. # just so we have a consistent order.
for iface in sorted(self.getConsequentialInterfaces(), for iface in sorted(self.getConsequentialInterfaces(),
cmp=cmp,
key=lambda x: x.identifier.name): key=lambda x: x.identifier.name):
# Flag the interface as being someone's consequential interface # Flag the interface as being someone's consequential interface
iface.setIsConsequentialInterfaceOf(self) iface.setIsConsequentialInterfaceOf(self)
@ -1325,6 +1327,7 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
for bindingAlias in member.bindingAliases: for bindingAlias in member.bindingAliases:
checkDuplicateNames(member, bindingAlias, "BindingAlias") checkDuplicateNames(member, bindingAlias, "BindingAlias")
# Conditional exposure makes no sense for interfaces with no # Conditional exposure makes no sense for interfaces with no
# interface object, unless they're navigator properties. # interface object, unless they're navigator properties.
# And SecureContext makes sense for interfaces with no interface object, # And SecureContext makes sense for interfaces with no interface object,
@ -1640,6 +1643,11 @@ class IDLInterface(IDLInterfaceOrNamespace):
raise WebIDLError(str(identifier) + " must take no arguments", raise WebIDLError(str(identifier) + " must take no arguments",
[attr.location]) [attr.location])
if self.globalNames:
raise WebIDLError("[%s] must not be specified together with "
"[Global]" % identifier,
[self.location, attr.location])
args = attr.args() if attr.hasArgs() else [] args = attr.args() if attr.hasArgs() else []
retType = IDLWrapperType(self.location, self) retType = IDLWrapperType(self.location, self)
@ -1700,6 +1708,10 @@ class IDLInterface(IDLInterfaceOrNamespace):
"an interface with inherited interfaces", "an interface with inherited interfaces",
[attr.location, self.location]) [attr.location, self.location])
elif identifier == "Global": elif identifier == "Global":
if self.ctor() or self.namedConstructors:
raise WebIDLError("[Global] cannot be specified on an "
"interface with a constructor",
[attr.location, self.location]);
if attr.hasValue(): if attr.hasValue():
self.globalNames = [attr.value()] self.globalNames = [attr.value()]
elif attr.hasArgs(): elif attr.hasArgs():
@ -1723,6 +1735,18 @@ class IDLInterface(IDLInterfaceOrNamespace):
self.parentScope.addIfaceGlobalNames(self.identifier.name, self.parentScope.addIfaceGlobalNames(self.identifier.name,
[self.identifier.name]) [self.identifier.name])
self._isOnGlobalProtoChain = True 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": elif identifier == "SecureContext":
if not attr.noArguments(): if not attr.noArguments():
raise WebIDLError("[%s] must take no arguments" % identifier, raise WebIDLError("[%s] must take no arguments" % identifier,
@ -1744,6 +1768,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "LegacyUnenumerableNamedProperties" or identifier == "LegacyUnenumerableNamedProperties" or
identifier == "RunConstructorInCallerCompartment" or identifier == "RunConstructorInCallerCompartment" or
identifier == "WantsEventListenerHooks" or identifier == "WantsEventListenerHooks" or
identifier == "Serializable" or
identifier == "Abstract" or identifier == "Abstract" or
identifier == "Inline"): identifier == "Inline"):
# Known extended attributes that do not take values # Known extended attributes that do not take values
@ -1770,6 +1795,19 @@ class IDLInterface(IDLInterfaceOrNamespace):
attrlist = attr.listValue() attrlist = attr.listValue()
self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True 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")
class IDLNamespace(IDLInterfaceOrNamespace): class IDLNamespace(IDLInterfaceOrNamespace):
def __init__(self, location, parentScope, name, members, isKnownNonPartial): def __init__(self, location, parentScope, name, members, isKnownNonPartial):
@ -1805,7 +1843,9 @@ class IDLNamespace(IDLInterfaceOrNamespace):
if not attr.noArguments(): if not attr.noArguments():
raise WebIDLError("[%s] must not have arguments" % identifier, raise WebIDLError("[%s] must not have arguments" % identifier,
[attr.location]) [attr.location])
elif identifier == "Pref" or identifier == "Func": elif (identifier == "Pref" or
identifier == "HeaderFile" or
identifier == "Func"):
# Known extended attributes that take a string value # Known extended attributes that take a string value
if not attr.hasValue(): if not attr.hasValue():
raise WebIDLError("[%s] must have a value" % identifier, raise WebIDLError("[%s] must have a value" % identifier,
@ -1818,6 +1858,9 @@ class IDLNamespace(IDLInterfaceOrNamespace):
attrlist = attr.listValue() attrlist = attr.listValue()
self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
def isSerializable(self):
return False
class IDLDictionary(IDLObjectWithScope): class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members): def __init__(self, location, parentScope, name, parent, members):
@ -1877,7 +1920,7 @@ class IDLDictionary(IDLObjectWithScope):
assert member.type.isComplete() assert member.type.isComplete()
# Members of a dictionary are sorted in lexicographic order # Members of a dictionary are sorted in lexicographic order
self.members.sort(cmp=cmp, key=lambda x: x.identifier.name) self.members.sort(key=lambda x: x.identifier.name)
inheritedMembers = [] inheritedMembers = []
ancestor = self.parent ancestor = self.parent
@ -2232,7 +2275,7 @@ class IDLUnresolvedType(IDLType):
assert obj assert obj
if obj.isType(): if obj.isType():
print obj print(obj)
assert not obj.isType() assert not obj.isType()
if obj.isTypedef(): if obj.isTypedef():
assert self.name.name == obj.identifier.name assert self.name.name == obj.identifier.name
@ -3562,8 +3605,6 @@ class IDLNullValue(IDLObject):
def coerceToType(self, type, location): def coerceToType(self, type, location):
if (not isinstance(type, IDLNullableType) and if (not isinstance(type, IDLNullableType) and
not (type.isUnion() and type.hasNullableType) and not (type.isUnion() and type.hasNullableType) and
not (type.isUnion() and type.hasDictionaryType()) and
not type.isDictionary() and
not type.isAny()): not type.isAny()):
raise WebIDLError("Cannot coerce null value to type %s." % type, raise WebIDLError("Cannot coerce null value to type %s." % type,
[location]) [location])
@ -3612,6 +3653,35 @@ class IDLEmptySequenceValue(IDLObject):
return set() 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): class IDLUndefinedValue(IDLObject):
def __init__(self, location): def __init__(self, location):
IDLObject.__init__(self, location) IDLObject.__init__(self, location)
@ -3689,7 +3759,7 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
def finish(self, scope): def finish(self, scope):
# We better be exposed _somewhere_. # We better be exposed _somewhere_.
if (len(self._exposureGlobalNames) == 0): if (len(self._exposureGlobalNames) == 0):
print self.identifier.name print(self.identifier.name)
assert len(self._exposureGlobalNames) != 0 assert len(self._exposureGlobalNames) != 0
IDLExposureMixins.finish(self, scope) IDLExposureMixins.finish(self, scope)
@ -4577,7 +4647,9 @@ class IDLArgument(IDLObjectWithIdentifier):
elif identifier == "TreatNonCallableAsNull": elif identifier == "TreatNonCallableAsNull":
self._allowTreatNonCallableAsNull = True self._allowTreatNonCallableAsNull = True
elif (self.dictionaryMember and elif (self.dictionaryMember and
(identifier == "ChromeOnly" or identifier == "Func")): (identifier == "ChromeOnly" or
identifier == "Func" or
identifier == "Pref")):
if not self.optional: if not self.optional:
raise WebIDLError("[%s] must not be used on a required " raise WebIDLError("[%s] must not be used on a required "
"dictionary member" % identifier, "dictionary member" % identifier,
@ -4609,14 +4681,7 @@ class IDLArgument(IDLObjectWithIdentifier):
assert not isinstance(type.name, IDLUnresolvedIdentifier) assert not isinstance(type.name, IDLUnresolvedIdentifier)
self.type = type self.type = type
if ((self.type.isDictionary() or if self.type.isAny():
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
self.optional and not self.defaultValue and not self.variadic and
not self.dictionaryMember):
# Default optional non-variadic dictionary arguments to null,
# for simplicity, so the codegen doesn't have to special-case this.
self.defaultValue = IDLNullValue(self.location)
elif self.type.isAny():
assert (self.defaultValue is None or assert (self.defaultValue is None or
isinstance(self.defaultValue, IDLNullValue)) isinstance(self.defaultValue, IDLNullValue))
# optional 'any' values always have a default value # optional 'any' values always have a default value
@ -4648,7 +4713,7 @@ class IDLArgument(IDLObjectWithIdentifier):
class IDLCallback(IDLObjectWithScope): class IDLCallback(IDLObjectWithScope):
def __init__(self, location, parentScope, identifier, returnType, arguments): def __init__(self, location, parentScope, identifier, returnType, arguments, isConstructor):
assert isinstance(returnType, IDLType) assert isinstance(returnType, IDLType)
self._returnType = returnType self._returnType = returnType
@ -4663,10 +4728,15 @@ class IDLCallback(IDLObjectWithScope):
self._treatNonCallableAsNull = False self._treatNonCallableAsNull = False
self._treatNonObjectAsNull = False self._treatNonObjectAsNull = False
self._isRunScriptBoundary = False
self._isConstructor = isConstructor
def isCallback(self): def isCallback(self):
return True return True
def isConstructor(self):
return self._isConstructor
def signatures(self): def signatures(self):
return [(self._returnType, self._arguments)] return [(self._returnType, self._arguments)]
@ -4699,7 +4769,16 @@ class IDLCallback(IDLObjectWithScope):
if attr.identifier() == "TreatNonCallableAsNull": if attr.identifier() == "TreatNonCallableAsNull":
self._treatNonCallableAsNull = True self._treatNonCallableAsNull = True
elif attr.identifier() == "TreatNonObjectAsNull": elif attr.identifier() == "TreatNonObjectAsNull":
if self._isConstructor:
raise WebIDLError("[TreatNonObjectAsNull] is not supported "
"on constructors", [self.location])
self._treatNonObjectAsNull = True 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: else:
unhandledAttrs.append(attr) unhandledAttrs.append(attr)
if self._treatNonCallableAsNull and self._treatNonObjectAsNull: if self._treatNonCallableAsNull and self._treatNonObjectAsNull:
@ -4711,6 +4790,9 @@ class IDLCallback(IDLObjectWithScope):
def _getDependentObjects(self): def _getDependentObjects(self):
return set([self._returnType] + self._arguments) return set([self._returnType] + self._arguments)
def isRunScriptBoundary(self):
return self._isRunScriptBoundary;
class IDLCallbackType(IDLType): class IDLCallbackType(IDLType):
def __init__(self, location, callback): def __init__(self, location, callback):
@ -4757,6 +4839,9 @@ class IDLMethodOverload:
deps.add(self.returnType) deps.add(self.returnType)
return deps return deps
def includesRestrictedFloatArgument(self):
return any(arg.type.includesRestrictedFloat() for arg in self.arguments)
class IDLMethod(IDLInterfaceMember, IDLScope): class IDLMethod(IDLInterfaceMember, IDLScope):
@ -4929,6 +5014,21 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert len(method._overloads) == 1 assert len(method._overloads) == 1
if self._extendedAttrDict != method._extendedAttrDict: 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 " raise WebIDLError("Extended attributes differ on different "
"overloads of %s" % method.identifier, "overloads of %s" % method.identifier,
[self.location, method.location]) [self.location, method.location])
@ -5039,6 +5139,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
"must be optional", "must be optional",
[argument.location]) [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 # An argument cannot be a Nullable Dictionary
if argument.type.nullable(): if argument.type.nullable():
raise WebIDLError("An argument cannot be a nullable " raise WebIDLError("An argument cannot be a nullable "
@ -5162,12 +5271,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
[attr.location, self.location]) [attr.location, self.location])
elif identifier == "LenientFloat": elif identifier == "LenientFloat":
# This is called before we've done overload resolution # This is called before we've done overload resolution
assert len(self.signatures()) == 1 overloads = self._overloads
sig = self.signatures()[0] assert len(overloads) == 1
if not sig[0].isVoid(): if not overloads[0].returnType.isVoid():
raise WebIDLError("[LenientFloat] used on a non-void method", raise WebIDLError("[LenientFloat] used on a non-void method",
[attr.location, self.location]) [attr.location, self.location])
if not any(arg.type.includesRestrictedFloat() for arg in sig[1]): if not overloads[0].includesRestrictedFloatArgument():
raise WebIDLError("[LenientFloat] used on an operation with no " raise WebIDLError("[LenientFloat] used on an operation with no "
"restricted float type arguments", "restricted float type arguments",
[attr.location, self.location]) [attr.location, self.location])
@ -5238,7 +5347,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if self.signatures()[0][0] != BuiltinTypes[IDLBuiltinType.Types.object]: if self.signatures()[0][0] != BuiltinTypes[IDLBuiltinType.Types.object]:
raise WebIDLError("The return type of the default toJSON " raise WebIDLError("The return type of the default toJSON "
"operation must be 'object'", "operation must be 'object'",
[attr.location, self.location]); [attr.location, self.location])
elif (identifier == "Throws" or elif (identifier == "Throws" or
identifier == "CanOOM" or identifier == "CanOOM" or
identifier == "NewObject" or identifier == "NewObject" or
@ -5251,7 +5360,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
identifier == "NeedsSubjectPrincipal" or identifier == "NeedsSubjectPrincipal" or
identifier == "NeedsCallerType" or identifier == "NeedsCallerType" or
identifier == "StaticClassOverride" or identifier == "StaticClassOverride" or
identifier == "NonEnumerable"): identifier == "NonEnumerable" or
identifier == "Unexposed"):
# Known attributes that we don't need to do anything with here # Known attributes that we don't need to do anything with here
pass pass
else: else:
@ -5478,6 +5588,7 @@ class Tokenizer(object):
"iterable": "ITERABLE", "iterable": "ITERABLE",
"namespace": "NAMESPACE", "namespace": "NAMESPACE",
"ReadableStream": "READABLESTREAM", "ReadableStream": "READABLESTREAM",
"constructor": "CONSTRUCTOR",
} }
tokens.extend(keywords.values()) tokens.extend(keywords.values())
@ -5604,6 +5715,7 @@ class Parser(Tokenizer):
def p_CallbackRestOrInterface(self, p): def p_CallbackRestOrInterface(self, p):
""" """
CallbackRestOrInterface : CallbackRest CallbackRestOrInterface : CallbackRest
| CallbackConstructorRest
| Interface | Interface
""" """
assert p[1] assert p[1]
@ -5637,7 +5749,7 @@ class Parser(Tokenizer):
[location, existingObj.location]) [location, existingObj.location])
existingObj.setNonPartial(*nonPartialArgs) existingObj.setNonPartial(*nonPartialArgs)
return existingObj return existingObj
except Exception, ex: except Exception as ex:
if isinstance(ex, WebIDLError): if isinstance(ex, WebIDLError):
raise ex raise ex
pass pass
@ -5675,7 +5787,7 @@ class Parser(Tokenizer):
"%s and %s" % (identifier.name, p[0]), "%s and %s" % (identifier.name, p[0]),
[location, p[0].location]) [location, p[0].location])
return return
except Exception, ex: except Exception as ex:
if isinstance(ex, WebIDLError): if isinstance(ex, WebIDLError):
raise ex raise ex
pass pass
@ -5739,7 +5851,7 @@ class Parser(Tokenizer):
"non-%s object" % "non-%s object" %
(prettyname, prettyname), (prettyname, prettyname),
[location, nonPartialObject.location]) [location, nonPartialObject.location])
except Exception, ex: except Exception as ex:
if isinstance(ex, WebIDLError): if isinstance(ex, WebIDLError):
raise ex raise ex
pass pass
@ -5905,12 +6017,23 @@ class Parser(Tokenizer):
""" """
DefaultValue : ConstValue DefaultValue : ConstValue
| LBRACKET RBRACKET | LBRACKET RBRACKET
| LBRACE RBRACE
""" """
if len(p) == 2: if len(p) == 2:
p[0] = p[1] p[0] = p[1]
else: else:
assert len(p) == 3 # Must be [] assert len(p) == 3 # Must be [] or {}
if p[1] == "[":
p[0] = IDLEmptySequenceValue(self.getLocation(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_Exception(self, p): def p_Exception(self, p):
""" """
@ -5967,7 +6090,15 @@ class Parser(Tokenizer):
""" """
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
p[0] = IDLCallback(self.getLocation(p, 1), self.globalScope(), p[0] = IDLCallback(self.getLocation(p, 1), self.globalScope(),
identifier, p[3], p[5]) identifier, p[3], p[5], isConstructor=False)
def p_CallbackConstructorRest(self, p):
"""
CallbackConstructorRest : CONSTRUCTOR IDENTIFIER EQUALS ReturnType 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): def p_ExceptionMembers(self, p):
""" """
@ -6041,12 +6172,6 @@ class Parser(Tokenizer):
stringType = BuiltinTypes[IDLBuiltinType.Types.domstring] stringType = BuiltinTypes[IDLBuiltinType.Types.domstring]
p[0] = IDLValue(location, stringType, p[1]) p[0] = IDLValue(location, stringType, p[1])
def p_ConstValueNull(self, p):
"""
ConstValue : NULL
"""
p[0] = IDLNullValue(self.getLocation(p, 1))
def p_BooleanLiteralTrue(self, p): def p_BooleanLiteralTrue(self, p):
""" """
BooleanLiteral : TRUE BooleanLiteral : TRUE
@ -6442,6 +6567,7 @@ class Parser(Tokenizer):
| ATTRIBUTE | ATTRIBUTE
| CALLBACK | CALLBACK
| CONST | CONST
| CONSTRUCTOR
| DELETER | DELETER
| DICTIONARY | DICTIONARY
| ENUM | ENUM
@ -6566,6 +6692,7 @@ class Parser(Tokenizer):
| BYTE | BYTE
| LEGACYCALLER | LEGACYCALLER
| CONST | CONST
| CONSTRUCTOR
| DELETER | DELETER
| DOUBLE | DOUBLE
| EXCEPTION | EXCEPTION
@ -6619,9 +6746,9 @@ class Parser(Tokenizer):
""" """
p[0] = p[2].withExtendedAttributes(p[1]) p[0] = p[2].withExtendedAttributes(p[1])
def p_SingleTypeNonAnyType(self, p): def p_SingleTypeDistinguishableType(self, p):
""" """
SingleType : NonAnyType SingleType : DistinguishableType
""" """
p[0] = p[1] p[0] = p[1]
@ -6631,6 +6758,14 @@ class Parser(Tokenizer):
""" """
p[0] = BuiltinTypes[IDLBuiltinType.Types.any] p[0] = BuiltinTypes[IDLBuiltinType.Types.any]
# Note: Promise<void> is allowed, so we want to parametrize on ReturnType,
# not Type. Promise types can't be null, hence no "Null" in there.
def p_SingleTypePromiseType(self, p):
"""
SingleType : PROMISE LT ReturnType GT
"""
p[0] = IDLPromiseType(self.getLocation(p, 1), p[3])
def p_UnionType(self, p): def p_UnionType(self, p):
""" """
UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN
@ -6639,9 +6774,9 @@ class Parser(Tokenizer):
types.extend(p[5]) types.extend(p[5])
p[0] = IDLUnionType(self.getLocation(p, 1), types) p[0] = IDLUnionType(self.getLocation(p, 1), types)
def p_UnionMemberTypeNonAnyType(self, p): def p_UnionMemberTypeDistinguishableType(self, p):
""" """
UnionMemberType : ExtendedAttributeList NonAnyType UnionMemberType : ExtendedAttributeList DistinguishableType
""" """
p[0] = p[2].withExtendedAttributes(p[1]) p[0] = p[2].withExtendedAttributes(p[1])
@ -6664,9 +6799,9 @@ class Parser(Tokenizer):
""" """
p[0] = [] p[0] = []
def p_NonAnyType(self, p): def p_DistinguishableType(self, p):
""" """
NonAnyType : PrimitiveType Null DistinguishableType : PrimitiveType Null
| ARRAYBUFFER Null | ARRAYBUFFER Null
| SHAREDARRAYBUFFER Null | SHAREDARRAYBUFFER Null
| READABLESTREAM Null | READABLESTREAM Null
@ -6685,40 +6820,32 @@ class Parser(Tokenizer):
p[0] = self.handleNullable(type, p[2]) p[0] = self.handleNullable(type, p[2])
def p_NonAnyTypeStringType(self, p): def p_DistinguishableTypeStringType(self, p):
""" """
NonAnyType : StringType Null DistinguishableType : StringType Null
""" """
p[0] = self.handleNullable(p[1], p[2]) p[0] = self.handleNullable(p[1], p[2])
def p_NonAnyTypeSequenceType(self, p): def p_DistinguishableTypeSequenceType(self, p):
""" """
NonAnyType : SEQUENCE LT TypeWithExtendedAttributes GT Null DistinguishableType : SEQUENCE LT TypeWithExtendedAttributes GT Null
""" """
innerType = p[3] innerType = p[3]
type = IDLSequenceType(self.getLocation(p, 1), innerType) type = IDLSequenceType(self.getLocation(p, 1), innerType)
p[0] = self.handleNullable(type, p[5]) p[0] = self.handleNullable(type, p[5])
# Note: Promise<void> is allowed, so we want to parametrize on ReturnType, def p_DistinguishableTypeRecordType(self, p):
# not Type. Promise types can't be null, hence no "Null" in there.
def p_NonAnyTypePromiseType(self, p):
""" """
NonAnyType : PROMISE LT ReturnType GT DistinguishableType : RECORD LT StringType COMMA TypeWithExtendedAttributes GT Null
"""
p[0] = IDLPromiseType(self.getLocation(p, 1), p[3])
def p_NonAnyTypeRecordType(self, p):
"""
NonAnyType : RECORD LT StringType COMMA TypeWithExtendedAttributes GT Null
""" """
keyType = p[3] keyType = p[3]
valueType = p[5] valueType = p[5]
type = IDLRecordType(self.getLocation(p, 1), keyType, valueType) type = IDLRecordType(self.getLocation(p, 1), keyType, valueType)
p[0] = self.handleNullable(type, p[7]) p[0] = self.handleNullable(type, p[7])
def p_NonAnyTypeScopedName(self, p): def p_DistinguishableTypeScopedName(self, p):
""" """
NonAnyType : ScopedName Null DistinguishableType : ScopedName Null
""" """
assert isinstance(p[1], IDLUnresolvedIdentifier) assert isinstance(p[1], IDLUnresolvedIdentifier)
@ -6748,28 +6875,26 @@ class Parser(Tokenizer):
type = IDLUnresolvedType(self.getLocation(p, 1), p[1]) type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
p[0] = self.handleNullable(type, p[2]) p[0] = self.handleNullable(type, p[2])
def p_NonAnyTypeDate(self, p): def p_DistinguishableTypeDate(self, p):
""" """
NonAnyType : DATE Null DistinguishableType : DATE Null
""" """
p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date], p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date],
p[2]) p[2])
def p_ConstType(self, p): def p_ConstType(self, p):
""" """
ConstType : PrimitiveType Null ConstType : PrimitiveType
""" """
type = BuiltinTypes[p[1]] p[0] = BuiltinTypes[p[1]]
p[0] = self.handleNullable(type, p[2])
def p_ConstTypeIdentifier(self, p): def p_ConstTypeIdentifier(self, p):
""" """
ConstType : IDENTIFIER Null ConstType : IDENTIFIER
""" """
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
type = IDLUnresolvedType(self.getLocation(p, 1), identifier) p[0] = IDLUnresolvedType(self.getLocation(p, 1), identifier)
p[0] = self.handleNullable(type, p[2])
def p_PrimitiveTypeUint(self, p): def p_PrimitiveTypeUint(self, p):
""" """
@ -7040,8 +7165,8 @@ class Parser(Tokenizer):
def _installBuiltins(self, scope): def _installBuiltins(self, scope):
assert isinstance(scope, IDLScope) assert isinstance(scope, IDLScope)
# xrange omits the last value. # range omits the last value.
for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1): for x in range(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
builtin = BuiltinTypes[x] builtin = BuiltinTypes[x]
name = builtin.name name = builtin.name
typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name) typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
@ -7185,14 +7310,14 @@ def main():
f = open(fullPath, 'rb') f = open(fullPath, 'rb')
lines = f.readlines() lines = f.readlines()
f.close() f.close()
print fullPath print(fullPath)
parser.parse(''.join(lines), fullPath) parser.parse(''.join(lines), fullPath)
parser.finish() parser.finish()
except WebIDLError, e: except WebIDLError as e:
if options.verbose_errors: if options.verbose_errors:
traceback.print_exc() traceback.print_exc()
else: else:
print e print(e)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View file

@ -1,11 +1,11 @@
--- WebIDL.py --- WebIDL.py
+++ WebIDL.py +++ WebIDL.py
@@ -1786,7 +1786,8 @@ class IDLInterface(IDLInterfaceOrNamespace): @@ -1768,7 +1768,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "ProbablyShortLivingWrapper" or
identifier == "LegacyUnenumerableNamedProperties" or identifier == "LegacyUnenumerableNamedProperties" or
identifier == "RunConstructorInCallerCompartment" or identifier == "RunConstructorInCallerCompartment" or
- identifier == "WantsEventListenerHooks"): identifier == "WantsEventListenerHooks" or
+ identifier == "WantsEventListenerHooks" or - identifier == "Serializable"):
+ identifier == "Serializable" or
+ identifier == "Abstract"): + identifier == "Abstract"):
# Known extended attributes that do not take values # Known extended attributes that do not take values
if not attr.noArguments(): if not attr.noArguments():

View file

@ -1,7 +1,7 @@
--- WebIDL.py --- WebIDL.py
+++ WebIDL.py +++ WebIDL.py
@@ -2275,7 +2275,7 @@ class IDLUnresolvedType(IDLType): @@ -2283,7 +2283,7 @@ class IDLUnresolvedType(IDLType):
return typedefType.complete(scope) return typedefType.complete(scope).withExtendedAttributes(self.extraTypeAttributes)
elif obj.isCallback() and not obj.isInterface(): elif obj.isCallback() and not obj.isInterface():
assert self.name.name == obj.identifier.name assert self.name.name == obj.identifier.name
- return IDLCallbackType(self.location, obj) - return IDLCallbackType(self.location, obj)
@ -9,7 +9,7 @@
name = self.name.resolve(scope, None) name = self.name.resolve(scope, None)
return IDLWrapperType(self.location, obj) return IDLWrapperType(self.location, obj)
@@ -6688,7 +6688,7 @@ class Parser(Tokenizer): @@ -6854,7 +6854,7 @@ class Parser(Tokenizer):
type = IDLTypedefType(self.getLocation(p, 1), obj.innerType, type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
obj.identifier.name) obj.identifier.name)
elif obj.isCallback() and not obj.isInterface(): elif obj.isCallback() and not obj.isInterface():

View file

@ -1,6 +1,6 @@
--- WebIDL.py --- WebIDL.py
+++ WebIDL.py +++ WebIDL.py
@@ -6959,7 +6959,8 @@ class Parser(Tokenizer): @@ -7123,7 +7123,8 @@ class Parser(Tokenizer):
self.parser = yacc.yacc(module=self, self.parser = yacc.yacc(module=self,
outputdir=outputdir, outputdir=outputdir,
tabmodule='webidlyacc', tabmodule='webidlyacc',

View file

@ -1,9 +1,9 @@
--- WebIDL.py --- WebIDL.py
+++ WebIDL.py +++ WebIDL.py
@@ -1787,7 +1787,8 @@ class IDLInterface(IDLInterfaceOrNamespace): @@ -1769,7 +1769,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "LegacyUnenumerableNamedProperties" or
identifier == "RunConstructorInCallerCompartment" or identifier == "RunConstructorInCallerCompartment" or
identifier == "WantsEventListenerHooks" or identifier == "WantsEventListenerHooks" or
identifier == "Serializable" or
- identifier == "Abstract"): - identifier == "Abstract"):
+ identifier == "Abstract" or + identifier == "Abstract" or
+ identifier == "Inline"): + identifier == "Inline"):

View file

@ -1,27 +0,0 @@
--- WebIDL.py
+++ WebIDL.py
@@ -1362,12 +1362,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
for bindingAlias in member.bindingAliases:
checkDuplicateNames(member, bindingAlias, "BindingAlias")
-
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
- raise WebIDLError("[Pref] used on an interface that is not "
- "main-thread-only",
- [self.location])
-
# Conditional exposure makes no sense for interfaces with no
# interface object, unless they're navigator properties.
# And SecureContext makes sense for interfaces with no interface object,
@@ -3619,11 +3613,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
IDLExposureMixins.finish(self, scope)
def validate(self):
- if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
- raise WebIDLError("[Pref] used on an interface member that is not "
- "main-thread-only",
- [self.location])
-
if self.isAttr() or self.isMethod():
if self.affects == "Everything" and self.dependsOn != "Everything":
raise WebIDLError("Interface member is flagged as affecting "

View file

@ -62,7 +62,7 @@ def run_tests(tests, verbose):
harness.start() harness.start()
try: try:
_test.WebIDLTest.__call__(WebIDL.Parser(), harness) _test.WebIDLTest.__call__(WebIDL.Parser(), harness)
except Exception, ex: except Exception as ex:
print("TEST-UNEXPECTED-FAIL | Unhandled exception in test %s: %s" % (testpath, ex)) print("TEST-UNEXPECTED-FAIL | Unhandled exception in test %s: %s" % (testpath, ex))
traceback.print_exc() traceback.print_exc()
finally: finally:

View file

@ -133,7 +133,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should not allow [SetterThrows] on readonly attributes") harness.ok(threw, "Should not allow [SetterThrows] on readonly attributes")
@ -146,7 +146,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should spell [Throws] correctly") harness.ok(threw, "Should spell [Throws] correctly")
@ -159,7 +159,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type") harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type")
@ -172,6 +172,6 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(not threw, "Should allow [SameObject] on attributes of interface type") harness.ok(not threw, "Should allow [SameObject] on attributes of interface type")

View file

@ -32,3 +32,6 @@ def WebIDLTest(parser, harness):
harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right 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(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type")
harness.ok(t.isCallback(), "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")

View file

@ -0,0 +1,63 @@
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("""
[TreatNonObjectAsNull]
callback constructor CallbackConstructorType = object ();
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should throw on TreatNonObjectAsNull 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")

View file

@ -38,7 +38,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, e: except Exception as e:
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e) harness.ok(False, "Shouldn't have thrown for [CEReactions] used on writable attribute. %s" % e)
threw = True threw = True
@ -52,7 +52,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, e: except Exception as e:
harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e) harness.ok(False, "Shouldn't have thrown for [CEReactions] used on regular operations. %s" % e)
threw = True threw = True

View file

@ -44,7 +44,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, exception: except Exception as exception:
pass pass
harness.ok(exception, "Should have thrown.") harness.ok(exception, "Should have thrown.")
@ -70,7 +70,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, exception: except Exception as exception:
pass pass
harness.ok(exception, "Should have thrown (2).") harness.ok(exception, "Should have thrown (2).")
@ -100,7 +100,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, exception: except Exception as exception:
pass pass
harness.ok(exception, "Should have thrown (3).") harness.ok(exception, "Should have thrown (3).")

View file

@ -12,9 +12,6 @@ expected = [
("::TestConsts::ll", "ll", "LongLong", -8), ("::TestConsts::ll", "ll", "LongLong", -8),
("::TestConsts::t", "t", "Boolean", True), ("::TestConsts::t", "t", "Boolean", True),
("::TestConsts::f", "f", "Boolean", False), ("::TestConsts::f", "f", "Boolean", False),
("::TestConsts::n", "n", "BooleanOrNull", None),
("::TestConsts::nt", "nt", "BooleanOrNull", True),
("::TestConsts::nf", "nf", "BooleanOrNull", False),
("::TestConsts::fl", "fl", "Float", 0.2), ("::TestConsts::fl", "fl", "Float", 0.2),
("::TestConsts::db", "db", "Double", 0.2), ("::TestConsts::db", "db", "Double", 0.2),
("::TestConsts::ufl", "ufl", "UnrestrictedFloat", 0.2), ("::TestConsts::ufl", "ufl", "UnrestrictedFloat", 0.2),
@ -39,9 +36,6 @@ def WebIDLTest(parser, harness):
const long long ll = -010; const long long ll = -010;
const boolean t = true; const boolean t = true;
const boolean f = false; const boolean f = false;
const boolean? n = null;
const boolean? nt = true;
const boolean? nf = false;
const float fl = 0.2; const float fl = 0.2;
const double db = 0.2; const double db = 0.2;
const unrestricted float ufl = 0.2; const unrestricted float ufl = 0.2;
@ -78,3 +72,16 @@ def WebIDLTest(parser, harness):
"Const's value has the same type as the type") "Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.") 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.")

View file

@ -0,0 +1,87 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
[Constructor, Global]
interface TestConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[Global, Constructor]
interface TestConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[Global, NamedConstructor=FooBar]
interface TestNamedConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[NamedConstructor=FooBar, Global]
interface TestNamedConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[Global, HTMLConstructor]
interface TestHTMLConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[HTMLConstructor, Global]
interface TestHTMLConstructorGlobal {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -13,6 +13,7 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False threw = False
try: try:
parser.parse(""" parser.parse("""

View file

@ -167,6 +167,22 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Trailing dictionary arg must be optional") harness.ok(threw, "Trailing dictionary arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(optional A arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Trailing dictionary arg must have a default value")
parser = parser.reset() parser = parser.reset()
threw = False threw = False
try: try:
@ -184,6 +200,23 @@ def WebIDLTest(parser, harness):
harness.ok(threw, harness.ok(threw,
"Trailing union arg containing a dictionary must be optional") "Trailing union arg containing a dictionary must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void 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() parser = parser.reset()
threw = False threw = False
try: try:
@ -200,6 +233,22 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Dictionary arg followed by optional arg must be optional") harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void 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() parser = parser.reset()
threw = False threw = False
try: try:
@ -235,6 +284,24 @@ def WebIDLTest(parser, harness):
"Union arg containing dictionary followed by optional arg must " "Union arg containing dictionary followed by optional arg must "
"be optional") "be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void 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 = parser.reset()
parser.parse(""" parser.parse("""
dictionary A { dictionary A {
@ -326,7 +393,7 @@ def WebIDLTest(parser, harness):
dictionary A { dictionary A {
}; };
interface X { interface X {
void doFoo(optional A arg); void doFoo(optional A arg = {});
}; };
""") """)
results = parser.finish() results = parser.finish()
@ -337,12 +404,23 @@ def WebIDLTest(parser, harness):
dictionary A { dictionary A {
}; };
interface X { interface X {
void doFoo(optional (A or DOMString) arg); void doFoo(optional (A or DOMString) arg = {});
}; };
""") """)
results = parser.finish() results = parser.finish()
harness.ok(True, "Union arg containing a dictionary should actually parse") harness.ok(True, "Union arg containing a dictionary should actually parse")
parser = parser.reset()
parser.parse("""
dictionary A {
};
interface X {
void 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() parser = parser.reset()
threw = False threw = False
try: try:

View file

@ -3,13 +3,16 @@ def firstArgType(method):
def WebIDLTest(parser, harness): def WebIDLTest(parser, harness):
parser.parse(""" parser.parse("""
// Give our dictionary a required member so we don't need to
// mess with optional and default values.
dictionary Dict { dictionary Dict {
required long member;
}; };
callback interface Foo { callback interface Foo {
}; };
interface Bar { interface Bar {
// Bit of a pain to get things that have dictionary types // Bit of a pain to get things that have dictionary types
void passDict(optional Dict arg); void passDict(Dict arg);
void passFoo(Foo arg); void passFoo(Foo arg);
void passNullableUnion((object? or DOMString) arg); void passNullableUnion((object? or DOMString) arg);
void passNullable(Foo? arg); void passNullable(Foo? arg);
@ -156,8 +159,8 @@ def WebIDLTest(parser, harness):
"AncestorInterface", "UnrelatedInterface", "AncestorInterface", "UnrelatedInterface",
"ImplementedInterface", "CallbackInterface", "ImplementedInterface", "CallbackInterface",
"CallbackInterface?", "CallbackInterface2", "CallbackInterface?", "CallbackInterface2",
"object", "Callback", "Callback2", "optional Dict", "object", "Callback", "Callback2", "Dict",
"optional Dict2", "sequence<long>", "sequence<short>", "Dict2", "sequence<long>", "sequence<short>",
"record<DOMString, object>", "record<DOMString, object>",
"record<USVString, Dict>", "record<USVString, Dict>",
"record<ByteString, long>", "record<ByteString, long>",
@ -165,7 +168,7 @@ def WebIDLTest(parser, harness):
"Promise<any>", "Promise<any>?", "Promise<any>", "Promise<any>?",
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
"Uint8Array", "Uint16Array", "Uint8Array", "Uint16Array",
"(long or Callback)", "optional (long or Dict)", "(long or Callback)", "(long or Dict)",
] ]
# When we can parse Date, we need to add it here. # When we can parse Date, we need to add it here.
# XXXbz we can, and should really do that... # XXXbz we can, and should really do that...
@ -174,7 +177,7 @@ def WebIDLTest(parser, harness):
def allBut(list1, list2): def allBut(list1, list2):
return [a for a in list1 if a not in list2 and return [a for a in list1 if a not in list2 and
(a != "any" and a != "Promise<any>" and a != "Promise<any>?")] (a != "any" and a != "Promise<any>" and a != "Promise<any>?")]
unions = [ "(long or Callback)", "optional (long or Dict)" ] unions = [ "(long or Callback)", "(long or Dict)" ]
numerics = [ "long", "short", "long?", "short?" ] numerics = [ "long", "short", "long?", "short?" ]
booleans = [ "boolean", "boolean?" ] booleans = [ "boolean", "boolean?" ]
primitives = numerics + booleans primitives = numerics + booleans
@ -189,7 +192,7 @@ def WebIDLTest(parser, harness):
interfaces = [ "Interface", "Interface?", "AncestorInterface", interfaces = [ "Interface", "Interface?", "AncestorInterface",
"UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
nullables = (["long?", "short?", "boolean?", "Interface?", nullables = (["long?", "short?", "boolean?", "Interface?",
"CallbackInterface?", "optional Dict", "optional Dict2", "CallbackInterface?", "Dict", "Dict2",
"Date?", "any", "Promise<any>?"] + "Date?", "any", "Promise<any>?"] +
allBut(unions, [ "(long or Callback)" ])) allBut(unions, [ "(long or Callback)" ]))
dates = [ "Date", "Date?" ] dates = [ "Date", "Date?" ]
@ -233,8 +236,8 @@ def WebIDLTest(parser, harness):
setDistinguishable("object", nonObjects) setDistinguishable("object", nonObjects)
setDistinguishable("Callback", nonUserObjects) setDistinguishable("Callback", nonUserObjects)
setDistinguishable("Callback2", nonUserObjects) setDistinguishable("Callback2", nonUserObjects)
setDistinguishable("optional Dict", allBut(nonUserObjects, nullables)) setDistinguishable("Dict", allBut(nonUserObjects, nullables))
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables)) setDistinguishable("Dict2", allBut(nonUserObjects, nullables))
setDistinguishable("sequence<long>", setDistinguishable("sequence<long>",
allBut(argTypes, sequences + ["object"])) allBut(argTypes, sequences + ["object"]))
setDistinguishable("sequence<short>", setDistinguishable("sequence<short>",
@ -254,7 +257,7 @@ def WebIDLTest(parser, harness):
setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"])) setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
setDistinguishable("(long or Callback)", setDistinguishable("(long or Callback)",
allBut(nonUserObjects, numerics)) allBut(nonUserObjects, numerics))
setDistinguishable("optional (long or Dict)", setDistinguishable("(long or Dict)",
allBut(nonUserObjects, numerics + nullables)) allBut(nonUserObjects, numerics + nullables))
def areDistinguishable(type1, type2): def areDistinguishable(type1, type2):
@ -273,8 +276,10 @@ def WebIDLTest(parser, harness):
callback interface CallbackInterface2 {}; callback interface CallbackInterface2 {};
callback Callback = any(); callback Callback = any();
callback Callback2 = long(short arg); callback Callback2 = long(short arg);
dictionary Dict {}; // Give our dictionaries required members so we don't need to
dictionary Dict2 {}; // mess with optional and default values.
dictionary Dict { required long member; };
dictionary Dict2 { required long member; };
interface TestInterface {%s interface TestInterface {%s
}; };
""" """

View file

@ -10,7 +10,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Constant cannot have [] as a default value") harness.ok(threw, "Constant cannot have [] as a default value")

View file

@ -8,7 +8,7 @@ def WebIDLTest(parser, harness):
try: try:
parser.parse(input) parser.parse(input)
results = parser.finish() results = parser.finish()
except WebIDL.WebIDLError, e: except WebIDL.WebIDLError as e:
threw = True threw = True
lines = str(e).split('\n') lines = str(e).split('\n')

View file

@ -14,7 +14,7 @@ interface ?"""
try: try:
parser.parse(input) parser.parse(input)
results = parser.finish() results = parser.finish()
except WebIDL.WebIDLError, e: except WebIDL.WebIDLError as e:
threw = True threw = True
lines = str(e).split('\n') lines = str(e).split('\n')

View file

@ -124,7 +124,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on invalid Exposed value on interface.") harness.ok(threw, "Should have thrown on invalid Exposed value on interface.")
@ -140,7 +140,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on invalid Exposed value on attribute.") harness.ok(threw, "Should have thrown on invalid Exposed value on attribute.")
@ -156,7 +156,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on invalid Exposed value on operation.") harness.ok(threw, "Should have thrown on invalid Exposed value on operation.")
@ -172,7 +172,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on invalid Exposed value on constant.") harness.ok(threw, "Should have thrown on invalid Exposed value on constant.")
@ -192,7 +192,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on member exposed where its interface is not.") harness.ok(threw, "Should have thrown on member exposed where its interface is not.")
@ -216,7 +216,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown on LHS of implements being exposed where RHS is not.") harness.ok(threw, "Should have thrown on LHS of implements being exposed where RHS is not.")

View file

@ -68,7 +68,7 @@ def WebIDLTest(parser, harness):
long m(float arg); long m(float arg);
}; };
""") """)
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "[LenientFloat] only allowed on void methods") harness.ok(threw, "[LenientFloat] only allowed on void methods")
@ -81,7 +81,7 @@ def WebIDLTest(parser, harness):
void m(unrestricted float arg); void m(unrestricted float arg);
}; };
""") """)
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args") harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args")
@ -94,7 +94,7 @@ def WebIDLTest(parser, harness):
void m(sequence<unrestricted float> arg); void m(sequence<unrestricted float> arg);
}; };
""") """)
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)") harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)")
@ -107,7 +107,7 @@ def WebIDLTest(parser, harness):
void m((unrestricted float or FloatTypes) arg); void m((unrestricted float or FloatTypes) arg);
}; };
""") """)
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)") harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)")
@ -120,6 +120,6 @@ def WebIDLTest(parser, harness):
readonly attribute float foo; readonly attribute float foo;
}; };
""") """)
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "[LenientFloat] only allowed on writable attributes") harness.ok(threw, "[LenientFloat] only allowed on writable attributes")

View file

@ -9,7 +9,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
harness.ok(False, "Should fail to parse") harness.ok(False, "Should fail to parse")
except Exception, e: except Exception as e:
harness.ok("Name collision" in e.message, harness.ok("Name collision" in e.message,
"Should have name collision for interface") "Should have name collision for interface")
@ -21,7 +21,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
harness.ok(False, "Should fail to parse") harness.ok(False, "Should fail to parse")
except Exception, e: except Exception as e:
harness.ok("Name collision" in e.message, harness.ok("Name collision" in e.message,
"Should have name collision for dictionary") "Should have name collision for dictionary")
@ -33,7 +33,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
harness.ok(False, "Should fail to parse") harness.ok(False, "Should fail to parse")
except Exception, e: except Exception as e:
harness.ok("Multiple unresolvable definitions" in e.message, harness.ok("Multiple unresolvable definitions" in e.message,
"Should have name collision for dictionary") "Should have name collision for dictionary")

View file

@ -374,3 +374,89 @@ def WebIDLTest(parser, harness):
threw = True threw = True
harness.ok(threw, harness.ok(threw,
"Should not allow unknown extended attributes on interfaces") "Should not allow unknown extended attributes on interfaces")
parser = parser.reset()
parser.parse("""
[Global] 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] interface 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] interface Window {};
[Exposed=Window, LegacyWindowAlias=A]
interface B {};
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] 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")

View file

@ -37,10 +37,10 @@ def WebIDLTest(parser, harness):
p.finish() p.finish()
harness.ok(False, harness.ok(False,
prefix + " - Interface passed when should've failed") prefix + " - Interface passed when should've failed")
except WebIDL.WebIDLError, e: except WebIDL.WebIDLError as e:
harness.ok(True, harness.ok(True,
prefix + " - Interface failed as expected") prefix + " - Interface failed as expected")
except Exception, e: except Exception as e:
harness.ok(False, harness.ok(False,
prefix + " - Interface failed but not as a WebIDLError exception: %s" % e) prefix + " - Interface failed but not as a WebIDLError exception: %s" % e)

View file

@ -1,6 +1,6 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
def should_throw(parser, harness, message, code): def should_throw(parser, harness, message, code):
parser = parser.reset(); parser = parser.reset();

View file

@ -120,7 +120,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(not threw, "Should allow integer to float type corecion") harness.ok(not threw, "Should allow integer to float type corecion")
@ -133,7 +133,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should not allow [GetterThrows] on methods") harness.ok(threw, "Should not allow [GetterThrows] on methods")
@ -146,7 +146,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should not allow [SetterThrows] on methods") harness.ok(threw, "Should not allow [SetterThrows] on methods")
@ -159,7 +159,7 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should spell [Throws] correctly on methods") harness.ok(threw, "Should spell [Throws] correctly on methods")
@ -172,6 +172,85 @@ def WebIDLTest(parser, harness):
}; };
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should not allow __noSuchMethod__ methods") harness.ok(threw, "Should not allow __noSuchMethod__ methods")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[Throws, LenientFloat]
void foo(float myFloat);
[Throws]
void 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]
void foo();
[Throws, LenientFloat]
void 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]
void foo(float myFloat);
[Throws]
void 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]
void foo(float myFloat, float yourFloat);
[Throws, LenientFloat]
void 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]
void foo(float myFloat);
[Throws, LenientFloat]
void foo(short myShort);
};
""")
results = parser.finish()
except Exception as x:
threw = True
harness.ok(threw, "Should prevent overloads from getting redundant [LenientFloat]")

View file

@ -70,7 +70,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -85,7 +85,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -104,7 +104,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -123,7 +123,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -142,7 +142,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -161,7 +161,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -180,7 +180,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -199,7 +199,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -218,6 +218,6 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")

View file

@ -33,7 +33,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown because record can't have void as value type.") harness.ok(threw, "Should have thrown because record can't have void as value type.")
@ -47,7 +47,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, harness.ok(threw,
"Should have thrown on dictionary containing itself via record.") "Should have thrown on dictionary containing itself via record.")

View file

@ -1,6 +1,6 @@
# This Source Code Form is subject to the terms of the Mozilla Public # 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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
def should_throw(parser, harness, message, code): def should_throw(parser, harness, message, code):
parser = parser.reset(); parser = parser.reset();

View file

@ -4,15 +4,15 @@ def WebIDLTest(parser, harness):
typedef long? mynullablelong; typedef long? mynullablelong;
interface Foo { interface Foo {
const mylong X = 5; const mylong X = 5;
const mynullablelong Y = 7; void foo(optional mynullablelong arg = 7);
const mynullablelong Z = null; void bar(optional mynullablelong arg = null);
void foo(mylong arg); void baz(mylong arg);
}; };
""") """)
results = parser.finish() results = parser.finish()
harness.check(results[2].members[1].type.name, "LongOrNull", harness.check(results[2].members[1].signatures()[0][1][0].type.name, "LongOrNull",
"Should expand typedefs") "Should expand typedefs")
parser = parser.reset() parser = parser.reset()

View file

@ -24,7 +24,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -39,7 +39,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")
@ -59,6 +59,6 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception, x: except Exception as x:
threw = True threw = True
harness.ok(threw, "Should have thrown.") harness.ok(threw, "Should have thrown.")

View file

@ -111,7 +111,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, harness.ok(threw,
"Should have thrown when shadowing unforgeable attribute on " "Should have thrown when shadowing unforgeable attribute on "
@ -130,7 +130,7 @@ def WebIDLTest(parser, harness):
""") """)
results = parser.finish() results = parser.finish()
except Exception,x: except Exception as x:
threw = True threw = True
harness.ok(threw, harness.ok(threw,
"Should have thrown when shadowing unforgeable operation on " "Should have thrown when shadowing unforgeable operation on "

View file

@ -17,7 +17,7 @@ def combinations(iterable, r):
n = len(pool) n = len(pool)
if r > n: if r > n:
return return
indices = range(r) indices = list(range(r))
yield tuple(pool[i] for i in indices) yield tuple(pool[i] for i in indices)
while True: while True:
for i in reversed(range(r)): for i in reversed(range(r)):

View file

@ -1,7 +1,6 @@
wget https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/bindings/parser/WebIDL.py -O WebIDL.py wget https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/bindings/parser/WebIDL.py -O WebIDL.py
patch < abstract.patch patch < abstract.patch
patch < debug.patch patch < debug.patch
patch < pref-main-thread.patch
patch < callback-location.patch patch < callback-location.patch
patch < union-typedef.patch patch < union-typedef.patch
patch < inline.patch patch < inline.patch