aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/parser
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py426
-rw-r--r--components/script/dom/bindings/codegen/parser/external.patch6
-rw-r--r--components/script/dom/bindings/codegen/parser/module.patch7
3 files changed, 336 insertions, 103 deletions
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index 7474f56baa2..a40c563ae35 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -204,7 +204,7 @@ class IDLObject(object):
deps.add(self.filename())
for d in self._getDependentObjects():
- deps = deps.union(d.getDeps(visited))
+ deps.update(d.getDeps(visited))
return deps
@@ -338,7 +338,10 @@ class IDLUnresolvedIdentifier(IDLObject):
assert len(name) > 0
- if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore:
+ if name == "__noSuchMethod__":
+ raise WebIDLError("__noSuchMethod__ is deprecated", [location])
+
+ if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore:
raise WebIDLError("Identifiers beginning with __ are reserved",
[location])
if name[0] == '_' and not allowDoubleUnderscore:
@@ -448,7 +451,59 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
obj = self.identifier.resolve(scope, None)
return scope.lookupIdentifier(obj)
-class IDLExternalInterface(IDLObjectWithIdentifier):
+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
+
+ # Verify that our [Exposed] value, if any, makes sense.
+ for globalName in self._exposureGlobalNames:
+ if globalName not in scope.globalNames:
+ raise WebIDLError("Unknown [Exposed] value %s" % globalName,
+ [self._location])
+
+ if len(self._exposureGlobalNames) == 0:
+ self._exposureGlobalNames.add(scope.primaryGlobalName)
+
+ globalNameSetToExposureSet(scope, self._exposureGlobalNames,
+ self.exposureSet)
+
+ def isExposedInWindow(self):
+ return 'Window' in self.exposureSet
+
+ def isExposedInAnyWorker(self):
+ return len(self.getWorkerExposureSet()) > 0
+
+ def isExposedInSystemGlobals(self):
+ return 'BackstagePass' in self.exposureSet
+
+ 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 getWorkerExposureSet(self):
+ workerScopes = self._globalScope.globalNameMapping["Worker"]
+ return workerScopes.intersection(self.exposureSet)
+
+
+class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def __init__(self, location, parentScope, identifier):
raise WebIDLError("Servo does not support external interfaces.",
[self.location])
@@ -511,7 +566,7 @@ def globalNameSetToExposureSet(globalScope, nameSet, exposureSet):
for name in nameSet:
exposureSet.update(globalScope.globalNameMapping[name])
-class IDLInterface(IDLObjectWithScope):
+class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
def __init__(self, location, parentScope, name, parent, members,
isKnownNonPartial):
assert isinstance(parentScope, IDLScope)
@@ -546,13 +601,9 @@ class IDLInterface(IDLObjectWithScope):
self.totalMembersInSlots = 0
# Tracking of the number of own own members we have in slots
self._ownMembersInSlots = 0
- # _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()
IDLObjectWithScope.__init__(self, location, parentScope, name)
+ IDLExposureMixins.__init__(self, location)
if isKnownNonPartial:
self.setNonPartial(location, parent, members)
@@ -592,17 +643,7 @@ class IDLInterface(IDLObjectWithScope):
"declaration" % self.identifier.name,
[self.location])
- # Verify that our [Exposed] value, if any, makes sense.
- for globalName in self._exposureGlobalNames:
- if globalName not in scope.globalNames:
- raise WebIDLError("Unknown [Exposed] value %s" % globalName,
- [self.location])
-
- if len(self._exposureGlobalNames) == 0:
- self._exposureGlobalNames.add(scope.primaryGlobalName)
-
- globalNameSetToExposureSet(scope, self._exposureGlobalNames,
- self.exposureSet)
+ IDLExposureMixins.finish(self, scope)
# Now go ahead and merge in our partial interfaces.
for partial in self._partialInterfaces:
@@ -681,6 +722,17 @@ class IDLInterface(IDLObjectWithScope):
self.parent.identifier.name),
[self.location, self.parent.location])
+ # Interfaces which have interface objects can't inherit
+ # from [NoInterfaceObject] interfaces.
+ if (self.parent.getExtendedAttribute("NoInterfaceObject") and
+ not self.getExtendedAttribute("NoInterfaceObject")):
+ raise WebIDLError("Interface %s does not have "
+ "[NoInterfaceObject] but inherits from "
+ "interface %s which does" %
+ (self.identifier.name,
+ self.parent.identifier.name),
+ [self.location, self.parent.location])
+
for iface in self.implementedInterfaces:
iface.finish(scope)
@@ -718,9 +770,13 @@ class IDLInterface(IDLObjectWithScope):
ctor = self.ctor()
if ctor is not None:
+ assert len(ctor._exposureGlobalNames) == 0
+ ctor._exposureGlobalNames.update(self._exposureGlobalNames)
ctor.finish(scope)
for ctor in self.namedConstructors:
+ 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
@@ -921,10 +977,15 @@ class IDLInterface(IDLObjectWithScope):
list(i.location for i in
self.interfacesBasedOnSelf if i.parent == self))
-
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.
if member.isAttr():
@@ -966,10 +1027,25 @@ class IDLInterface(IDLObjectWithScope):
if (self.getExtendedAttribute("Pref") and
self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
- raise WebIDLError("[Pref] used on an member that is not %s-only" %
+ raise WebIDLError("[Pref] used on an interface that is not %s-only" %
+ self.parentScope.primaryGlobalName,
+ [self.location])
+
+ if (self.getExtendedAttribute("CheckPermissions") and
+ self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
+ raise WebIDLError("[CheckPermissions] used on an interface that is "
+ "not %s-only" %
self.parentScope.primaryGlobalName,
[self.location])
+ # Conditional exposure makes no sense for interfaces with no
+ # interface object, unless they're navigator properties.
+ if (self.isExposedConditionally() and
+ not self.hasInterfaceObject() and
+ not self.getNavigatorProperty()):
+ raise WebIDLError("Interface with no interface object is "
+ "exposed conditionally",
+ [self.location])
def isInterface(self):
return True
@@ -1151,10 +1227,11 @@ class IDLInterface(IDLObjectWithScope):
self.parentScope.globalNames.add(self.identifier.name)
self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
self._isOnGlobalProtoChain = True
- elif (identifier == "NeedNewResolve" or
+ elif (identifier == "NeedResolve" or
identifier == "OverrideBuiltins" or
identifier == "ChromeOnly" or
identifier == "Unforgeable" or
+ identifier == "UnsafeInPrerendering" or
identifier == "LegacyEventInit"):
# Known extended attributes that do not take values
if not attr.noArguments():
@@ -1284,7 +1361,7 @@ class IDLInterface(IDLObjectWithScope):
def _getDependentObjects(self):
deps = set(self.members)
- deps.union(self.implementedInterfaces)
+ deps.update(self.implementedInterfaces)
if self.parent:
deps.add(self.parent)
return deps
@@ -1292,6 +1369,13 @@ class IDLInterface(IDLObjectWithScope):
def hasMembersInSlots(self):
return self._ownMembersInSlots != 0
+ def isExposedConditionally(self):
+ return (self.getExtendedAttribute("Pref") or
+ self.getExtendedAttribute("ChromeOnly") or
+ self.getExtendedAttribute("Func") or
+ self.getExtendedAttribute("AvailableIn") or
+ self.getExtendedAttribute("CheckPermissions"))
+
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@@ -1486,7 +1570,7 @@ class IDLType(IDLObject):
'any',
'domstring',
'bytestring',
- 'scalarvaluestring',
+ 'usvstring',
'object',
'date',
'void',
@@ -1539,7 +1623,7 @@ class IDLType(IDLObject):
def isDOMString(self):
return False
- def isScalarValueString(self):
+ def isUSVString(self):
return False
def isVoid(self):
@@ -1688,7 +1772,10 @@ class IDLNullableType(IDLType):
assert not innerType.isVoid()
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
- IDLType.__init__(self, location, innerType.name)
+ name = innerType.name
+ if innerType.isComplete():
+ name += "OrNull"
+ IDLType.__init__(self, location, name)
self.inner = innerType
self.builtin = False
@@ -1722,8 +1809,8 @@ class IDLNullableType(IDLType):
def isDOMString(self):
return self.inner.isDOMString()
- def isScalarValueString(self):
- return self.inner.isScalarValueString()
+ def isUSVString(self):
+ return self.inner.isUSVString()
def isFloat(self):
return self.inner.isFloat()
@@ -1801,7 +1888,7 @@ class IDLNullableType(IDLType):
"be a union type that itself has a nullable "
"type as a member type", [self.location])
- self.name = self.inner.name
+ self.name = self.inner.name + "OrNull"
return self
def unroll(self):
@@ -1824,6 +1911,10 @@ class IDLSequenceType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
+ # 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 __eq__(self, other):
return isinstance(other, IDLSequenceType) and self.inner == other.inner
@@ -1846,7 +1937,7 @@ class IDLSequenceType(IDLType):
def isDOMString(self):
return False
- def isScalarValueString(self):
+ def isUSVString(self):
return False
def isVoid(self):
@@ -1885,7 +1976,7 @@ class IDLSequenceType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
- self.name = self.inner.name
+ self.name = self.inner.name + "Sequence"
return self
def unroll(self):
@@ -1896,7 +1987,8 @@ class IDLSequenceType(IDLType):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
- other.isDate() or other.isNonCallbackInterface() or other.isMozMap())
+ other.isDate() or other.isInterface() or other.isDictionary() or
+ other.isCallback() or other.isMozMap())
def _getDependentObjects(self):
return self.inner._getDependentObjects()
@@ -1911,6 +2003,10 @@ class IDLMozMapType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
+ # 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 + "MozMap"
def __eq__(self, other):
return isinstance(other, IDLMozMapType) and self.inner == other.inner
@@ -1936,7 +2032,7 @@ class IDLMozMapType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
- self.name = self.inner.name
+ self.name = self.inner.name + "MozMap"
return self
def unroll(self):
@@ -1970,6 +2066,10 @@ class IDLUnionType(IDLType):
def __eq__(self, other):
return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes
+ def __hash__(self):
+ assert self.isComplete()
+ return self.name.__hash__()
+
def isVoid(self):
return False
@@ -2001,9 +2101,6 @@ class IDLUnionType(IDLType):
return typeName(type._identifier.object())
if isinstance(type, IDLObjectWithIdentifier):
return typeName(type.identifier)
- if (isinstance(type, IDLType) and
- (type.isArray() or type.isSequence() or type.isMozMap)):
- return str(type)
return type.name
for (i, type) in enumerate(self.memberTypes):
@@ -2114,7 +2211,7 @@ class IDLArrayType(IDLType):
def isDOMString(self):
return False
- def isScalarValueString(self):
+ def isUSVString(self):
return False
def isVoid(self):
@@ -2212,8 +2309,8 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isDOMString(self):
return self.inner.isDOMString()
- def isScalarValueString(self):
- return self.inner.isScalarValueString()
+ def isUSVString(self):
+ return self.inner.isUSVString()
def isVoid(self):
return self.inner.isVoid()
@@ -2313,7 +2410,7 @@ class IDLWrapperType(IDLType):
def isDOMString(self):
return False
- def isScalarValueString(self):
+ def isUSVString(self):
return False
def isVoid(self):
@@ -2387,7 +2484,8 @@ class IDLWrapperType(IDLType):
other.isDate())
if self.isDictionary() and other.nullable():
return False
- if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
+ if (other.isPrimitive() or other.isString() or other.isEnum() or
+ other.isDate() or other.isSequence()):
return True
if self.isDictionary():
return other.isNonCallbackInterface()
@@ -2405,7 +2503,7 @@ class IDLWrapperType(IDLType):
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
- other.isSequence() or other.isMozMap() or other.isArray()):
+ other.isMozMap() or other.isArray()):
return self.isNonCallbackInterface()
# Not much else |other| can be
@@ -2441,6 +2539,13 @@ class IDLWrapperType(IDLType):
# 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 IDLBuiltinType(IDLType):
@@ -2466,7 +2571,7 @@ class IDLBuiltinType(IDLType):
'any',
'domstring',
'bytestring',
- 'scalarvaluestring',
+ 'usvstring',
'object',
'date',
'void',
@@ -2501,7 +2606,7 @@ class IDLBuiltinType(IDLType):
Types.any: IDLType.Tags.any,
Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
- Types.scalarvaluestring: IDLType.Tags.scalarvaluestring,
+ Types.usvstring: IDLType.Tags.usvstring,
Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void,
@@ -2535,7 +2640,7 @@ class IDLBuiltinType(IDLType):
def isString(self):
return self._typeTag == IDLBuiltinType.Types.domstring or \
self._typeTag == IDLBuiltinType.Types.bytestring or \
- self._typeTag == IDLBuiltinType.Types.scalarvaluestring
+ self._typeTag == IDLBuiltinType.Types.usvstring
def isByteString(self):
return self._typeTag == IDLBuiltinType.Types.bytestring
@@ -2543,8 +2648,8 @@ class IDLBuiltinType(IDLType):
def isDOMString(self):
return self._typeTag == IDLBuiltinType.Types.domstring
- def isScalarValueString(self):
- return self._typeTag == IDLBuiltinType.Types.scalarvaluestring
+ def isUSVString(self):
+ return self._typeTag == IDLBuiltinType.Types.usvstring
def isInteger(self):
return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
@@ -2698,9 +2803,9 @@ BuiltinTypes = {
IDLBuiltinType.Types.bytestring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
IDLBuiltinType.Types.bytestring),
- IDLBuiltinType.Types.scalarvaluestring:
- IDLBuiltinType(BuiltinLocation("<builtin type>"), "ScalarValueString",
- IDLBuiltinType.Types.scalarvaluestring),
+ IDLBuiltinType.Types.usvstring:
+ IDLBuiltinType(BuiltinLocation("<builtin type>"), "USVString",
+ IDLBuiltinType.Types.usvstring),
IDLBuiltinType.Types.object:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
IDLBuiltinType.Types.object),
@@ -2835,10 +2940,10 @@ class IDLValue(IDLObject):
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
% self.value, [location]);
return self
- elif self.type.isString() and type.isScalarValueString():
- # Allow ScalarValueStrings to use default value just like
+ 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 ScalarValueString just like DOMString, but with an
+ # treats USVString just like DOMString, but with an
# extra normalization step.
assert self.type.isDOMString()
return self
@@ -2923,7 +3028,7 @@ class IDLUndefinedValue(IDLObject):
def _getDependentObjects(self):
return set()
-class IDLInterfaceMember(IDLObjectWithIdentifier):
+class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
Tags = enum(
'Const',
@@ -2936,15 +3041,14 @@ class IDLInterfaceMember(IDLObjectWithIdentifier):
'Stringifier'
)
+ AffectsValues = ("Nothing", "Everything")
+ DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
+
def __init__(self, location, identifier, tag):
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
+ IDLExposureMixins.__init__(self, location)
self.tag = tag
self._extendedAttrDict = {}
- # _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()
def isMethod(self):
return self.tag == IDLInterfaceMember.Tags.Method
@@ -2968,21 +3072,53 @@ class IDLInterfaceMember(IDLObjectWithIdentifier):
return self._extendedAttrDict.get(name, None)
def finish(self, scope):
- for globalName in self._exposureGlobalNames:
- if globalName not in scope.globalNames:
- raise WebIDLError("Unknown [Exposed] value %s" % globalName,
- [self.location])
- globalNameSetToExposureSet(scope, self._exposureGlobalNames,
- self.exposureSet)
- self._scope = scope
+ # We better be exposed _somewhere_.
+ if (len(self._exposureGlobalNames) == 0):
+ print self.identifier.name
+ assert len(self._exposureGlobalNames) != 0
+ IDLExposureMixins.finish(self, scope)
def validate(self):
if (self.getExtendedAttribute("Pref") and
- self.exposureSet != set([self._scope.primaryGlobalName])):
+ self.exposureSet != set([self._globalScope.primaryGlobalName])):
raise WebIDLError("[Pref] used on an interface member that is not "
- "%s-only" % self._scope.primaryGlobalName,
+ "%s-only" % self._globalScope.primaryGlobalName,
+ [self.location])
+
+ if (self.getExtendedAttribute("CheckPermissions") and
+ self.exposureSet != set([self._globalScope.primaryGlobalName])):
+ raise WebIDLError("[CheckPermissions] used on an interface member "
+ "that is not %s-only" %
+ self._globalScope.primaryGlobalName,
[self.location])
+ 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])
+
+ 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
+
class IDLConst(IDLInterfaceMember):
def __init__(self, location, identifier, type, value):
IDLInterfaceMember.__init__(self, location, identifier,
@@ -3061,6 +3197,8 @@ class IDLAttribute(IDLInterfaceMember):
self.enforceRange = False
self.clamp = False
self.slotIndex = None
+ self.dependsOn = "Everything"
+ self.affects = "Everything"
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
@@ -3129,11 +3267,11 @@ class IDLAttribute(IDLInterfaceMember):
if ((self.getExtendedAttribute("Cached") or
self.getExtendedAttribute("StoreInSlot")) and
- not self.getExtendedAttribute("Constant") and
- not self.getExtendedAttribute("Pure")):
+ not self.affects == "Nothing"):
raise WebIDLError("Cached attributes and attributes stored in "
- "slots must be constant or pure, since the "
- "getter won't always be called.",
+ "slots must be Constant or Pure or "
+ "Affects=Nothing, since the getter won't always "
+ "be called.",
[self.location])
if self.getExtendedAttribute("Frozen"):
if (not self.type.isSequence() and not self.type.isDictionary() and
@@ -3158,8 +3296,7 @@ class IDLAttribute(IDLInterfaceMember):
(identifier == "StoreInSlot" and
(self.getExtendedAttribute("Throws") or
self.getExtendedAttribute("GetterThrows")))):
- raise WebIDLError("Throwing things can't be [Pure] or [Constant] "
- "or [SameObject] or [StoreInSlot]",
+ raise WebIDLError("Throwing things can't be [StoreInSlot]",
[attr.location])
elif identifier == "LenientThis":
if not attr.noArguments():
@@ -3203,6 +3340,15 @@ class IDLAttribute(IDLInterfaceMember):
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.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",
@@ -3250,18 +3396,43 @@ class IDLAttribute(IDLInterfaceMember):
[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 == "Pref" or
identifier == "SetterThrows" or
- identifier == "Pure" or
identifier == "Throws" or
identifier == "GetterThrows" or
identifier == "ChromeOnly" or
- identifier == "SameObject" or
- identifier == "Constant" or
identifier == "Func" or
identifier == "Frozen" or
identifier == "AvailableIn" or
identifier == "NewObject" or
+ identifier == "UnsafeInPrerendering" or
identifier == "CheckPermissions" or
identifier == "BinaryName"):
# Known attributes that we don't need to do anything with here
@@ -3306,6 +3477,7 @@ class IDLArgument(IDLObjectWithIdentifier):
self._allowTreatNonCallableAsNull = False
assert not variadic or optional
+ assert not variadic or not defaultValue
def addExtendedAttributes(self, attrs):
attrs = self.checkForStringHandlingExtendedAttributes(
@@ -3354,9 +3526,9 @@ class IDLArgument(IDLObjectWithIdentifier):
if ((self.type.isDictionary() or
self.type.isUnion() and self.type.unroll().hasDictionaryType) and
- self.optional and not self.defaultValue):
- # Default optional dictionaries to null, for simplicity,
- # so the codegen doesn't have to special-case this.
+ self.optional and not self.defaultValue and not self.variadic):
+ # Default optional non-variadic dictionaries 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
@@ -3383,6 +3555,9 @@ class IDLArgument(IDLObjectWithIdentifier):
deps.add(self.defaultValue)
return deps
+ def canHaveMissingValue(self):
+ return self.optional and not self.defaultValue
+
class IDLCallbackType(IDLType, IDLObjectWithScope):
def __init__(self, location, parentScope, identifier, returnType, arguments):
assert isinstance(returnType, IDLType)
@@ -3442,7 +3617,8 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
# 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.isDate())
+ other.isNonCallbackInterface() or other.isDate() or
+ other.isSequence())
def addExtendedAttributes(self, attrs):
unhandledAttrs = []
@@ -3538,6 +3714,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
self._jsonifier = jsonifier
self._specialType = specialType
self._unforgeable = False
+ self.dependsOn = "Everything"
+ self.affects = "Everything"
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static operation must not be 'prototype'",
@@ -3618,7 +3796,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
return self._hasOverloads
def isIdentifierLess(self):
- return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
+ return self.identifier.name[:2] == "__"
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
@@ -3849,16 +4027,32 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
[attr.location, self.location])
elif identifier == "Exposed":
convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
- elif (identifier == "Pure" or
- identifier == "CrossOriginCallable" or
+ elif (identifier == "CrossOriginCallable" or
identifier == "WebGLHandlesContextLoss"):
# Known no-argument attributes.
if not attr.noArguments():
raise WebIDLError("[%s] must take no arguments" % identifier,
[attr.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 == "Throws" or
identifier == "NewObject" or
identifier == "ChromeOnly" or
+ identifier == "UnsafeInPrerendering" or
identifier == "Pref" or
identifier == "Func" or
identifier == "AvailableIn" or
@@ -3880,7 +4074,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def _getDependentObjects(self):
deps = set()
for overload in self._overloads:
- deps.union(overload._getDependentObjects())
+ deps.update(overload._getDependentObjects())
return deps
class IDLImplementsStatement(IDLObject):
@@ -3888,8 +4082,11 @@ class IDLImplementsStatement(IDLObject):
IDLObject.__init__(self, location)
self.implementor = implementor;
self.implementee = implementee
+ self._finished = False
def finish(self, scope):
+ if self._finished:
+ return
assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
implementor = self.implementor.finish(scope)
@@ -3914,6 +4111,8 @@ class IDLImplementsStatement(IDLObject):
"interface",
[self.implementee.location])
implementor.addImplementedInterface(implementee)
+ self.implementor = implementor
+ self.implementee = implementee
def validate(self):
pass
@@ -4044,7 +4243,7 @@ class Tokenizer(object):
"Date": "DATE",
"DOMString": "DOMSTRING",
"ByteString": "BYTESTRING",
- "ScalarValueString": "SCALARVALUESTRING",
+ "USVString": "USVSTRING",
"any": "ANY",
"boolean": "BOOLEAN",
"byte": "BYTE",
@@ -4053,8 +4252,8 @@ class Tokenizer(object):
"long": "LONG",
"object": "OBJECT",
"octet": "OCTET",
- "optional": "OPTIONAL",
"Promise": "PROMISE",
+ "required": "REQUIRED",
"sequence": "SEQUENCE",
"MozMap": "MOZMAP",
"short": "SHORT",
@@ -4339,15 +4538,21 @@ class Parser(Tokenizer):
def p_DictionaryMember(self, p):
"""
- DictionaryMember : Type IDENTIFIER Default SEMICOLON
+ DictionaryMember : Required Type IDENTIFIER Default SEMICOLON
"""
# These quack a lot like optional arguments, so just treat them that way.
- t = p[1]
+ t = p[2]
assert isinstance(t, IDLType)
- identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
- defaultValue = p[3]
+ identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
+ defaultValue = p[4]
+ optional = not p[1]
+
+ if not optional and defaultValue:
+ raise WebIDLError("Required dictionary members can't have a default value.",
+ [self.getLocation(p, 4)])
- p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
+ p[0] = IDLArgument(self.getLocation(p, 3), identifier, t,
+ optional=optional,
defaultValue=defaultValue, variadic=False,
dictionaryMember=True)
@@ -4545,7 +4750,7 @@ class Parser(Tokenizer):
def p_AttributeRest(self, p):
"""
- AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON
+ AttributeRest : ReadOnly ATTRIBUTE Type AttributeName SEMICOLON
"""
location = self.getLocation(p, 2)
readonly = p[1]
@@ -4874,6 +5079,7 @@ class Parser(Tokenizer):
| INTERFACE
| LEGACYCALLER
| PARTIAL
+ | REQUIRED
| SERIALIZER
| SETTER
| STATIC
@@ -4884,6 +5090,13 @@ class Parser(Tokenizer):
"""
p[0] = p[1]
+ def p_AttributeName(self, p):
+ """
+ AttributeName : IDENTIFIER
+ | REQUIRED
+ """
+ p[0] = p[1]
+
def p_Optional(self, p):
"""
Optional : OPTIONAL
@@ -4896,6 +5109,18 @@ class Parser(Tokenizer):
"""
p[0] = False
+ def p_Required(self, p):
+ """
+ Required : REQUIRED
+ """
+ p[0] = True
+
+ def p_RequiredEmpty(self, p):
+ """
+ Required :
+ """
+ p[0] = False
+
def p_Ellipsis(self, p):
"""
Ellipsis : ELLIPSIS
@@ -4982,7 +5207,7 @@ class Parser(Tokenizer):
| DATE
| DOMSTRING
| BYTESTRING
- | SCALARVALUESTRING
+ | USVSTRING
| ANY
| ATTRIBUTE
| BOOLEAN
@@ -5255,11 +5480,11 @@ class Parser(Tokenizer):
"""
p[0] = IDLBuiltinType.Types.bytestring
- def p_PrimitiveOrStringTypeScalarValueString(self, p):
+ def p_PrimitiveOrStringTypeUSVString(self, p):
"""
- PrimitiveOrStringType : SCALARVALUESTRING
+ PrimitiveOrStringType : USVSTRING
"""
- p[0] = IDLBuiltinType.Types.scalarvaluestring
+ p[0] = IDLBuiltinType.Types.usvstring
def p_UnsignedIntegerTypeUnsigned(self, p):
"""
@@ -5473,6 +5698,10 @@ class Parser(Tokenizer):
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
+ # And we add the special-cased "System" global name, which
+ # doesn't have any corresponding interfaces.
+ self._globalScope.globalNames.add("System")
+ self._globalScope.globalNameMapping["System"].add("BackstagePass")
self._installBuiltins(self._globalScope)
self._productions = []
@@ -5548,6 +5777,7 @@ class Parser(Tokenizer):
# Builtin IDL defined by WebIDL
_builtins = """
typedef unsigned long long DOMTimeStamp;
+ typedef (ArrayBufferView or ArrayBuffer) BufferSource;
"""
def main():
diff --git a/components/script/dom/bindings/codegen/parser/external.patch b/components/script/dom/bindings/codegen/parser/external.patch
index 9464511a9d0..964a6d8774a 100644
--- a/components/script/dom/bindings/codegen/parser/external.patch
+++ b/components/script/dom/bindings/codegen/parser/external.patch
@@ -1,16 +1,18 @@
--- WebIDL.py
+++ WebIDL.py
-@@ -450,44 +450,8 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
+@@ -505,46 +505,8 @@ class IDLExposureMixins():
- class IDLExternalInterface(IDLObjectWithIdentifier):
+ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def __init__(self, location, parentScope, identifier):
- assert isinstance(identifier, IDLUnresolvedIdentifier)
- assert isinstance(parentScope, IDLScope)
- self.parent = None
- IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
+- IDLExposureMixins.__init__(self, location)
- IDLObjectWithIdentifier.resolve(self, parentScope)
-
- def finish(self, scope):
+- IDLExposureMixins.finish(self, scope)
- pass
-
- def validate(self):
diff --git a/components/script/dom/bindings/codegen/parser/module.patch b/components/script/dom/bindings/codegen/parser/module.patch
index f2ed1aff944..aaec7c61b7e 100644
--- a/components/script/dom/bindings/codegen/parser/module.patch
+++ b/components/script/dom/bindings/codegen/parser/module.patch
@@ -1,15 +1,16 @@
--- WebIDL.py
+++ WebIDL.py
-@@ -1422,6 +1422,9 @@ class IDLDictionary(IDLObjectWithScope):
+@@ -1506,6 +1506,9 @@ class IDLDictionary(IDLObjectWithScope):
self.identifier.name,
[member.location] + locations)
-
+
+ def module(self):
+ return self.location.filename().split('/')[-1].split('.webidl')[0] + 'Binding'
+
def addExtendedAttributes(self, attrs):
assert len(attrs) == 0
-@@ -3398,6 +3398,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
+
+@@ -3574,6 +3577,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
self._treatNonCallableAsNull = False
self._treatNonObjectAsNull = False