mirror of
https://github.com/servo/servo.git
synced 2025-07-28 09:40:33 +01:00
Update WebIDL parser
This commit is contained in:
parent
06947965b1
commit
c1718a0b1f
1 changed files with 376 additions and 318 deletions
|
@ -540,6 +540,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def isIteratorInterface(self):
|
||||||
|
return False
|
||||||
|
|
||||||
def isExternal(self):
|
def isExternal(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -640,7 +643,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
self._callback = False
|
self._callback = False
|
||||||
self._finished = False
|
self._finished = False
|
||||||
self.members = []
|
self.members = []
|
||||||
self.maplikeOrSetlike = None
|
self.maplikeOrSetlikeOrIterable = None
|
||||||
self._partialInterfaces = []
|
self._partialInterfaces = []
|
||||||
self._extendedAttrDict = {}
|
self._extendedAttrDict = {}
|
||||||
# namedConstructors needs deterministic ordering because bindings code
|
# namedConstructors needs deterministic ordering because bindings code
|
||||||
|
@ -664,6 +667,9 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
self.totalMembersInSlots = 0
|
self.totalMembersInSlots = 0
|
||||||
# Tracking of the number of own own members we have in slots
|
# Tracking of the number of own own members we have in slots
|
||||||
self._ownMembersInSlots = 0
|
self._ownMembersInSlots = 0
|
||||||
|
# If this is an iterator interface, we need to know what iterable
|
||||||
|
# interface we're iterating for in order to get its nativeType.
|
||||||
|
self.iterableInterface = None
|
||||||
|
|
||||||
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
||||||
IDLExposureMixins.__init__(self, location)
|
IDLExposureMixins.__init__(self, location)
|
||||||
|
@ -682,6 +688,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def isIterable(self):
|
||||||
|
return (self.maplikeOrSetlikeOrIterable and
|
||||||
|
self.maplikeOrSetlikeOrIterable.isIterable())
|
||||||
|
|
||||||
|
def isIteratorInterface(self):
|
||||||
|
return self.iterableInterface is not None
|
||||||
|
|
||||||
def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
|
def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject):
|
||||||
assert isinstance(scope, IDLScope)
|
assert isinstance(scope, IDLScope)
|
||||||
assert isinstance(originalObject, IDLInterfaceMember)
|
assert isinstance(originalObject, IDLInterfaceMember)
|
||||||
|
@ -718,22 +731,22 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
# need to be treated like regular interface members, do this before
|
# need to be treated like regular interface members, do this before
|
||||||
# things like exposure setting.
|
# things like exposure setting.
|
||||||
for member in self.members:
|
for member in self.members:
|
||||||
if member.isMaplikeOrSetlike():
|
if member.isMaplikeOrSetlikeOrIterable():
|
||||||
# Check that we only have one interface declaration (currently
|
# Check that we only have one interface declaration (currently
|
||||||
# there can only be one maplike/setlike declaration per
|
# there can only be one maplike/setlike declaration per
|
||||||
# interface)
|
# interface)
|
||||||
if self.maplikeOrSetlike:
|
if self.maplikeOrSetlikeOrIterable:
|
||||||
raise WebIDLError("%s declaration used on "
|
raise WebIDLError("%s declaration used on "
|
||||||
"interface that already has %s "
|
"interface that already has %s "
|
||||||
"declaration" %
|
"declaration" %
|
||||||
(member.maplikeOrSetlikeType,
|
(member.maplikeOrSetlikeOrIterableType,
|
||||||
self.maplikeOrSetlike.maplikeOrSetlikeType),
|
self.maplikeOrSetlikeOrIterable.maplikeOrSetlikeOrIterableType),
|
||||||
[self.maplikeOrSetlike.location,
|
[self.maplikeOrSetlikeOrIterable.location,
|
||||||
member.location])
|
member.location])
|
||||||
self.maplikeOrSetlike = member
|
self.maplikeOrSetlikeOrIterable = member
|
||||||
# If we've got a maplike or setlike declaration, we'll be building all of
|
# If we've got a maplike or setlike declaration, we'll be building all of
|
||||||
# our required methods in Codegen. Generate members now.
|
# our required methods in Codegen. Generate members now.
|
||||||
self.maplikeOrSetlike.expand(self.members, self.isJSImplemented())
|
self.maplikeOrSetlikeOrIterable.expand(self.members, self.isJSImplemented())
|
||||||
|
|
||||||
# Now that we've merged in our partial interfaces, set the
|
# Now that we've merged in our partial interfaces, set the
|
||||||
# _exposureGlobalNames on any members that don't have it set yet. Note
|
# _exposureGlobalNames on any members that don't have it set yet. Note
|
||||||
|
@ -884,14 +897,14 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
|
|
||||||
# If we have a maplike or setlike, and the consequential interface
|
# If we have a maplike or setlike, and the consequential interface
|
||||||
# also does, throw an error.
|
# also does, throw an error.
|
||||||
if iface.maplikeOrSetlike and self.maplikeOrSetlike:
|
if iface.maplikeOrSetlikeOrIterable and self.maplikeOrSetlikeOrIterable:
|
||||||
raise WebIDLError("Maplike/setlike interface %s cannot have "
|
raise WebIDLError("Maplike/setlike/iterable interface %s cannot have "
|
||||||
"maplike/setlike interface %s as a "
|
"maplike/setlike/iterable interface %s as a "
|
||||||
"consequential interface" %
|
"consequential interface" %
|
||||||
(self.identifier.name,
|
(self.identifier.name,
|
||||||
iface.identifier.name),
|
iface.identifier.name),
|
||||||
[self.maplikeOrSetlike.location,
|
[self.maplikeOrSetlikeOrIterable.location,
|
||||||
iface.maplikeOrSetlike.location])
|
iface.maplikeOrSetlikeOrIterable.location])
|
||||||
additionalMembers = iface.originalMembers
|
additionalMembers = iface.originalMembers
|
||||||
for additionalMember in additionalMembers:
|
for additionalMember in additionalMembers:
|
||||||
for member in self.members:
|
for member in self.members:
|
||||||
|
@ -905,15 +918,15 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
|
|
||||||
for ancestor in self.getInheritedInterfaces():
|
for ancestor in self.getInheritedInterfaces():
|
||||||
ancestor.interfacesBasedOnSelf.add(self)
|
ancestor.interfacesBasedOnSelf.add(self)
|
||||||
if (ancestor.maplikeOrSetlike is not None and
|
if (ancestor.maplikeOrSetlikeOrIterable is not None and
|
||||||
self.maplikeOrSetlike is not None):
|
self.maplikeOrSetlikeOrIterable is not None):
|
||||||
raise WebIDLError("Cannot have maplike/setlike on %s that "
|
raise WebIDLError("Cannot have maplike/setlike on %s that "
|
||||||
"inherits %s, which is already "
|
"inherits %s, which is already "
|
||||||
"maplike/setlike" %
|
"maplike/setlike" %
|
||||||
(self.identifier.name,
|
(self.identifier.name,
|
||||||
ancestor.identifier.name),
|
ancestor.identifier.name),
|
||||||
[self.maplikeOrSetlike.location,
|
[self.maplikeOrSetlikeOrIterable.location,
|
||||||
ancestor.maplikeOrSetlike.location])
|
ancestor.maplikeOrSetlikeOrIterable.location])
|
||||||
for ancestorConsequential in ancestor.getConsequentialInterfaces():
|
for ancestorConsequential in ancestor.getConsequentialInterfaces():
|
||||||
ancestorConsequential.interfacesBasedOnSelf.add(self)
|
ancestorConsequential.interfacesBasedOnSelf.add(self)
|
||||||
|
|
||||||
|
@ -997,11 +1010,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
# At this point, we have all of our members. If the current interface
|
# At this point, we have all of our members. If the current interface
|
||||||
# uses maplike/setlike, check for collisions anywhere in the current
|
# uses maplike/setlike, check for collisions anywhere in the current
|
||||||
# interface or higher in the inheritance chain.
|
# interface or higher in the inheritance chain.
|
||||||
if self.maplikeOrSetlike:
|
if self.maplikeOrSetlikeOrIterable:
|
||||||
testInterface = self
|
testInterface = self
|
||||||
isAncestor = False
|
isAncestor = False
|
||||||
while testInterface:
|
while testInterface:
|
||||||
self.maplikeOrSetlike.checkCollisions(testInterface.members,
|
self.maplikeOrSetlikeOrIterable.checkCollisions(testInterface.members,
|
||||||
isAncestor)
|
isAncestor)
|
||||||
isAncestor = True
|
isAncestor = True
|
||||||
testInterface = testInterface.parent
|
testInterface = testInterface.parent
|
||||||
|
@ -1411,7 +1424,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||||
identifier == "AvailableIn" or
|
identifier == "AvailableIn" or
|
||||||
identifier == "Func" or
|
identifier == "Func" or
|
||||||
identifier == "CheckAnyPermissions" or
|
identifier == "CheckAnyPermissions" or
|
||||||
identifier == "CheckAllPermissions"):
|
identifier == "CheckAllPermissions" or
|
||||||
|
identifier == "Deprecated"):
|
||||||
# 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,
|
||||||
|
@ -1821,15 +1835,9 @@ class IDLType(IDLObject):
|
||||||
def isSharedArrayBuffer(self):
|
def isSharedArrayBuffer(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isSharedArrayBufferView(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def isTypedArray(self):
|
def isTypedArray(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isSharedTypedArray(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def isCallbackInterface(self):
|
def isCallbackInterface(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1850,9 +1858,7 @@ class IDLType(IDLObject):
|
||||||
return self.isInterface() and (self.isArrayBuffer() or
|
return self.isInterface() and (self.isArrayBuffer() or
|
||||||
self.isArrayBufferView() or
|
self.isArrayBufferView() or
|
||||||
self.isSharedArrayBuffer() or
|
self.isSharedArrayBuffer() or
|
||||||
self.isSharedArrayBufferView() or
|
self.isTypedArray())
|
||||||
self.isTypedArray() or
|
|
||||||
self.isSharedTypedArray())
|
|
||||||
|
|
||||||
def isDictionary(self):
|
def isDictionary(self):
|
||||||
return False
|
return False
|
||||||
|
@ -2039,15 +2045,9 @@ class IDLNullableType(IDLType):
|
||||||
def isSharedArrayBuffer(self):
|
def isSharedArrayBuffer(self):
|
||||||
return self.inner.isSharedArrayBuffer()
|
return self.inner.isSharedArrayBuffer()
|
||||||
|
|
||||||
def isSharedArrayBufferView(self):
|
|
||||||
return self.inner.isSharedArrayBufferView()
|
|
||||||
|
|
||||||
def isTypedArray(self):
|
def isTypedArray(self):
|
||||||
return self.inner.isTypedArray()
|
return self.inner.isTypedArray()
|
||||||
|
|
||||||
def isSharedTypedArray(self):
|
|
||||||
return self.inner.isSharedTypedArray()
|
|
||||||
|
|
||||||
def isDictionary(self):
|
def isDictionary(self):
|
||||||
return self.inner.isDictionary()
|
return self.inner.isDictionary()
|
||||||
|
|
||||||
|
@ -2554,15 +2554,9 @@ class IDLTypedefType(IDLType):
|
||||||
def isSharedArrayBuffer(self):
|
def isSharedArrayBuffer(self):
|
||||||
return self.inner.isSharedArrayBuffer()
|
return self.inner.isSharedArrayBuffer()
|
||||||
|
|
||||||
def isSharedArrayBufferView(self):
|
|
||||||
return self.inner.isSharedArrayBufferView()
|
|
||||||
|
|
||||||
def isTypedArray(self):
|
def isTypedArray(self):
|
||||||
return self.inner.isTypedArray()
|
return self.inner.isTypedArray()
|
||||||
|
|
||||||
def isSharedTypedArray(self):
|
|
||||||
return self.inner.isSharedTypedArray()
|
|
||||||
|
|
||||||
def isInterface(self):
|
def isInterface(self):
|
||||||
return self.inner.isInterface()
|
return self.inner.isInterface()
|
||||||
|
|
||||||
|
@ -2832,7 +2826,6 @@ class IDLBuiltinType(IDLType):
|
||||||
'ArrayBuffer',
|
'ArrayBuffer',
|
||||||
'ArrayBufferView',
|
'ArrayBufferView',
|
||||||
'SharedArrayBuffer',
|
'SharedArrayBuffer',
|
||||||
'SharedArrayBufferView',
|
|
||||||
'Int8Array',
|
'Int8Array',
|
||||||
'Uint8Array',
|
'Uint8Array',
|
||||||
'Uint8ClampedArray',
|
'Uint8ClampedArray',
|
||||||
|
@ -2841,16 +2834,7 @@ class IDLBuiltinType(IDLType):
|
||||||
'Int32Array',
|
'Int32Array',
|
||||||
'Uint32Array',
|
'Uint32Array',
|
||||||
'Float32Array',
|
'Float32Array',
|
||||||
'Float64Array',
|
'Float64Array'
|
||||||
'SharedInt8Array',
|
|
||||||
'SharedUint8Array',
|
|
||||||
'SharedUint8ClampedArray',
|
|
||||||
'SharedInt16Array',
|
|
||||||
'SharedUint16Array',
|
|
||||||
'SharedInt32Array',
|
|
||||||
'SharedUint32Array',
|
|
||||||
'SharedFloat32Array',
|
|
||||||
'SharedFloat64Array'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
TagLookup = {
|
TagLookup = {
|
||||||
|
@ -2877,7 +2861,6 @@ class IDLBuiltinType(IDLType):
|
||||||
Types.ArrayBuffer: IDLType.Tags.interface,
|
Types.ArrayBuffer: IDLType.Tags.interface,
|
||||||
Types.ArrayBufferView: IDLType.Tags.interface,
|
Types.ArrayBufferView: IDLType.Tags.interface,
|
||||||
Types.SharedArrayBuffer: IDLType.Tags.interface,
|
Types.SharedArrayBuffer: IDLType.Tags.interface,
|
||||||
Types.SharedArrayBufferView: IDLType.Tags.interface,
|
|
||||||
Types.Int8Array: IDLType.Tags.interface,
|
Types.Int8Array: IDLType.Tags.interface,
|
||||||
Types.Uint8Array: IDLType.Tags.interface,
|
Types.Uint8Array: IDLType.Tags.interface,
|
||||||
Types.Uint8ClampedArray: IDLType.Tags.interface,
|
Types.Uint8ClampedArray: IDLType.Tags.interface,
|
||||||
|
@ -2886,16 +2869,7 @@ class IDLBuiltinType(IDLType):
|
||||||
Types.Int32Array: IDLType.Tags.interface,
|
Types.Int32Array: IDLType.Tags.interface,
|
||||||
Types.Uint32Array: IDLType.Tags.interface,
|
Types.Uint32Array: IDLType.Tags.interface,
|
||||||
Types.Float32Array: IDLType.Tags.interface,
|
Types.Float32Array: IDLType.Tags.interface,
|
||||||
Types.Float64Array: IDLType.Tags.interface,
|
Types.Float64Array: IDLType.Tags.interface
|
||||||
Types.SharedInt8Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedUint8Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedUint8ClampedArray: IDLType.Tags.interface,
|
|
||||||
Types.SharedInt16Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedUint16Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedInt32Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedUint32Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedFloat32Array: IDLType.Tags.interface,
|
|
||||||
Types.SharedFloat64Array: IDLType.Tags.interface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, location, name, type):
|
def __init__(self, location, name, type):
|
||||||
|
@ -2938,17 +2912,10 @@ class IDLBuiltinType(IDLType):
|
||||||
def isSharedArrayBuffer(self):
|
def isSharedArrayBuffer(self):
|
||||||
return self._typeTag == IDLBuiltinType.Types.SharedArrayBuffer
|
return self._typeTag == IDLBuiltinType.Types.SharedArrayBuffer
|
||||||
|
|
||||||
def isSharedArrayBufferView(self):
|
|
||||||
return self._typeTag == IDLBuiltinType.Types.SharedArrayBufferView
|
|
||||||
|
|
||||||
def isTypedArray(self):
|
def isTypedArray(self):
|
||||||
return (self._typeTag >= IDLBuiltinType.Types.Int8Array and
|
return (self._typeTag >= IDLBuiltinType.Types.Int8Array and
|
||||||
self._typeTag <= IDLBuiltinType.Types.Float64Array)
|
self._typeTag <= IDLBuiltinType.Types.Float64Array)
|
||||||
|
|
||||||
def isSharedTypedArray(self):
|
|
||||||
return (self._typeTag >= IDLBuiltinType.Types.SharedInt8Array and
|
|
||||||
self._typeTag <= IDLBuiltinType.Types.SharedFloat64Array)
|
|
||||||
|
|
||||||
def isInterface(self):
|
def isInterface(self):
|
||||||
# TypedArray things are interface types per the TypedArray spec,
|
# TypedArray things are interface types per the TypedArray spec,
|
||||||
# but we handle them as builtins because SpiderMonkey implements
|
# but we handle them as builtins because SpiderMonkey implements
|
||||||
|
@ -2956,9 +2923,7 @@ class IDLBuiltinType(IDLType):
|
||||||
return (self.isArrayBuffer() or
|
return (self.isArrayBuffer() or
|
||||||
self.isArrayBufferView() or
|
self.isArrayBufferView() or
|
||||||
self.isSharedArrayBuffer() or
|
self.isSharedArrayBuffer() or
|
||||||
self.isSharedArrayBufferView() or
|
self.isTypedArray())
|
||||||
self.isTypedArray() or
|
|
||||||
self.isSharedTypedArray())
|
|
||||||
|
|
||||||
def isNonCallbackInterface(self):
|
def isNonCallbackInterface(self):
|
||||||
# All the interfaces we can be are non-callback
|
# All the interfaces we can be are non-callback
|
||||||
|
@ -3036,15 +3001,11 @@ class IDLBuiltinType(IDLType):
|
||||||
# that's not an ArrayBufferView or typed array.
|
# that's not an ArrayBufferView or typed array.
|
||||||
(self.isArrayBufferView() and not other.isArrayBufferView() and
|
(self.isArrayBufferView() and not other.isArrayBufferView() and
|
||||||
not other.isTypedArray()) or
|
not other.isTypedArray()) or
|
||||||
(self.isSharedArrayBufferView() and not other.isSharedArrayBufferView() and
|
|
||||||
not other.isSharedTypedArray()) or
|
|
||||||
# Typed arrays are distinguishable from everything
|
# Typed arrays are distinguishable from everything
|
||||||
# except ArrayBufferView and the same type of typed
|
# except ArrayBufferView and the same type of typed
|
||||||
# array
|
# array
|
||||||
(self.isTypedArray() and not other.isArrayBufferView() and not
|
(self.isTypedArray() and not other.isArrayBufferView() and not
|
||||||
(other.isTypedArray() and other.name == self.name)) or
|
(other.isTypedArray() and other.name == self.name)))))
|
||||||
(self.isSharedTypedArray() and not other.isSharedArrayBufferView() and not
|
|
||||||
(other.isSharedTypedArray() and other.name == self.name)))))
|
|
||||||
|
|
||||||
def _getDependentObjects(self):
|
def _getDependentObjects(self):
|
||||||
return set()
|
return set()
|
||||||
|
@ -3119,9 +3080,6 @@ BuiltinTypes = {
|
||||||
IDLBuiltinType.Types.SharedArrayBuffer:
|
IDLBuiltinType.Types.SharedArrayBuffer:
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBuffer",
|
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBuffer",
|
||||||
IDLBuiltinType.Types.SharedArrayBuffer),
|
IDLBuiltinType.Types.SharedArrayBuffer),
|
||||||
IDLBuiltinType.Types.SharedArrayBufferView:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBufferView",
|
|
||||||
IDLBuiltinType.Types.SharedArrayBufferView),
|
|
||||||
IDLBuiltinType.Types.Int8Array:
|
IDLBuiltinType.Types.Int8Array:
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
|
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
|
||||||
IDLBuiltinType.Types.Int8Array),
|
IDLBuiltinType.Types.Int8Array),
|
||||||
|
@ -3148,34 +3106,7 @@ BuiltinTypes = {
|
||||||
IDLBuiltinType.Types.Float32Array),
|
IDLBuiltinType.Types.Float32Array),
|
||||||
IDLBuiltinType.Types.Float64Array:
|
IDLBuiltinType.Types.Float64Array:
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
|
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
|
||||||
IDLBuiltinType.Types.Float64Array),
|
IDLBuiltinType.Types.Float64Array)
|
||||||
IDLBuiltinType.Types.SharedInt8Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt8Array",
|
|
||||||
IDLBuiltinType.Types.SharedInt8Array),
|
|
||||||
IDLBuiltinType.Types.SharedUint8Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8Array",
|
|
||||||
IDLBuiltinType.Types.SharedUint8Array),
|
|
||||||
IDLBuiltinType.Types.SharedUint8ClampedArray:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8ClampedArray",
|
|
||||||
IDLBuiltinType.Types.SharedUint8ClampedArray),
|
|
||||||
IDLBuiltinType.Types.SharedInt16Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt16Array",
|
|
||||||
IDLBuiltinType.Types.SharedInt16Array),
|
|
||||||
IDLBuiltinType.Types.SharedUint16Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint16Array",
|
|
||||||
IDLBuiltinType.Types.SharedUint16Array),
|
|
||||||
IDLBuiltinType.Types.SharedInt32Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt32Array",
|
|
||||||
IDLBuiltinType.Types.SharedInt32Array),
|
|
||||||
IDLBuiltinType.Types.SharedUint32Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint32Array",
|
|
||||||
IDLBuiltinType.Types.SharedUint32Array),
|
|
||||||
IDLBuiltinType.Types.SharedFloat32Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat32Array",
|
|
||||||
IDLBuiltinType.Types.SharedFloat32Array),
|
|
||||||
IDLBuiltinType.Types.SharedFloat64Array:
|
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat64Array",
|
|
||||||
IDLBuiltinType.Types.SharedFloat64Array)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3266,7 +3197,7 @@ class IDLValue(IDLObject):
|
||||||
(self.value == float("inf") or self.value == float("-inf") or
|
(self.value == float("inf") or self.value == float("-inf") or
|
||||||
math.isnan(self.value))):
|
math.isnan(self.value))):
|
||||||
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
|
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
|
||||||
% self.value, [location]);
|
% self.value, [location])
|
||||||
return IDLValue(self.location, type, self.value)
|
return IDLValue(self.location, type, self.value)
|
||||||
elif self.type.isString() and type.isUSVString():
|
elif self.type.isString() and type.isUSVString():
|
||||||
# Allow USVStrings to use default value just like
|
# Allow USVStrings to use default value just like
|
||||||
|
@ -3366,7 +3297,8 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
'Const',
|
'Const',
|
||||||
'Attr',
|
'Attr',
|
||||||
'Method',
|
'Method',
|
||||||
'MaplikeOrSetlike'
|
'MaplikeOrSetlike',
|
||||||
|
'Iterable'
|
||||||
)
|
)
|
||||||
|
|
||||||
Special = enum(
|
Special = enum(
|
||||||
|
@ -3392,6 +3324,10 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
def isConst(self):
|
def isConst(self):
|
||||||
return self.tag == IDLInterfaceMember.Tags.Const
|
return self.tag == IDLInterfaceMember.Tags.Const
|
||||||
|
|
||||||
|
def isMaplikeOrSetlikeOrIterable(self):
|
||||||
|
return (self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike or
|
||||||
|
self.tag == IDLInterfaceMember.Tags.Iterable)
|
||||||
|
|
||||||
def isMaplikeOrSetlike(self):
|
def isMaplikeOrSetlike(self):
|
||||||
return self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike
|
return self.tag == IDLInterfaceMember.Tags.MaplikeOrSetlike
|
||||||
|
|
||||||
|
@ -3469,58 +3405,42 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||||
self.aliases.append(alias)
|
self.aliases.append(alias)
|
||||||
|
|
||||||
|
|
||||||
# MaplikeOrSetlike adds a trait to an interface, like map or iteration
|
class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||||
# functions. To handle them while still getting all of the generated binding
|
|
||||||
# code taken care of, we treat them as macros that are expanded into members
|
|
||||||
# based on parsed values.
|
|
||||||
class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
|
||||||
|
|
||||||
MaplikeOrSetlikeTypes = enum(
|
|
||||||
'maplike',
|
|
||||||
'setlike'
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, location, identifier, maplikeOrSetlikeType,
|
|
||||||
readonly, keyType, valueType):
|
|
||||||
IDLInterfaceMember.__init__(self, location, identifier,
|
|
||||||
IDLInterfaceMember.Tags.MaplikeOrSetlike)
|
|
||||||
|
|
||||||
|
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
|
||||||
|
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
|
||||||
assert isinstance(keyType, IDLType)
|
assert isinstance(keyType, IDLType)
|
||||||
|
assert ifaceType in ['maplike', 'setlike', 'iterable']
|
||||||
|
if valueType is not None:
|
||||||
assert isinstance(valueType, IDLType)
|
assert isinstance(valueType, IDLType)
|
||||||
self.maplikeOrSetlikeType = maplikeOrSetlikeType
|
|
||||||
self.readonly = readonly
|
|
||||||
self.keyType = keyType
|
self.keyType = keyType
|
||||||
self.valueType = valueType
|
self.valueType = valueType
|
||||||
self.slotIndex = None
|
self.maplikeOrSetlikeOrIterableType = ifaceType
|
||||||
self.disallowedMemberNames = []
|
self.disallowedMemberNames = []
|
||||||
self.disallowedNonMethodNames = []
|
self.disallowedNonMethodNames = []
|
||||||
|
|
||||||
# When generating JSAPI access code, we need to know the backing object
|
|
||||||
# type prefix to create the correct function. Generate here for reuse.
|
|
||||||
if self.isMaplike():
|
|
||||||
self.prefix = 'Map'
|
|
||||||
elif self.isSetlike():
|
|
||||||
self.prefix = 'Set'
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "declared '%s' with key '%s'" % (self.maplikeOrSetlikeType, self.keyType)
|
|
||||||
|
|
||||||
def isMaplike(self):
|
def isMaplike(self):
|
||||||
return self.maplikeOrSetlikeType == "maplike"
|
return self.maplikeOrSetlikeOrIterableType == "maplike"
|
||||||
|
|
||||||
def isSetlike(self):
|
def isSetlike(self):
|
||||||
return self.maplikeOrSetlikeType == "setlike"
|
return self.maplikeOrSetlikeOrIterableType == "setlike"
|
||||||
|
|
||||||
|
def isIterable(self):
|
||||||
|
return self.maplikeOrSetlikeOrIterableType == "iterable"
|
||||||
|
|
||||||
|
def hasValueType(self):
|
||||||
|
return self.valueType is not None
|
||||||
|
|
||||||
def checkCollisions(self, members, isAncestor):
|
def checkCollisions(self, members, isAncestor):
|
||||||
for member in members:
|
for member in members:
|
||||||
# Check that there are no disallowed members
|
# Check that there are no disallowed members
|
||||||
if (member.identifier.name in self.disallowedMemberNames and
|
if (member.identifier.name in self.disallowedMemberNames and
|
||||||
not ((member.isMethod() and member.isMaplikeOrSetlikeMethod()) or
|
not ((member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod()) or
|
||||||
(member.isAttr() and member.isMaplikeOrSetlikeAttr()))):
|
(member.isAttr() and member.isMaplikeOrSetlikeAttr()))):
|
||||||
raise WebIDLError("Member '%s' conflicts "
|
raise WebIDLError("Member '%s' conflicts "
|
||||||
"with reserved %s name." %
|
"with reserved %s name." %
|
||||||
(member.identifier.name,
|
(member.identifier.name,
|
||||||
self.maplikeOrSetlikeType),
|
self.maplikeOrSetlikeOrIterableType),
|
||||||
[self.location, member.location])
|
[self.location, member.location])
|
||||||
# Check that there are no disallowed non-method members
|
# Check that there are no disallowed non-method members
|
||||||
if (isAncestor or (member.isAttr() or member.isConst()) and
|
if (isAncestor or (member.isAttr() or member.isConst()) and
|
||||||
|
@ -3528,27 +3448,31 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
raise WebIDLError("Member '%s' conflicts "
|
raise WebIDLError("Member '%s' conflicts "
|
||||||
"with reserved %s method." %
|
"with reserved %s method." %
|
||||||
(member.identifier.name,
|
(member.identifier.name,
|
||||||
self.maplikeOrSetlikeType),
|
self.maplikeOrSetlikeOrIterableType),
|
||||||
[self.location, member.location])
|
[self.location, member.location])
|
||||||
|
|
||||||
def expand(self, members, isJSImplemented):
|
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
|
||||||
|
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
|
||||||
"""
|
"""
|
||||||
In order to take advantage of all of the method machinery in Codegen,
|
Create an IDLMethod based on the parameters passed in.
|
||||||
we generate our functions as if they were part of the interface
|
|
||||||
specification during parsing.
|
- members is the member list to add this function to, since this is
|
||||||
"""
|
called during the member expansion portion of interface object
|
||||||
def addMethod(name, allowExistingOperations, returnType, args=[],
|
building.
|
||||||
chromeOnly=False, isPure=False, affectsNothing=False):
|
|
||||||
"""
|
- chromeOnly is only True for read-only js implemented classes, to
|
||||||
Create an IDLMethod based on the parameters passed in. chromeOnly is only
|
implement underscore prefixed convenience functions which would
|
||||||
True for read-only js implemented classes, to implement underscore
|
otherwise not be available, unlike the case of C++ bindings.
|
||||||
prefixed convenience functions would otherwise not be available,
|
|
||||||
unlike the case of C++ bindings. isPure is only True for
|
- isPure is only True for idempotent functions, so it is not valid for
|
||||||
idempotent functions, so it is not valid for things like keys,
|
things like keys, values, etc. that return a new object every time.
|
||||||
values, etc. that return a new object every time.
|
|
||||||
|
- affectsNothing means that nothing changes due to this method, which
|
||||||
|
affects JIT optimization behavior
|
||||||
|
|
||||||
|
- newObject means the method creates and returns a new object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Only add name to lists for collision checks if it's not chrome
|
# Only add name to lists for collision checks if it's not chrome
|
||||||
# only.
|
# only.
|
||||||
if chromeOnly:
|
if chromeOnly:
|
||||||
|
@ -3558,7 +3482,6 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
self.disallowedMemberNames.append(name)
|
self.disallowedMemberNames.append(name)
|
||||||
else:
|
else:
|
||||||
self.disallowedNonMethodNames.append(name)
|
self.disallowedNonMethodNames.append(name)
|
||||||
|
|
||||||
# If allowExistingOperations is True, and another operation exists
|
# If allowExistingOperations is True, and another operation exists
|
||||||
# with the same name as the one we're trying to add, don't add the
|
# with the same name as the one we're trying to add, don't add the
|
||||||
# maplike/setlike operation. However, if the operation is static,
|
# maplike/setlike operation. However, if the operation is static,
|
||||||
|
@ -3568,11 +3491,9 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
for m in members:
|
for m in members:
|
||||||
if m.identifier.name == name and m.isMethod() and not m.isStatic():
|
if m.identifier.name == name and m.isMethod() and not m.isStatic():
|
||||||
return
|
return
|
||||||
|
|
||||||
method = IDLMethod(self.location,
|
method = IDLMethod(self.location,
|
||||||
IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly),
|
IDLUnresolvedIdentifier(self.location, name, allowDoubleUnderscore=chromeOnly),
|
||||||
returnType, args, maplikeOrSetlike=self)
|
returnType, args, maplikeOrSetlikeOrIterable=self)
|
||||||
|
|
||||||
# We need to be able to throw from declaration methods
|
# We need to be able to throw from declaration methods
|
||||||
method.addExtendedAttributes(
|
method.addExtendedAttributes(
|
||||||
[IDLExtendedAttribute(self.location, ("Throws",))])
|
[IDLExtendedAttribute(self.location, ("Throws",))])
|
||||||
|
@ -3588,107 +3509,14 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
method.addExtendedAttributes(
|
method.addExtendedAttributes(
|
||||||
[IDLExtendedAttribute(self.location, ("DependsOn", "Everything")),
|
[IDLExtendedAttribute(self.location, ("DependsOn", "Everything")),
|
||||||
IDLExtendedAttribute(self.location, ("Affects", "Nothing"))])
|
IDLExtendedAttribute(self.location, ("Affects", "Nothing"))])
|
||||||
|
if newObject:
|
||||||
|
method.addExtendedAttributes(
|
||||||
|
[IDLExtendedAttribute(self.location, ("NewObject",))])
|
||||||
members.append(method)
|
members.append(method)
|
||||||
|
|
||||||
# Both maplike and setlike have a size attribute
|
|
||||||
members.append(IDLAttribute(self.location,
|
|
||||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
|
|
||||||
True,
|
|
||||||
maplikeOrSetlike=self))
|
|
||||||
self.reserved_ro_names = ["size"]
|
|
||||||
|
|
||||||
# object entries()
|
|
||||||
addMethod("entries", False, BuiltinTypes[IDLBuiltinType.Types.object],
|
|
||||||
affectsNothing=True)
|
|
||||||
# object keys()
|
|
||||||
addMethod("keys", False, BuiltinTypes[IDLBuiltinType.Types.object],
|
|
||||||
affectsNothing=True)
|
|
||||||
# object values()
|
|
||||||
addMethod("values", False, BuiltinTypes[IDLBuiltinType.Types.object],
|
|
||||||
affectsNothing=True)
|
|
||||||
|
|
||||||
# void forEach(callback(valueType, keyType), thisVal)
|
|
||||||
foreachArguments = [IDLArgument(self.location,
|
|
||||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
|
||||||
"callback"),
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.object]),
|
|
||||||
IDLArgument(self.location,
|
|
||||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
|
||||||
"thisArg"),
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.any],
|
|
||||||
optional=True)]
|
|
||||||
addMethod("forEach", False, BuiltinTypes[IDLBuiltinType.Types.void],
|
|
||||||
foreachArguments)
|
|
||||||
|
|
||||||
def getKeyArg():
|
|
||||||
return IDLArgument(self.location,
|
|
||||||
IDLUnresolvedIdentifier(self.location, "key"),
|
|
||||||
self.keyType)
|
|
||||||
|
|
||||||
# boolean has(keyType key)
|
|
||||||
addMethod("has", False, BuiltinTypes[IDLBuiltinType.Types.boolean],
|
|
||||||
[getKeyArg()], isPure=True)
|
|
||||||
|
|
||||||
if not self.readonly:
|
|
||||||
# void clear()
|
|
||||||
addMethod("clear", True, BuiltinTypes[IDLBuiltinType.Types.void],
|
|
||||||
[])
|
|
||||||
# boolean delete(keyType key)
|
|
||||||
addMethod("delete", True,
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()])
|
|
||||||
|
|
||||||
# Always generate underscored functions (e.g. __add, __clear) for js
|
|
||||||
# implemented interfaces as convenience functions.
|
|
||||||
if isJSImplemented:
|
|
||||||
# void clear()
|
|
||||||
addMethod("clear", True, BuiltinTypes[IDLBuiltinType.Types.void],
|
|
||||||
[], chromeOnly=True)
|
|
||||||
# boolean delete(keyType key)
|
|
||||||
addMethod("delete", True,
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()],
|
|
||||||
chromeOnly=True)
|
|
||||||
|
|
||||||
if self.isSetlike():
|
|
||||||
if not self.readonly:
|
|
||||||
# Add returns the set object it just added to.
|
|
||||||
# object add(keyType key)
|
|
||||||
|
|
||||||
addMethod("add", True,
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()])
|
|
||||||
if isJSImplemented:
|
|
||||||
addMethod("add", True,
|
|
||||||
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()],
|
|
||||||
chromeOnly=True)
|
|
||||||
return
|
|
||||||
|
|
||||||
# If we get this far, we're a maplike declaration.
|
|
||||||
|
|
||||||
# valueType get(keyType key)
|
|
||||||
#
|
|
||||||
# Note that instead of the value type, we're using any here. The
|
|
||||||
# validity checks should happen as things are inserted into the map,
|
|
||||||
# and using any as the return type makes code generation much simpler.
|
|
||||||
#
|
|
||||||
# TODO: Bug 1155340 may change this to use specific type to provide
|
|
||||||
# more info to JIT.
|
|
||||||
addMethod("get", False, BuiltinTypes[IDLBuiltinType.Types.any],
|
|
||||||
[getKeyArg()], isPure=True)
|
|
||||||
|
|
||||||
def getValueArg():
|
|
||||||
return IDLArgument(self.location,
|
|
||||||
IDLUnresolvedIdentifier(self.location, "value"),
|
|
||||||
self.valueType)
|
|
||||||
|
|
||||||
if not self.readonly:
|
|
||||||
addMethod("set", True, BuiltinTypes[IDLBuiltinType.Types.object],
|
|
||||||
[getKeyArg(), getValueArg()])
|
|
||||||
if isJSImplemented:
|
|
||||||
addMethod("set", True, BuiltinTypes[IDLBuiltinType.Types.object],
|
|
||||||
[getKeyArg(), getValueArg()], chromeOnly=True)
|
|
||||||
|
|
||||||
def resolve(self, parentScope):
|
def resolve(self, parentScope):
|
||||||
self.keyType.resolveType(parentScope)
|
self.keyType.resolveType(parentScope)
|
||||||
|
if self.valueType:
|
||||||
self.valueType.resolveType(parentScope)
|
self.valueType.resolveType(parentScope)
|
||||||
|
|
||||||
def finish(self, scope):
|
def finish(self, scope):
|
||||||
|
@ -3700,7 +3528,7 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
assert not isinstance(t, IDLTypedefType)
|
assert not isinstance(t, IDLTypedefType)
|
||||||
assert not isinstance(t.name, IDLUnresolvedIdentifier)
|
assert not isinstance(t.name, IDLUnresolvedIdentifier)
|
||||||
self.keyType = t
|
self.keyType = t
|
||||||
if not self.valueType.isComplete():
|
if self.valueType and not self.valueType.isComplete():
|
||||||
t = self.valueType.complete(scope)
|
t = self.valueType.complete(scope)
|
||||||
|
|
||||||
assert not isinstance(t, IDLUnresolvedType)
|
assert not isinstance(t, IDLUnresolvedType)
|
||||||
|
@ -3715,8 +3543,161 @@ class IDLMaplikeOrSetlike(IDLInterfaceMember):
|
||||||
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
||||||
|
|
||||||
def _getDependentObjects(self):
|
def _getDependentObjects(self):
|
||||||
|
if self.valueType:
|
||||||
return set([self.keyType, self.valueType])
|
return set([self.keyType, self.valueType])
|
||||||
|
return set([self.keyType])
|
||||||
|
|
||||||
|
# Iterable adds ES6 iterator style functions and traits
|
||||||
|
# (keys/values/entries/@@iterator) to an interface.
|
||||||
|
class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
|
||||||
|
|
||||||
|
def __init__(self, location, identifier, keyType, valueType=None, scope=None):
|
||||||
|
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier,
|
||||||
|
"iterable", keyType, valueType,
|
||||||
|
IDLInterfaceMember.Tags.Iterable)
|
||||||
|
self.iteratorType = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "declared iterable with key '%s' and value '%s'" % (self.keyType, self.valueType)
|
||||||
|
|
||||||
|
def expand(self, members, isJSImplemented):
|
||||||
|
"""
|
||||||
|
In order to take advantage of all of the method machinery in Codegen,
|
||||||
|
we generate our functions as if they were part of the interface
|
||||||
|
specification during parsing.
|
||||||
|
"""
|
||||||
|
# object entries()
|
||||||
|
self.addMethod("entries", members, False, self.iteratorType,
|
||||||
|
affectsNothing=True, newObject=True)
|
||||||
|
# object keys()
|
||||||
|
self.addMethod("keys", members, False, self.iteratorType,
|
||||||
|
affectsNothing=True, newObject=True)
|
||||||
|
# object values()
|
||||||
|
self.addMethod("values", members, False, self.iteratorType,
|
||||||
|
affectsNothing=True, newObject=True)
|
||||||
|
|
||||||
|
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
|
||||||
|
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
|
||||||
|
|
||||||
|
def __init__(self, location, identifier, maplikeOrSetlikeType,
|
||||||
|
readonly, keyType, valueType):
|
||||||
|
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, maplikeOrSetlikeType,
|
||||||
|
keyType, valueType, IDLInterfaceMember.Tags.MaplikeOrSetlike)
|
||||||
|
self.readonly = readonly
|
||||||
|
self.slotIndex = None
|
||||||
|
|
||||||
|
# When generating JSAPI access code, we need to know the backing object
|
||||||
|
# type prefix to create the correct function. Generate here for reuse.
|
||||||
|
if self.isMaplike():
|
||||||
|
self.prefix = 'Map'
|
||||||
|
elif self.isSetlike():
|
||||||
|
self.prefix = 'Set'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "declared '%s' with key '%s'" % (self.maplikeOrSetlikeOrIterableType, self.keyType)
|
||||||
|
|
||||||
|
def expand(self, members, isJSImplemented):
|
||||||
|
"""
|
||||||
|
In order to take advantage of all of the method machinery in Codegen,
|
||||||
|
we generate our functions as if they were part of the interface
|
||||||
|
specification during parsing.
|
||||||
|
"""
|
||||||
|
# Both maplike and setlike have a size attribute
|
||||||
|
members.append(IDLAttribute(self.location,
|
||||||
|
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
|
||||||
|
True,
|
||||||
|
maplikeOrSetlike=self))
|
||||||
|
self.reserved_ro_names = ["size"]
|
||||||
|
|
||||||
|
# object entries()
|
||||||
|
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||||
|
affectsNothing=True)
|
||||||
|
# object keys()
|
||||||
|
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||||
|
affectsNothing=True)
|
||||||
|
# object values()
|
||||||
|
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||||
|
affectsNothing=True)
|
||||||
|
|
||||||
|
# void forEach(callback(valueType, keyType), thisVal)
|
||||||
|
foreachArguments = [IDLArgument(self.location,
|
||||||
|
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||||
|
"callback"),
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.object]),
|
||||||
|
IDLArgument(self.location,
|
||||||
|
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||||
|
"thisArg"),
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.any],
|
||||||
|
optional=True)]
|
||||||
|
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
|
||||||
|
foreachArguments)
|
||||||
|
|
||||||
|
def getKeyArg():
|
||||||
|
return IDLArgument(self.location,
|
||||||
|
IDLUnresolvedIdentifier(self.location, "key"),
|
||||||
|
self.keyType)
|
||||||
|
|
||||||
|
# boolean has(keyType key)
|
||||||
|
self.addMethod("has", members, False, BuiltinTypes[IDLBuiltinType.Types.boolean],
|
||||||
|
[getKeyArg()], isPure=True)
|
||||||
|
|
||||||
|
if not self.readonly:
|
||||||
|
# void clear()
|
||||||
|
self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.void],
|
||||||
|
[])
|
||||||
|
# boolean delete(keyType key)
|
||||||
|
self.addMethod("delete", members, True,
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()])
|
||||||
|
|
||||||
|
# Always generate underscored functions (e.g. __add, __clear) for js
|
||||||
|
# implemented interfaces as convenience functions.
|
||||||
|
if isJSImplemented:
|
||||||
|
# void clear()
|
||||||
|
self.addMethod("clear", members, True, BuiltinTypes[IDLBuiltinType.Types.void],
|
||||||
|
[], chromeOnly=True)
|
||||||
|
# boolean delete(keyType key)
|
||||||
|
self.addMethod("delete", members, True,
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.boolean], [getKeyArg()],
|
||||||
|
chromeOnly=True)
|
||||||
|
|
||||||
|
if self.isSetlike():
|
||||||
|
if not self.readonly:
|
||||||
|
# Add returns the set object it just added to.
|
||||||
|
# object add(keyType key)
|
||||||
|
|
||||||
|
self.addMethod("add", members, True,
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()])
|
||||||
|
if isJSImplemented:
|
||||||
|
self.addMethod("add", members, True,
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()],
|
||||||
|
chromeOnly=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
# If we get this far, we're a maplike declaration.
|
||||||
|
|
||||||
|
# valueType get(keyType key)
|
||||||
|
#
|
||||||
|
# Note that instead of the value type, we're using any here. The
|
||||||
|
# validity checks should happen as things are inserted into the map,
|
||||||
|
# and using any as the return type makes code generation much simpler.
|
||||||
|
#
|
||||||
|
# TODO: Bug 1155340 may change this to use specific type to provide
|
||||||
|
# more info to JIT.
|
||||||
|
self.addMethod("get", members, False, BuiltinTypes[IDLBuiltinType.Types.any],
|
||||||
|
[getKeyArg()], isPure=True)
|
||||||
|
|
||||||
|
def getValueArg():
|
||||||
|
return IDLArgument(self.location,
|
||||||
|
IDLUnresolvedIdentifier(self.location, "value"),
|
||||||
|
self.valueType)
|
||||||
|
|
||||||
|
if not self.readonly:
|
||||||
|
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||||
|
[getKeyArg(), getValueArg()])
|
||||||
|
if isJSImplemented:
|
||||||
|
self.addMethod("set", members, True, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||||
|
[getKeyArg(), getValueArg()], chromeOnly=True)
|
||||||
|
|
||||||
class IDLConst(IDLInterfaceMember):
|
class IDLConst(IDLInterfaceMember):
|
||||||
def __init__(self, location, identifier, type, value):
|
def __init__(self, location, identifier, type, value):
|
||||||
|
@ -4026,6 +4007,11 @@ class IDLAttribute(IDLInterfaceMember):
|
||||||
"readonly attributes" % attr.value(),
|
"readonly attributes" % attr.value(),
|
||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
self._setDependsOn(attr.value())
|
self._setDependsOn(attr.value())
|
||||||
|
elif identifier == "UseCounter":
|
||||||
|
if self.stringifier:
|
||||||
|
raise WebIDLError("[UseCounter] must not be used on a "
|
||||||
|
"stringifier attribute",
|
||||||
|
[attr.location, self.location])
|
||||||
elif (identifier == "Pref" or
|
elif (identifier == "Pref" or
|
||||||
identifier == "Deprecated" or
|
identifier == "Deprecated" or
|
||||||
identifier == "SetterThrows" or
|
identifier == "SetterThrows" or
|
||||||
|
@ -4313,7 +4299,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
static=False, getter=False, setter=False, creator=False,
|
static=False, getter=False, setter=False, creator=False,
|
||||||
deleter=False, specialType=NamedOrIndexed.Neither,
|
deleter=False, specialType=NamedOrIndexed.Neither,
|
||||||
legacycaller=False, stringifier=False, jsonifier=False,
|
legacycaller=False, stringifier=False, jsonifier=False,
|
||||||
maplikeOrSetlike=None):
|
maplikeOrSetlikeOrIterable=None):
|
||||||
# REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
|
# REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
|
||||||
IDLInterfaceMember.__init__(self, location, identifier,
|
IDLInterfaceMember.__init__(self, location, identifier,
|
||||||
IDLInterfaceMember.Tags.Method)
|
IDLInterfaceMember.Tags.Method)
|
||||||
|
@ -4341,8 +4327,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
self._stringifier = stringifier
|
self._stringifier = stringifier
|
||||||
assert isinstance(jsonifier, bool)
|
assert isinstance(jsonifier, bool)
|
||||||
self._jsonifier = jsonifier
|
self._jsonifier = jsonifier
|
||||||
assert maplikeOrSetlike is None or isinstance(maplikeOrSetlike, IDLMaplikeOrSetlike)
|
assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
|
||||||
self.maplikeOrSetlike = maplikeOrSetlike
|
self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable
|
||||||
self._specialType = specialType
|
self._specialType = specialType
|
||||||
self._unforgeable = False
|
self._unforgeable = False
|
||||||
self.dependsOn = "Everything"
|
self.dependsOn = "Everything"
|
||||||
|
@ -4424,12 +4410,21 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
def isJsonifier(self):
|
def isJsonifier(self):
|
||||||
return self._jsonifier
|
return self._jsonifier
|
||||||
|
|
||||||
def isMaplikeOrSetlikeMethod(self):
|
def isMaplikeOrSetlikeOrIterableMethod(self):
|
||||||
"""
|
"""
|
||||||
True if this method was generated as part of a
|
True if this method was generated as part of a
|
||||||
maplike/setlike/etc interface (e.g. has/get methods)
|
maplike/setlike/etc interface (e.g. has/get methods)
|
||||||
"""
|
"""
|
||||||
return self.maplikeOrSetlike is not None
|
return self.maplikeOrSetlikeOrIterable is not None
|
||||||
|
|
||||||
|
def isSpecial(self):
|
||||||
|
return (self.isGetter() or
|
||||||
|
self.isSetter() or
|
||||||
|
self.isCreator() or
|
||||||
|
self.isDeleter() or
|
||||||
|
self.isLegacycaller() or
|
||||||
|
self.isStringifier() or
|
||||||
|
self.isJsonifier())
|
||||||
|
|
||||||
def hasOverloads(self):
|
def hasOverloads(self):
|
||||||
return self._hasOverloads
|
return self._hasOverloads
|
||||||
|
@ -4443,7 +4438,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
an non-identifier name, they actually DO have an identifier.
|
an non-identifier name, they actually DO have an identifier.
|
||||||
"""
|
"""
|
||||||
return (self.identifier.name[:2] == "__" and
|
return (self.identifier.name[:2] == "__" and
|
||||||
not self.isMaplikeOrSetlikeMethod())
|
not self.isMaplikeOrSetlikeOrIterableMethod())
|
||||||
|
|
||||||
def resolve(self, parentScope):
|
def resolve(self, parentScope):
|
||||||
assert isinstance(parentScope, IDLScope)
|
assert isinstance(parentScope, IDLScope)
|
||||||
|
@ -4712,6 +4707,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
raise WebIDLError("[Alias] takes an identifier or string",
|
raise WebIDLError("[Alias] takes an identifier or string",
|
||||||
[attr.location])
|
[attr.location])
|
||||||
self._addAlias(attr.value())
|
self._addAlias(attr.value())
|
||||||
|
elif identifier == "UseCounter":
|
||||||
|
if self.isSpecial():
|
||||||
|
raise WebIDLError("[UseCounter] must not be used on a special "
|
||||||
|
"operation",
|
||||||
|
[attr.location, self.location])
|
||||||
elif (identifier == "Throws" or
|
elif (identifier == "Throws" or
|
||||||
identifier == "NewObject" or
|
identifier == "NewObject" or
|
||||||
identifier == "ChromeOnly" or
|
identifier == "ChromeOnly" or
|
||||||
|
@ -4723,7 +4723,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
identifier == "CheckAnyPermissions" or
|
identifier == "CheckAnyPermissions" or
|
||||||
identifier == "CheckAllPermissions" or
|
identifier == "CheckAllPermissions" or
|
||||||
identifier == "BinaryName" or
|
identifier == "BinaryName" or
|
||||||
identifier == "MethodIdentityTestable" or
|
|
||||||
identifier == "StaticClassOverride"):
|
identifier == "StaticClassOverride"):
|
||||||
# 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
|
||||||
|
@ -4946,7 +4945,8 @@ class Tokenizer(object):
|
||||||
"SharedArrayBuffer": "SHAREDARRAYBUFFER",
|
"SharedArrayBuffer": "SHAREDARRAYBUFFER",
|
||||||
"or": "OR",
|
"or": "OR",
|
||||||
"maplike": "MAPLIKE",
|
"maplike": "MAPLIKE",
|
||||||
"setlike": "SETLIKE"
|
"setlike": "SETLIKE",
|
||||||
|
"iterable": "ITERABLE"
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.extend(keywords.values())
|
tokens.extend(keywords.values())
|
||||||
|
@ -5100,8 +5100,9 @@ class Parser(Tokenizer):
|
||||||
raise ex
|
raise ex
|
||||||
pass
|
pass
|
||||||
|
|
||||||
p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
|
iface = IDLInterface(location, self.globalScope(), identifier, parent,
|
||||||
members, isKnownNonPartial=True)
|
members, isKnownNonPartial=True)
|
||||||
|
p[0] = iface
|
||||||
|
|
||||||
def p_InterfaceForwardDecl(self, p):
|
def p_InterfaceForwardDecl(self, p):
|
||||||
"""
|
"""
|
||||||
|
@ -5187,7 +5188,7 @@ class Parser(Tokenizer):
|
||||||
def p_InterfaceMember(self, p):
|
def p_InterfaceMember(self, p):
|
||||||
"""
|
"""
|
||||||
InterfaceMember : Const
|
InterfaceMember : Const
|
||||||
| AttributeOrOperationOrMaplikeOrSetlike
|
| AttributeOrOperationOrMaplikeOrSetlikeOrIterable
|
||||||
"""
|
"""
|
||||||
p[0] = p[1]
|
p[0] = p[1]
|
||||||
|
|
||||||
|
@ -5402,15 +5403,30 @@ class Parser(Tokenizer):
|
||||||
"""
|
"""
|
||||||
p[0] = False
|
p[0] = False
|
||||||
|
|
||||||
def p_AttributeOrOperationOrMaplikeOrSetlike(self, p):
|
def p_AttributeOrOperationOrMaplikeOrSetlikeOrIterable(self, p):
|
||||||
"""
|
"""
|
||||||
AttributeOrOperationOrMaplikeOrSetlike : Attribute
|
AttributeOrOperationOrMaplikeOrSetlikeOrIterable : Attribute
|
||||||
| Maplike
|
| Maplike
|
||||||
| Setlike
|
| Setlike
|
||||||
|
| Iterable
|
||||||
| Operation
|
| Operation
|
||||||
"""
|
"""
|
||||||
p[0] = p[1]
|
p[0] = p[1]
|
||||||
|
|
||||||
|
def p_Iterable(self, p):
|
||||||
|
"""
|
||||||
|
Iterable : ITERABLE LT Type GT SEMICOLON
|
||||||
|
| ITERABLE LT Type COMMA Type GT SEMICOLON
|
||||||
|
"""
|
||||||
|
location = self.getLocation(p, 2)
|
||||||
|
identifier = IDLUnresolvedIdentifier(location, "__iterable",
|
||||||
|
allowDoubleUnderscore=True)
|
||||||
|
keyType = p[3]
|
||||||
|
valueType = None
|
||||||
|
if (len(p) > 6):
|
||||||
|
valueType = p[5]
|
||||||
|
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
|
||||||
|
|
||||||
def p_Setlike(self, p):
|
def p_Setlike(self, p):
|
||||||
"""
|
"""
|
||||||
Setlike : ReadOnly SETLIKE LT Type GT SEMICOLON
|
Setlike : ReadOnly SETLIKE LT Type GT SEMICOLON
|
||||||
|
@ -5783,6 +5799,7 @@ class Parser(Tokenizer):
|
||||||
| IMPLEMENTS
|
| IMPLEMENTS
|
||||||
| INHERIT
|
| INHERIT
|
||||||
| INTERFACE
|
| INTERFACE
|
||||||
|
| ITERABLE
|
||||||
| LEGACYCALLER
|
| LEGACYCALLER
|
||||||
| MAPLIKE
|
| MAPLIKE
|
||||||
| PARTIAL
|
| PARTIAL
|
||||||
|
@ -6432,7 +6449,7 @@ class Parser(Tokenizer):
|
||||||
assert isinstance(scope, IDLScope)
|
assert isinstance(scope, IDLScope)
|
||||||
|
|
||||||
# xrange omits the last value.
|
# xrange omits the last value.
|
||||||
for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.SharedFloat64Array + 1):
|
for x in xrange(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)
|
||||||
|
@ -6461,7 +6478,49 @@ class Parser(Tokenizer):
|
||||||
self._filename = None
|
self._filename = None
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
# First, finish all the IDLImplementsStatements. In particular, we
|
# If we have interfaces that are iterable, create their
|
||||||
|
# iterator interfaces and add them to the productions array.
|
||||||
|
interfaceStatements = [p for p in self._productions if
|
||||||
|
isinstance(p, IDLInterface)]
|
||||||
|
|
||||||
|
iterableIteratorIface = None
|
||||||
|
for iface in interfaceStatements:
|
||||||
|
iterable = None
|
||||||
|
# We haven't run finish() on the interface yet, so we don't know
|
||||||
|
# whether our interface is maplike/setlike/iterable or not. This
|
||||||
|
# means we have to loop through the members to see if we have an
|
||||||
|
# iterable member.
|
||||||
|
for m in iface.members:
|
||||||
|
if isinstance(m, IDLIterable):
|
||||||
|
iterable = m
|
||||||
|
break
|
||||||
|
if iterable:
|
||||||
|
def simpleExtendedAttr(str):
|
||||||
|
return IDLExtendedAttribute(iface.location, (str, ))
|
||||||
|
nextMethod = IDLMethod(
|
||||||
|
iface.location,
|
||||||
|
IDLUnresolvedIdentifier(iface.location, "next"),
|
||||||
|
BuiltinTypes[IDLBuiltinType.Types.object], [])
|
||||||
|
nextMethod.addExtendedAttributes([simpleExtendedAttr("Throws")])
|
||||||
|
itr_ident = IDLUnresolvedIdentifier(iface.location,
|
||||||
|
iface.identifier.name + "Iterator")
|
||||||
|
itr_iface = IDLInterface(iface.location, self.globalScope(),
|
||||||
|
itr_ident, None, [nextMethod],
|
||||||
|
isKnownNonPartial=True)
|
||||||
|
itr_iface.addExtendedAttributes([simpleExtendedAttr("NoInterfaceObject")])
|
||||||
|
# Make sure the exposure set for the iterator interface is the
|
||||||
|
# same as the exposure set for the iterable interface, because
|
||||||
|
# we're going to generate methods on the iterable that return
|
||||||
|
# instances of the iterator.
|
||||||
|
itr_iface._exposureGlobalNames = set(iface._exposureGlobalNames)
|
||||||
|
# Always append generated iterable interfaces after the
|
||||||
|
# interface they're a member of, otherwise nativeType generation
|
||||||
|
# won't work correctly.
|
||||||
|
itr_iface.iterableInterface = iface
|
||||||
|
self._productions.append(itr_iface)
|
||||||
|
iterable.iteratorType = IDLWrapperType(iface.location, itr_iface)
|
||||||
|
|
||||||
|
# Then, finish all the IDLImplementsStatements. In particular, we
|
||||||
# have to make sure we do those before we do the IDLInterfaces.
|
# have to make sure we do those before we do the IDLInterfaces.
|
||||||
# XXX khuey hates this bit and wants to nuke it from orbit.
|
# XXX khuey hates this bit and wants to nuke it from orbit.
|
||||||
implementsStatements = [p for p in self._productions if
|
implementsStatements = [p for p in self._productions if
|
||||||
|
@ -6493,7 +6552,6 @@ class Parser(Tokenizer):
|
||||||
_builtins = """
|
_builtins = """
|
||||||
typedef unsigned long long DOMTimeStamp;
|
typedef unsigned long long DOMTimeStamp;
|
||||||
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
|
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
|
||||||
typedef (SharedArrayBufferView or SharedArrayBuffer) SharedBufferSource;
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue