aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/parser/WebIDL.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen/parser/WebIDL.py')
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py157
1 files changed, 90 insertions, 67 deletions
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index 5045eae6493..b2daa1bce20 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -1095,12 +1095,12 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
testInterface = testInterface.parent
# Ensure that there's at most one of each {named,indexed}
- # {getter,setter,creator,deleter}, at most one stringifier,
+ # {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/creator by
+ # treat deleter analogously to getter/setter by
# prefixing it with "named".
specialMembersSeen = {}
for member in self.members:
@@ -1111,8 +1111,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
memberType = "getters"
elif member.isSetter():
memberType = "setters"
- elif member.isCreator():
- memberType = "creators"
elif member.isDeleter():
memberType = "deleters"
elif member.isStringifier():
@@ -1158,8 +1156,8 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
ancestor = ancestor.parent
if self._isOnGlobalProtoChain:
- # Make sure we have no named setters, creators, or deleters
- for memberType in ["setter", "creator", "deleter"]:
+ # 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" %
@@ -1183,6 +1181,22 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
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 don't support consequential unforgeable interfaces. Need to check
# this here, because in finish() an interface might not know yet that
# it's consequential.
@@ -1295,15 +1309,15 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
raise WebIDLError("[Alias] must not be used on an "
"[Unforgeable] operation",
[member.location])
- for m in self.members:
- if m.identifier.name == alias:
- raise WebIDLError("[Alias=%s] has same name as "
- "interface member" % alias,
- [member.location, m.location])
- if m.isMethod() and m != member and alias in m.aliases:
- raise WebIDLError("duplicate [Alias=%s] definitions" %
- alias,
- [member.location, m.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, unless they're navigator properties.
@@ -1720,10 +1734,10 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "OverrideBuiltins" or
identifier == "ChromeOnly" or
identifier == "Unforgeable" or
- identifier == "UnsafeInPrerendering" or
identifier == "LegacyEventInit" or
identifier == "ProbablyShortLivingWrapper" or
identifier == "LegacyUnenumerableNamedProperties" or
+ identifier == "RunConstructorInCallerCompartment" or
identifier == "NonOrdinaryGetPrototypeOf" or
identifier == "Abstract" or
identifier == "Inline"):
@@ -1780,10 +1794,16 @@ class IDLNamespace(IDLInterfaceOrNamespace):
if not attr.hasValue():
raise WebIDLError("[%s] must have a value" % identifier,
[attr.location])
- elif identifier == "ProtoObjectHack":
+ elif (identifier == "ProtoObjectHack" or
+ identifier == "ChromeOnly"):
if not attr.noArguments():
raise WebIDLError("[%s] must not have arguments" % identifier,
[attr.location])
+ elif identifier == "Pref":
+ # 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,
@@ -3581,6 +3601,11 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
[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):
@@ -3701,6 +3726,11 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if isIteratorAlias:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
+ # Methods generated for iterables should be enumerable, but the ones for
+ # maplike/setlike should not be.
+ if not self.isIterable():
+ method.addExtendedAttributes(
+ [IDLExtendedAttribute(self.location, ("NonEnumerable",))])
members.append(method)
def resolve(self, parentScope):
@@ -3824,11 +3854,15 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
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))
+ sizeAttr = IDLAttribute(self.location,
+ IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
+ BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
+ True,
+ maplikeOrSetlike=self)
+ # This should be non-enumerable.
+ sizeAttr.addExtendedAttributes(
+ [IDLExtendedAttribute(self.location, ("NonEnumerable",))])
+ members.append(sizeAttr)
self.reserved_ro_names = ["size"]
self.disallowedMemberNames.append("size")
@@ -3964,7 +3998,9 @@ class IDLConst(IDLInterfaceMember):
elif (identifier == "Pref" or
identifier == "ChromeOnly" or
identifier == "Func" or
- identifier == "SecureContext"):
+ identifier == "SecureContext" or
+ identifier == "NonEnumerable" or
+ identifier == "NeedsWindowsUndef"):
# Known attributes that we don't need to do anything with here
pass
else:
@@ -4000,6 +4036,7 @@ class IDLAttribute(IDLInterfaceMember):
self.dependsOn = "Everything"
self.affects = "Everything"
self.navigatorObjectGetter = navigatorObjectGetter
+ self.bindingAliases = []
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
@@ -4138,11 +4175,17 @@ class IDLAttribute(IDLInterfaceMember):
def handleExtendedAttribute(self, attr):
identifier = attr.identifier()
- if ((identifier == "SetterThrows" or identifier == "SetterCanOOM")
+ 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
@@ -4338,11 +4381,13 @@ class IDLAttribute(IDLInterfaceMember):
identifier == "SecureContext" or
identifier == "Frozen" or
identifier == "NewObject" or
- identifier == "UnsafeInPrerendering" or
identifier == "NeedsSubjectPrincipal" or
+ identifier == "SetterNeedsSubjectPrincipal" or
+ identifier == "GetterNeedsSubjectPrincipal" or
identifier == "NeedsCallerType" or
identifier == "ReturnValueNeedsContainsHack" or
- identifier == "BinaryName"):
+ identifier == "BinaryName" or
+ identifier == "NonEnumerable"):
# Known attributes that we don't need to do anything with here
pass
else:
@@ -4606,7 +4651,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
Special = enum(
'Getter',
'Setter',
- 'Creator',
'Deleter',
'LegacyCaller',
base=IDLInterfaceMember.Special
@@ -4619,7 +4663,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
)
def __init__(self, location, identifier, returnType, arguments,
- static=False, getter=False, setter=False, creator=False,
+ static=False, getter=False, setter=False,
deleter=False, specialType=NamedOrIndexed.Neither,
legacycaller=False, stringifier=False, jsonifier=False,
maplikeOrSetlikeOrIterable=None, htmlConstructor=False):
@@ -4640,8 +4684,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
self._getter = getter
assert isinstance(setter, bool)
self._setter = setter
- assert isinstance(creator, bool)
- self._creator = creator
assert isinstance(deleter, bool)
self._deleter = deleter
assert isinstance(legacycaller, bool)
@@ -4682,7 +4724,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert not arguments[0].optional and not arguments[0].variadic
assert not self._getter or not overload.returnType.isVoid()
- if self._setter or self._creator:
+ if self._setter:
assert len(self._overloads) == 1
arguments = self._overloads[0].arguments
assert len(arguments) == 2
@@ -4715,9 +4757,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def isSetter(self):
return self._setter
- def isCreator(self):
- return self._creator
-
def isDeleter(self):
return self._deleter
@@ -4750,7 +4789,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def isSpecial(self):
return (self.isGetter() or
self.isSetter() or
- self.isCreator() or
self.isDeleter() or
self.isLegacycaller() or
self.isStringifier() or
@@ -4806,8 +4844,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert not method.isGetter()
assert not self.isSetter()
assert not method.isSetter()
- assert not self.isCreator()
- assert not method.isCreator()
assert not self.isDeleter()
assert not method.isDeleter()
assert not self.isStringifier()
@@ -4984,7 +5020,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if (identifier == "GetterThrows" or
identifier == "SetterThrows" or
identifier == "GetterCanOOM" or
- identifier == "SetterCanOOM"):
+ identifier == "SetterCanOOM" or
+ identifier == "SetterNeedsSubjectPrincipal" or
+ identifier == "GetterNeedsSubjectPrincipal"):
raise WebIDLError("Methods must not be flagged as "
"[%s]" % identifier,
[attr.location, self.location])
@@ -5071,7 +5109,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
identifier == "CanOOM" or
identifier == "NewObject" or
identifier == "ChromeOnly" or
- identifier == "UnsafeInPrerendering" or
identifier == "Pref" or
identifier == "Deprecated" or
identifier == "Func" or
@@ -5079,7 +5116,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
identifier == "BinaryName" or
identifier == "NeedsSubjectPrincipal" or
identifier == "NeedsCallerType" or
- identifier == "StaticClassOverride"):
+ identifier == "StaticClassOverride" or
+ identifier == "NonEnumerable"):
# Known attributes that we don't need to do anything with here
pass
else:
@@ -5262,7 +5300,6 @@ class Tokenizer(object):
"static": "STATIC",
"getter": "GETTER",
"setter": "SETTER",
- "creator": "CREATOR",
"deleter": "DELETER",
"legacycaller": "LEGACYCALLER",
"optional": "OPTIONAL",
@@ -5977,13 +6014,12 @@ class Parser(Tokenizer):
getter = True if IDLMethod.Special.Getter in p[1] else False
setter = True if IDLMethod.Special.Setter in p[1] else False
- creator = True if IDLMethod.Special.Creator 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 or creator:
- raise WebIDLError("getter and deleter are incompatible with setter and creator",
+ if setter:
+ raise WebIDLError("getter and deleter are incompatible with setter",
[self.getLocation(p, 1)])
(returnType, identifier, arguments) = p[2]
@@ -6018,10 +6054,9 @@ class Parser(Tokenizer):
if returnType.isVoid():
raise WebIDLError("getter cannot have void return type",
[self.getLocation(p, 2)])
- if setter or creator:
+ if setter:
if len(arguments) != 2:
- raise WebIDLError("%s has wrong number of arguments" %
- ("setter" if setter else "creator"),
+ raise WebIDLError("setter has wrong number of arguments",
[self.getLocation(p, 2)])
argType = arguments[0].type
if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]:
@@ -6029,18 +6064,15 @@ class Parser(Tokenizer):
elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]:
specialType = IDLMethod.NamedOrIndexed.Indexed
else:
- raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" %
- ("setter" if setter else "creator"),
+ 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("%s cannot have %s argument" %
- ("setter" if setter else "creator",
- "optional" if arguments[0].optional else "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("%s cannot have %s argument" %
- ("setter" if setter else "creator",
- "optional" if arguments[1].optional else "variadic"),
+ raise WebIDLError("setter cannot have %s argument" %
+ ("optional" if arguments[1].optional else "variadic"),
[arguments[1].location])
if stringifier:
@@ -6053,7 +6085,7 @@ class Parser(Tokenizer):
# identifier might be None. This is only permitted for special methods.
if not identifier:
- if (not getter and not setter and not creator and
+ 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)])
@@ -6061,19 +6093,18 @@ class Parser(Tokenizer):
location = BuiltinLocation("<auto-generated-identifier>")
identifier = IDLUnresolvedIdentifier(
location,
- "__%s%s%s%s%s%s%s" %
+ "__%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 "",
- "creator" if creator 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, creator=creator,
+ static=static, getter=getter, setter=setter,
deleter=deleter, specialType=specialType,
legacycaller=legacycaller, stringifier=stringifier)
p[0] = method
@@ -6149,12 +6180,6 @@ class Parser(Tokenizer):
"""
p[0] = IDLMethod.Special.Setter
- def p_SpecialCreator(self, p):
- """
- Special : CREATOR
- """
- p[0] = IDLMethod.Special.Creator
-
def p_SpecialDeleter(self, p):
"""
Special : DELETER
@@ -6246,7 +6271,6 @@ class Parser(Tokenizer):
| ATTRIBUTE
| CALLBACK
| CONST
- | CREATOR
| DELETER
| DICTIONARY
| ENUM
@@ -6396,7 +6420,6 @@ class Parser(Tokenizer):
| BYTE
| LEGACYCALLER
| CONST
- | CREATOR
| DELETER
| DOUBLE
| EXCEPTION