mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Remove [PrimaryGlobal]
This commit is contained in:
parent
84693d8117
commit
2660f35925
167 changed files with 417 additions and 829 deletions
|
@ -154,6 +154,9 @@ class IDLObject(object):
|
|||
def isNamespace(self):
|
||||
return False
|
||||
|
||||
def isInterfaceMixin(self):
|
||||
return False
|
||||
|
||||
def isEnum(self):
|
||||
return False
|
||||
|
||||
|
@ -233,8 +236,6 @@ class IDLScope(IDLObject):
|
|||
# A mapping from global name to the set of global interfaces
|
||||
# that have that global name.
|
||||
self.globalNameMapping = defaultdict(set)
|
||||
self.primaryGlobalAttr = None
|
||||
self.primaryGlobalName = None
|
||||
|
||||
def __str__(self):
|
||||
return self.QName()
|
||||
|
@ -462,8 +463,17 @@ class IDLExposureMixins():
|
|||
raise WebIDLError("Unknown [Exposed] value %s" % globalName,
|
||||
[self._location])
|
||||
|
||||
if len(self._exposureGlobalNames) == 0:
|
||||
self._exposureGlobalNames.add(scope.primaryGlobalName)
|
||||
# Verify that we are exposed _somwhere_ if we have some place to be
|
||||
# exposed. We don't want to assert that we're definitely exposed
|
||||
# because a lot of our parser tests have small-enough IDL snippets that
|
||||
# they don't include any globals, and we don't really want to go through
|
||||
# and add global interfaces and [Exposed] annotations to all those
|
||||
# tests.
|
||||
if len(scope.globalNames) != 0:
|
||||
if (len(self._exposureGlobalNames) == 0):
|
||||
raise WebIDLError(("'%s' is not exposed anywhere even though we have "
|
||||
"globals to be exposed to") % self,
|
||||
[self.location])
|
||||
|
||||
globalNameSetToExposureSet(scope, self._exposureGlobalNames,
|
||||
self.exposureSet)
|
||||
|
@ -508,17 +518,15 @@ class IDLExposureMixins():
|
|||
return workerDebuggerScopes.intersection(self.exposureSet)
|
||||
|
||||
|
||||
class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||
class IDLExternalInterface(IDLObjectWithIdentifier):
|
||||
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):
|
||||
|
@ -533,9 +541,6 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
|||
def isInterface(self):
|
||||
return True
|
||||
|
||||
def isConsequential(self):
|
||||
return False
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
if len(attrs) != 0:
|
||||
raise WebIDLError("There are no extended attributes that are "
|
||||
|
@ -554,9 +559,6 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
|||
def hasProbablyShortLivingWrapper(self):
|
||||
return False
|
||||
|
||||
def isSerializable(self):
|
||||
return False
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
|
@ -718,6 +720,7 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix
|
|||
return "interface"
|
||||
if self.isNamespace():
|
||||
return "namespace"
|
||||
assert self.isInterfaceMixin()
|
||||
return "interface mixin"
|
||||
|
||||
def getExtendedAttribute(self, name):
|
||||
|
@ -770,10 +773,13 @@ class IDLInterfaceOrInterfaceMixinOrNamespace(IDLObjectWithScope, IDLExposureMix
|
|||
# sets, make sure they aren't exposed in places where we are not.
|
||||
for member in self.members:
|
||||
if not member.exposureSet.issubset(self.exposureSet):
|
||||
raise WebIDLError("Interface or interface mixin member has"
|
||||
raise WebIDLError("Interface or interface mixin member has "
|
||||
"larger exposure set than its container",
|
||||
[member.location, self.location])
|
||||
|
||||
def isExternal(self):
|
||||
return False
|
||||
|
||||
|
||||
class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
|
||||
def __init__(self, location, parentScope, name, members, isKnownNonPartial):
|
||||
|
@ -788,6 +794,9 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
def __str__(self):
|
||||
return "Interface mixin '%s'" % self.identifier.name
|
||||
|
||||
def isInterfaceMixin(self):
|
||||
return True
|
||||
|
||||
def finish(self, scope):
|
||||
if self._finished:
|
||||
return
|
||||
|
@ -796,8 +805,10 @@ class IDLInterfaceMixin(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# Expose to the globals of interfaces that includes this mixin if this
|
||||
# mixin has no explicit [Exposed] so that its members can be exposed
|
||||
# based on the base interface exposure set.
|
||||
# Make sure this is done before IDLExposureMixins.finish call to
|
||||
# prevent exposing to PrimaryGlobal by default.
|
||||
#
|
||||
# Make sure this is done before IDLExposureMixins.finish call, since
|
||||
# that converts our set of exposure global names to an actual exposure
|
||||
# set.
|
||||
hasImplicitExposure = len(self._exposureGlobalNames) == 0
|
||||
if hasImplicitExposure:
|
||||
self._exposureGlobalNames.update(self.actualExposureGlobalNames)
|
||||
|
@ -876,16 +887,11 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# them.
|
||||
self.namedConstructors = list()
|
||||
self.legacyWindowAliases = []
|
||||
self.implementedInterfaces = set()
|
||||
self.includedMixins = set()
|
||||
self._consequential = False
|
||||
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
|
||||
# self or have self as a consequential interface, including self itself.
|
||||
# self, including self itself.
|
||||
# Used for distinguishability checking.
|
||||
self.interfacesBasedOnSelf = set([self])
|
||||
# self.interfacesImplementingSelf is the set of interfaces that directly
|
||||
# have self as a consequential interface
|
||||
self.interfacesImplementingSelf = set()
|
||||
self._hasChildInterfaces = False
|
||||
self._isOnGlobalProtoChain = False
|
||||
# Tracking of the number of reserved slots we need for our
|
||||
|
@ -896,6 +902,10 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# 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
|
||||
# True if we have cross-origin members.
|
||||
self.hasCrossOriginMembers = False
|
||||
# True if some descendant (including ourselves) has cross-origin members
|
||||
self.hasDescendantWithCrossOriginMembers = False
|
||||
|
||||
self.toStringTag = toStringTag
|
||||
|
||||
|
@ -996,10 +1006,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
|
||||
self.totalMembersInSlots = self.parent.totalMembersInSlots
|
||||
|
||||
# Interfaces with [Global] or [PrimaryGlobal] must not
|
||||
# have anything inherit from them
|
||||
if (self.parent.getExtendedAttribute("Global") or
|
||||
self.parent.getExtendedAttribute("PrimaryGlobal")):
|
||||
# Interfaces with [Global] must not have anything inherit from them
|
||||
if self.parent.getExtendedAttribute("Global"):
|
||||
# Note: This is not a self.parent.isOnGlobalProtoChain() check
|
||||
# because ancestors of a [Global] interface can have other
|
||||
# descendants.
|
||||
|
@ -1015,10 +1023,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
self.parent.identifier.name),
|
||||
[self.location, self.parent.location])
|
||||
|
||||
# Callbacks must not inherit from non-callbacks or inherit from
|
||||
# anything that has consequential interfaces.
|
||||
# Callbacks must not inherit from non-callbacks.
|
||||
# XXXbz Can non-callbacks inherit from callbacks? Spec issue pending.
|
||||
# XXXbz Can callbacks have consequential interfaces? Spec issue pending
|
||||
if self.isCallback():
|
||||
if not self.parent.isCallback():
|
||||
raise WebIDLError("Callback interface %s inheriting from "
|
||||
|
@ -1055,23 +1061,14 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
self.parent.identifier.name),
|
||||
[self.location, self.parent.location])
|
||||
|
||||
for iface in self.implementedInterfaces:
|
||||
iface.finish(scope)
|
||||
for mixin in self.includedMixins:
|
||||
mixin.finish(scope)
|
||||
|
||||
cycleInGraph = self.findInterfaceLoopPoint(self)
|
||||
if cycleInGraph:
|
||||
raise WebIDLError("Interface %s has itself as ancestor or "
|
||||
"implemented interface" % self.identifier.name,
|
||||
[self.location, cycleInGraph.location])
|
||||
|
||||
if self.isCallback():
|
||||
# "implements" should have made sure we have no
|
||||
# consequential interfaces.
|
||||
assert len(self.getConsequentialInterfaces()) == 0
|
||||
# And that we're not consequential.
|
||||
assert not self.isConsequential()
|
||||
raise WebIDLError(
|
||||
"Interface %s has itself as ancestor" % self.identifier.name,
|
||||
[self.location, cycleInGraph.location])
|
||||
|
||||
self.finishMembers(scope)
|
||||
|
||||
|
@ -1104,7 +1101,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
if self.globalNames:
|
||||
raise WebIDLError(
|
||||
"Can't have both a named constructor and [Global]",
|
||||
[self.location, self.namedConstructors.location])
|
||||
[self.location, ctor.location])
|
||||
assert len(ctor._exposureGlobalNames) == 0
|
||||
ctor._exposureGlobalNames.update(self._exposureGlobalNames)
|
||||
ctor.finish(scope)
|
||||
|
@ -1114,43 +1111,15 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# admixed.
|
||||
self.originalMembers = list(self.members)
|
||||
|
||||
# Import everything from our consequential interfaces into
|
||||
# self.members. Sort our consequential interfaces by name
|
||||
# just so we have a consistent order.
|
||||
for iface in sorted(self.getConsequentialInterfaces(),
|
||||
key=lambda x: x.identifier.name):
|
||||
# Flag the interface as being someone's consequential interface
|
||||
iface.setIsConsequentialInterfaceOf(self)
|
||||
# Verify that we're not exposed somewhere where iface is not exposed
|
||||
if not self.exposureSet.issubset(iface.exposureSet):
|
||||
raise WebIDLError("Interface %s is exposed in globals where its "
|
||||
"consequential interface %s is not exposed." %
|
||||
(self.identifier.name, iface.identifier.name),
|
||||
[self.location, iface.location])
|
||||
|
||||
# If we have a maplike or setlike, and the consequential interface
|
||||
# also does, throw an error.
|
||||
if iface.maplikeOrSetlikeOrIterable and self.maplikeOrSetlikeOrIterable:
|
||||
raise WebIDLError("Maplike/setlike/iterable interface %s cannot have "
|
||||
"maplike/setlike/iterable interface %s as a "
|
||||
"consequential interface" %
|
||||
(self.identifier.name,
|
||||
iface.identifier.name),
|
||||
[self.maplikeOrSetlikeOrIterable.location,
|
||||
iface.maplikeOrSetlikeOrIterable.location])
|
||||
additionalMembers = iface.originalMembers
|
||||
for additionalMember in additionalMembers:
|
||||
for member in self.members:
|
||||
if additionalMember.identifier.name == member.identifier.name:
|
||||
raise WebIDLError(
|
||||
"Multiple definitions of %s on %s coming from 'implements' statements" %
|
||||
(member.identifier.name, self),
|
||||
[additionalMember.location, member.location])
|
||||
self.members.extend(additionalMembers)
|
||||
iface.interfacesImplementingSelf.add(self)
|
||||
|
||||
for mixin in sorted(self.includedMixins,
|
||||
key=lambda x: x.identifier.name):
|
||||
for mixinMember in mixin.members:
|
||||
for member in self.members:
|
||||
if mixinMember.identifier.name == member.identifier.name:
|
||||
raise WebIDLError(
|
||||
"Multiple definitions of %s on %s coming from 'includes' statements" %
|
||||
(member.identifier.name, self),
|
||||
[mixinMember.location, member.location])
|
||||
self.members.extend(mixin.members)
|
||||
|
||||
for ancestor in self.getInheritedInterfaces():
|
||||
|
@ -1164,8 +1133,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
ancestor.identifier.name),
|
||||
[self.maplikeOrSetlikeOrIterable.location,
|
||||
ancestor.maplikeOrSetlikeOrIterable.location])
|
||||
for ancestorConsequential in ancestor.getConsequentialInterfaces():
|
||||
ancestorConsequential.interfacesBasedOnSelf.add(self)
|
||||
|
||||
# Deal with interfaces marked [Unforgeable], now that we have our full
|
||||
# member list, except unforgeables pulled in from parents. We want to
|
||||
|
@ -1199,6 +1166,21 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
not hasattr(member, "originatingInterface")):
|
||||
member.originatingInterface = self
|
||||
|
||||
for member in self.members:
|
||||
if ((member.isMethod() and
|
||||
member.getExtendedAttribute("CrossOriginCallable")) or
|
||||
(member.isAttr() and
|
||||
(member.getExtendedAttribute("CrossOriginReadable") or
|
||||
member.getExtendedAttribute("CrossOriginWritable")))):
|
||||
self.hasCrossOriginMembers = True
|
||||
break
|
||||
|
||||
if self.hasCrossOriginMembers:
|
||||
parent = self
|
||||
while parent:
|
||||
parent.hasDescendantWithCrossOriginMembers = True
|
||||
parent = parent.parent
|
||||
|
||||
# Compute slot indices for our members before we pull in unforgeable
|
||||
# members from our parent. Also, maplike/setlike declarations get a
|
||||
# slot to hold their backing object.
|
||||
|
@ -1221,13 +1203,12 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
self._ownMembersInSlots += 1
|
||||
|
||||
if self.parent:
|
||||
# Make sure we don't shadow any of the [Unforgeable] attributes on
|
||||
# our ancestor interfaces. We don't have to worry about
|
||||
# consequential interfaces here, because those have already been
|
||||
# imported into the relevant .members lists. And we don't have to
|
||||
# worry about anything other than our parent, because it has already
|
||||
# imported its ancestors unforgeable attributes into its member
|
||||
# list.
|
||||
# Make sure we don't shadow any of the [Unforgeable] attributes on our
|
||||
# ancestor interfaces. We don't have to worry about mixins here, because
|
||||
# those have already been imported into the relevant .members lists. And
|
||||
# we don't have to worry about anything other than our parent, because it
|
||||
# has already imported its ancestors' unforgeable attributes into its
|
||||
# member list.
|
||||
for unforgeableMember in (member for member in self.parent.members if
|
||||
(member.isAttr() or member.isMethod()) and
|
||||
member.isUnforgeable()):
|
||||
|
@ -1363,17 +1344,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
(attributeName, name),
|
||||
[member.location, m.location])
|
||||
|
||||
# We don't support consequential unforgeable interfaces. Need to check
|
||||
# this here, because in finish() an interface might not know yet that
|
||||
# it's consequential.
|
||||
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
|
||||
raise WebIDLError(
|
||||
"%s is an unforgeable consequential interface" %
|
||||
self.identifier.name,
|
||||
[self.location] +
|
||||
list(i.location for i in
|
||||
(self.interfacesBasedOnSelf - {self})))
|
||||
|
||||
# We also don't support inheriting from unforgeable interfaces.
|
||||
if self.getExtendedAttribute("Unforgeable") and self.hasChildInterfaces():
|
||||
locations = ([self.location] +
|
||||
|
@ -1529,16 +1499,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
'an integer-typed "length" attribute',
|
||||
[self.location, indexedGetter.location])
|
||||
|
||||
def isExternal(self):
|
||||
return False
|
||||
|
||||
def setIsConsequentialInterfaceOf(self, other):
|
||||
self._consequential = True
|
||||
self.interfacesBasedOnSelf.add(other)
|
||||
|
||||
def isConsequential(self):
|
||||
return self._consequential
|
||||
|
||||
def setCallback(self, value):
|
||||
self._callback = value
|
||||
|
||||
|
@ -1553,8 +1513,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
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
|
||||
|
@ -1582,10 +1540,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
return (not self.isCallback() and not self.isNamespace()
|
||||
and self.getUserData('hasConcreteDescendant', False))
|
||||
|
||||
def addImplementedInterface(self, implementedInterface):
|
||||
assert(isinstance(implementedInterface, IDLInterface))
|
||||
self.implementedInterfaces.add(implementedInterface)
|
||||
|
||||
def addIncludedMixin(self, includedMixin):
|
||||
assert(isinstance(includedMixin, IDLInterfaceMixin))
|
||||
self.includedMixins.add(includedMixin)
|
||||
|
@ -1603,27 +1557,10 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
parentInterfaces.insert(0, self.parent)
|
||||
return parentInterfaces
|
||||
|
||||
def getConsequentialInterfaces(self):
|
||||
assert(self._finished)
|
||||
# The interfaces we implement directly
|
||||
consequentialInterfaces = set(self.implementedInterfaces)
|
||||
|
||||
# And their inherited interfaces
|
||||
for iface in self.implementedInterfaces:
|
||||
consequentialInterfaces |= set(iface.getInheritedInterfaces())
|
||||
|
||||
# And now collect up the consequential interfaces of all of those
|
||||
temp = set()
|
||||
for iface in consequentialInterfaces:
|
||||
temp |= iface.getConsequentialInterfaces()
|
||||
|
||||
return consequentialInterfaces | temp
|
||||
|
||||
def findInterfaceLoopPoint(self, otherInterface):
|
||||
"""
|
||||
Finds an interface, amongst our ancestors and consequential interfaces,
|
||||
that inherits from otherInterface or implements otherInterface
|
||||
directly. If there is no such interface, returns None.
|
||||
Finds an interface amongst our ancestors that inherits from otherInterface.
|
||||
If there is no such interface, returns None.
|
||||
"""
|
||||
if self.parent:
|
||||
if self.parent == otherInterface:
|
||||
|
@ -1631,13 +1568,8 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
|
||||
if loopPoint:
|
||||
return loopPoint
|
||||
if otherInterface in self.implementedInterfaces:
|
||||
return self
|
||||
for iface in self.implementedInterfaces:
|
||||
loopPoint = iface.findInterfaceLoopPoint(otherInterface)
|
||||
if loopPoint:
|
||||
return loopPoint
|
||||
return None
|
||||
|
||||
def setNonPartial(self, location, parent, members):
|
||||
assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
|
||||
IDLInterfaceOrInterfaceMixinOrNamespace.setNonPartial(self, location, members)
|
||||
|
@ -1671,7 +1603,6 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
|
||||
def _getDependentObjects(self):
|
||||
deps = set(self.members)
|
||||
deps.update(self.implementedInterfaces)
|
||||
deps.update(self.includedMixins)
|
||||
if self.parent:
|
||||
deps.add(self.parent)
|
||||
|
@ -1794,20 +1725,6 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||
self.globalNames)
|
||||
self._isOnGlobalProtoChain = True
|
||||
elif identifier == "PrimaryGlobal":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[PrimaryGlobal] must take no arguments",
|
||||
[attr.location])
|
||||
if self.parentScope.primaryGlobalAttr is not None:
|
||||
raise WebIDLError(
|
||||
"[PrimaryGlobal] specified twice",
|
||||
[attr.location,
|
||||
self.parentScope.primaryGlobalAttr.location])
|
||||
self.parentScope.primaryGlobalAttr = attr
|
||||
self.parentScope.primaryGlobalName = self.identifier.name
|
||||
self.parentScope.addIfaceGlobalNames(self.identifier.name,
|
||||
[self.identifier.name])
|
||||
self._isOnGlobalProtoChain = True
|
||||
elif identifier == "LegacyWindowAlias":
|
||||
if attr.hasValue():
|
||||
self.legacyWindowAliases = [attr.value()]
|
||||
|
@ -3081,8 +2998,9 @@ class IDLWrapperType(IDLType):
|
|||
return True
|
||||
iface = self.inner
|
||||
if iface.isExternal():
|
||||
# Let's say true, though ideally we'd only do this when
|
||||
# exposureSet contains the primary global's name.
|
||||
# Let's say true, so we don't have to implement exposure mixins on
|
||||
# external interfaces and sprinkle [Exposed=Window] on every single
|
||||
# external interface declaration.
|
||||
return True
|
||||
return iface.exposureSet.issuperset(exposureSet)
|
||||
|
||||
|
@ -3865,10 +3783,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
|
|||
return self._extendedAttrDict.get(name, None)
|
||||
|
||||
def finish(self, 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):
|
||||
|
@ -5539,52 +5453,6 @@ class IDLConstructor(IDLMethod):
|
|||
[IDLExtendedAttribute(self.location, ("NewObject",))])
|
||||
|
||||
|
||||
class IDLImplementsStatement(IDLObject):
|
||||
def __init__(self, location, implementor, implementee):
|
||||
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)
|
||||
implementee = self.implementee.finish(scope)
|
||||
# NOTE: we depend on not setting self.implementor and
|
||||
# self.implementee here to keep track of the original
|
||||
# locations.
|
||||
if not isinstance(implementor, IDLInterface):
|
||||
raise WebIDLError("Left-hand side of 'implements' is not an "
|
||||
"interface",
|
||||
[self.implementor.location])
|
||||
if implementor.isCallback():
|
||||
raise WebIDLError("Left-hand side of 'implements' is a callback "
|
||||
"interface",
|
||||
[self.implementor.location])
|
||||
if not isinstance(implementee, IDLInterface):
|
||||
raise WebIDLError("Right-hand side of 'implements' is not an "
|
||||
"interface",
|
||||
[self.implementee.location])
|
||||
if implementee.isCallback():
|
||||
raise WebIDLError("Right-hand side of 'implements' is a callback "
|
||||
"interface",
|
||||
[self.implementee.location])
|
||||
implementor.addImplementedInterface(implementee)
|
||||
self.implementor = implementor
|
||||
self.implementee = implementee
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
if len(attrs) != 0:
|
||||
raise WebIDLError("There are no extended attributes that are "
|
||||
"allowed on implements statements",
|
||||
[attrs[0].location, self.location])
|
||||
|
||||
class IDLIncludesStatement(IDLObject):
|
||||
def __init__(self, location, interface, mixin):
|
||||
IDLObject.__init__(self, location)
|
||||
|
@ -5606,16 +5474,18 @@ class IDLIncludesStatement(IDLObject):
|
|||
if not isinstance(interface, IDLInterface):
|
||||
raise WebIDLError("Left-hand side of 'includes' is not an "
|
||||
"interface",
|
||||
[self.interface.location])
|
||||
[self.interface.location, interface.location])
|
||||
if interface.isCallback():
|
||||
raise WebIDLError("Left-hand side of 'includes' is a callback "
|
||||
"interface",
|
||||
[self.interface.location])
|
||||
[self.interface.location, interface.location])
|
||||
if not isinstance(mixin, IDLInterfaceMixin):
|
||||
raise WebIDLError("Right-hand side of 'includes' is not an "
|
||||
"interface mixin",
|
||||
[self.mixin.location])
|
||||
[self.mixin.location, mixin.location])
|
||||
|
||||
mixin.actualExposureGlobalNames.update(interface._exposureGlobalNames)
|
||||
|
||||
interface.addIncludedMixin(mixin)
|
||||
self.interface = interface
|
||||
self.mixin = mixin
|
||||
|
@ -5721,7 +5591,6 @@ class Tokenizer(object):
|
|||
return t
|
||||
|
||||
keywords = {
|
||||
"module": "MODULE",
|
||||
"interface": "INTERFACE",
|
||||
"partial": "PARTIAL",
|
||||
"mixin": "MIXIN",
|
||||
|
@ -5730,7 +5599,6 @@ class Tokenizer(object):
|
|||
"enum": "ENUM",
|
||||
"callback": "CALLBACK",
|
||||
"typedef": "TYPEDEF",
|
||||
"implements": "IMPLEMENTS",
|
||||
"includes": "INCLUDES",
|
||||
"const": "CONST",
|
||||
"null": "NULL",
|
||||
|
@ -5894,7 +5762,6 @@ class Parser(Tokenizer):
|
|||
| Exception
|
||||
| Enum
|
||||
| Typedef
|
||||
| ImplementsStatement
|
||||
| IncludesStatement
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
@ -6427,16 +6294,6 @@ class Parser(Tokenizer):
|
|||
p[2], p[3])
|
||||
p[0] = typedef
|
||||
|
||||
def p_ImplementsStatement(self, p):
|
||||
"""
|
||||
ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
|
||||
"""
|
||||
assert(p[2] == "implements")
|
||||
implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
|
||||
implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
|
||||
p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
|
||||
implementee)
|
||||
|
||||
def p_IncludesStatement(self, p):
|
||||
"""
|
||||
IncludesStatement : ScopedName INCLUDES ScopedName SEMICOLON
|
||||
|
@ -6898,7 +6755,6 @@ class Parser(Tokenizer):
|
|||
| ENUM
|
||||
| EXCEPTION
|
||||
| GETTER
|
||||
| IMPLEMENTS
|
||||
| INHERIT
|
||||
| INTERFACE
|
||||
| ITERABLE
|
||||
|
@ -7025,11 +6881,9 @@ class Parser(Tokenizer):
|
|||
| FALSE
|
||||
| FLOAT
|
||||
| GETTER
|
||||
| IMPLEMENTS
|
||||
| INHERIT
|
||||
| INTERFACE
|
||||
| LONG
|
||||
| MODULE
|
||||
| NULL
|
||||
| OBJECT
|
||||
| OCTET
|
||||
|
@ -7479,12 +7333,6 @@ class Parser(Tokenizer):
|
|||
|
||||
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
||||
|
||||
# To make our test harness work, pretend like we have a primary global already.
|
||||
# Note that we _don't_ set _globalScope.primaryGlobalAttr,
|
||||
# so we'll still be able to detect multiple PrimaryGlobal extended attributes.
|
||||
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
|
||||
self._globalScope.addIfaceGlobalNames("FakeTestPrimaryGlobal", ["FakeTestPrimaryGlobal"])
|
||||
|
||||
self._installBuiltins(self._globalScope)
|
||||
self._productions = []
|
||||
|
||||
|
@ -7568,20 +7416,13 @@ class Parser(Tokenizer):
|
|||
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.
|
||||
# XXX khuey hates this bit and wants to nuke it from orbit.
|
||||
implementsStatements = [p for p in self._productions if
|
||||
isinstance(p, IDLImplementsStatement)]
|
||||
# Make sure we finish IDLIncludesStatements before we finish the
|
||||
# IDLInterfaces.
|
||||
# XXX khuey hates this bit and wants to nuke it from orbit.
|
||||
includesStatements = [p for p in self._productions if
|
||||
isinstance(p, IDLIncludesStatement)]
|
||||
otherStatements = [p for p in self._productions if
|
||||
not isinstance(p, (IDLImplementsStatement,
|
||||
IDLIncludesStatement))]
|
||||
for production in implementsStatements:
|
||||
production.finish(self.globalScope())
|
||||
not isinstance(p, IDLIncludesStatement)]
|
||||
for production in includesStatements:
|
||||
production.finish(self.globalScope())
|
||||
for production in otherStatements:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue