aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/codegen/parser/WebIDL.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/dom/bindings/codegen/parser/WebIDL.py')
-rw-r--r--src/components/script/dom/bindings/codegen/parser/WebIDL.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/components/script/dom/bindings/codegen/parser/WebIDL.py b/src/components/script/dom/bindings/codegen/parser/WebIDL.py
index 1aab3debc6a..046b8130dff 100644
--- a/src/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/src/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -146,6 +146,23 @@ class IDLObject(object):
def isCallback(self):
return False
+ def isSingleOperationInterface(self):
+ assert self.isCallback() or self.isJSImplemented()
+ return (
+ # JS-implemented things should never need the
+ # this-handling weirdness of single-operation interfaces.
+ not self.isJSImplemented() and
+ # Not inheriting from another interface
+ not self.parent and
+ # No consequential interfaces
+ len(self.getConsequentialInterfaces()) == 0 and
+ # No attributes of any kinds
+ not any(m.isAttr() for m in self.members) and
+ # There is at least one regular operation, and all regular
+ # operations have the same identifier
+ len(set(m.identifier.name for m in self.members if
+ m.isMethod() and not m.isStatic())) == 1)
+
def isType(self):
return False
@@ -167,6 +184,38 @@ class IDLObject(object):
def handleExtendedAttribute(self, attr):
assert False # Override me!
+ def _getDependentObjects(self):
+ assert False # Override me!
+
+ def getDeps(self, visited=None):
+ """ Return a set of files that this object depends on. If any of
+ these files are changed the parser needs to be rerun to regenerate
+ a new IDLObject.
+
+ The visited argument is a set of all the objects already visited.
+ We must test to see if we are in it, and if so, do nothing. This
+ prevents infinite recursion."""
+
+ # NB: We can't use visited=set() above because the default value is
+ # evaluated when the def statement is evaluated, not when the function
+ # is executed, so there would be one set for all invocations.
+ if visited == None:
+ visited = set()
+
+ if self in visited:
+ return set()
+
+ visited.add(self)
+
+ deps = set()
+ if self.filename() != "<builtin>":
+ deps.add(self.filename())
+
+ for d in self._getDependentObjects():
+ deps = deps.union(d.getDeps(visited))
+
+ return deps
+
class IDLScope(IDLObject):
def __init__(self, location, parentScope, identifier):
IDLObject.__init__(self, location)
@@ -428,6 +477,15 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
def resolve(self, parentScope):
pass
+ def getJSImplementation(self):
+ return None
+
+ def isJSImplemented(self):
+ return False
+
+ def _getDependentObjects(self):
+ return set()
+
class IDLInterface(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members,
isPartial):
@@ -777,6 +835,24 @@ class IDLInterface(IDLObjectWithScope):
# Put the new members at the beginning
self.members = members + self.members
+ def getJSImplementation(self):
+ classId = self.getExtendedAttribute("JSImplementation")
+ if not classId:
+ return classId
+ assert isinstance(classId, list)
+ assert len(classId) == 1
+ return classId[0]
+
+ def isJSImplemented(self):
+ return bool(self.getJSImplementation())
+
+ def _getDependentObjects(self):
+ deps = set(self.members)
+ deps.union(self.implementedInterfaces)
+ if self.parent:
+ deps.add(self.parent)
+ return deps
+
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@@ -847,6 +923,11 @@ class IDLDictionary(IDLObjectWithScope):
def addExtendedAttributes(self, attrs):
assert len(attrs) == 0
+ def _getDependentObjects(self):
+ deps = set(self.members)
+ if (self.parent):
+ deps.add(self.parent)
+ return deps
class IDLEnum(IDLObjectWithIdentifier):
def __init__(self, location, parentScope, name, values):
@@ -875,6 +956,9 @@ class IDLEnum(IDLObjectWithIdentifier):
def addExtendedAttributes(self, attrs):
assert len(attrs) == 0
+ def _getDependentObjects(self):
+ return set()
+
class IDLType(IDLObject):
Tags = enum(
# The integer types
@@ -893,6 +977,7 @@ class IDLType(IDLObject):
# Other types
'any',
'domstring',
+ 'bytestring',
'object',
'date',
'void',
@@ -930,6 +1015,12 @@ class IDLType(IDLObject):
def isString(self):
return False
+ def isByteString(self):
+ return False
+
+ def isDOMString(self):
+ return False
+
def isVoid(self):
return self.name == "Void"
@@ -1075,6 +1166,12 @@ class IDLNullableType(IDLType):
def isString(self):
return self.inner.isString()
+ def isByteString(self):
+ return self.inner.isByteString()
+
+ def isDOMString(self):
+ return self.inner.isDOMString()
+
def isFloat(self):
return self.inner.isFloat()
@@ -1163,6 +1260,9 @@ class IDLNullableType(IDLType):
return False
return self.inner.isDistinguishableFrom(other)
+ def _getDependentObjects(self):
+ return self.inner._getDependentObjects()
+
class IDLSequenceType(IDLType):
def __init__(self, location, parameterType):
assert not parameterType.isVoid()
@@ -1231,6 +1331,9 @@ class IDLSequenceType(IDLType):
other.isDictionary() or other.isDate() or
other.isNonCallbackInterface())
+ def _getDependentObjects(self):
+ return self.inner._getDependentObjects()
+
class IDLUnionType(IDLType):
def __init__(self, location, memberTypes):
IDLType.__init__(self, location, "")
@@ -1317,6 +1420,9 @@ class IDLUnionType(IDLType):
return False
return True
+ def _getDependentObjects(self):
+ return set(self.memberTypes)
+
class IDLArrayType(IDLType):
def __init__(self, location, parameterType):
assert not parameterType.isVoid()
@@ -1393,6 +1499,9 @@ class IDLArrayType(IDLType):
other.isDictionary() or other.isDate() or
other.isNonCallbackInterface())
+ def _getDependentObjects(self):
+ return self.inner._getDependentObjects()
+
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def __init__(self, location, innerType, name):
IDLType.__init__(self, location, innerType.name)
@@ -1478,6 +1587,9 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isDistinguishableFrom(self, other):
return self.inner.isDistinguishableFrom(other)
+ def _getDependentObjects(self):
+ return self.inner._getDependentObjects()
+
class IDLWrapperType(IDLType):
def __init__(self, location, inner):
IDLType.__init__(self, location, inner.identifier.name)
@@ -1583,6 +1695,23 @@ class IDLWrapperType(IDLType):
assert other.isObject()
return False
+ def _getDependentObjects(self):
+ # NB: The codegen for an interface type depends on
+ # a) That the identifier is in fact an interface (as opposed to
+ # a dictionary or something else).
+ # b) The native type of the interface.
+ # If we depend on the interface object we will also depend on
+ # anything the interface depends on which is undesirable. We
+ # considered implementing a dependency just on the interface type
+ # file, but then every modification to an interface would cause this
+ # to be regenerated which is still undesirable. We decided not to
+ # depend on anything, reasoning that:
+ # 1) Changing the concrete type of the interface requires modifying
+ # Bindings.conf, which is still a global dependency.
+ # 2) Changing an interface to a dictionary (or vice versa) with the
+ # same identifier should be incredibly rare.
+ return set()
+
class IDLBuiltinType(IDLType):
Types = enum(
@@ -1602,6 +1731,7 @@ class IDLBuiltinType(IDLType):
# Other types
'any',
'domstring',
+ 'bytestring',
'object',
'date',
'void',
@@ -1633,6 +1763,7 @@ class IDLBuiltinType(IDLType):
Types.double: IDLType.Tags.double,
Types.any: IDLType.Tags.any,
Types.domstring: IDLType.Tags.domstring,
+ Types.bytestring: IDLType.Tags.bytestring,
Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void,
@@ -1658,6 +1789,13 @@ class IDLBuiltinType(IDLType):
return self._typeTag <= IDLBuiltinType.Types.double
def isString(self):
+ return self._typeTag == IDLBuiltinType.Types.domstring or \
+ self._typeTag == IDLBuiltinType.Types.bytestring
+
+ def isByteString(self):
+ return self._typeTag == IDLBuiltinType.Types.bytestring
+
+ def isDOMString(self):
return self._typeTag == IDLBuiltinType.Types.domstring
def isInteger(self):
@@ -1733,6 +1871,9 @@ class IDLBuiltinType(IDLType):
(self.isTypedArray() and not other.isArrayBufferView() and not
(other.isTypedArray() and other.name == self.name)))))
+ def _getDependentObjects(self):
+ return set()
+
BuiltinTypes = {
IDLBuiltinType.Types.byte:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
@@ -1877,6 +2018,9 @@ class IDLValue(IDLObject):
raise WebIDLError("Cannot coerce type %s to type %s." %
(self.type, type), [location])
+ def _getDependentObjects(self):
+ return set()
+
class IDLNullValue(IDLObject):
def __init__(self, location):
IDLObject.__init__(self, location)
@@ -1895,6 +2039,9 @@ class IDLNullValue(IDLObject):
nullValue.type = type
return nullValue
+ def _getDependentObjects(self):
+ return set()
+
class IDLInterfaceMember(IDLObjectWithIdentifier):
@@ -1966,6 +2113,9 @@ class IDLConst(IDLInterfaceMember):
def validate(self):
pass
+ def _getDependentObjects(self):
+ return set([self.type, self.value])
+
class IDLAttribute(IDLInterfaceMember):
def __init__(self, location, identifier, type, readonly, inherit,
static=False):
@@ -2052,6 +2202,9 @@ class IDLAttribute(IDLInterfaceMember):
def hasLenientThis(self):
return self.lenientThis
+ def _getDependentObjects(self):
+ return set([self.type])
+
class IDLArgument(IDLObjectWithIdentifier):
def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
@@ -2124,6 +2277,12 @@ class IDLArgument(IDLObjectWithIdentifier):
self.location)
assert self.defaultValue
+ def _getDependentObjects(self):
+ deps = set([self.type])
+ if self.defaultValue:
+ deps.add(self.defaultValue)
+ return deps
+
class IDLCallbackType(IDLType, IDLObjectWithScope):
def __init__(self, location, parentScope, identifier, returnType, arguments):
assert isinstance(returnType, IDLType)
@@ -2179,6 +2338,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isNonCallbackInterface() or other.isDate())
+ def _getDependentObjects(self):
+ return set([self._returnType] + self._arguments)
+
class IDLMethodOverload:
"""
A class that represents a single overload of a WebIDL method. This is not
@@ -2194,6 +2356,11 @@ class IDLMethodOverload:
self.arguments = list(arguments)
self.location = location
+ def _getDependentObjects(self):
+ deps = set(self.arguments)
+ deps.add(self.returnType)
+ return deps
+
class IDLMethod(IDLInterfaceMember, IDLScope):
Special = enum(
@@ -2494,6 +2661,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
[attr.location, self.location])
IDLInterfaceMember.handleExtendedAttribute(self, attr)
+ def _getDependentObjects(self):
+ deps = set()
+ for overload in self._overloads:
+ deps.union(overload._getDependentObjects())
+ return deps
+
class IDLImplementsStatement(IDLObject):
def __init__(self, location, implementor, implementee):
IDLObject.__init__(self, location)