aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/codegen/parser
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2013-07-10 16:18:02 -0400
committerJosh Matthews <josh@joshmatthews.net>2013-07-10 16:18:02 -0400
commitea983cf8e4eefd38a06762d682e2a70904a06309 (patch)
treef711d12adb0d5373df98a7d328ed17846e02bb63 /src/components/script/dom/bindings/codegen/parser
parente1c406f594dc86a75b0bb02136214a4263e4878f (diff)
downloadservo-ea983cf8e4eefd38a06762d682e2a70904a06309.tar.gz
servo-ea983cf8e4eefd38a06762d682e2a70904a06309.zip
Import partial interface support for WebIDL parsing from Gecko.
Diffstat (limited to 'src/components/script/dom/bindings/codegen/parser')
-rw-r--r--src/components/script/dom/bindings/codegen/parser/WebIDL.py79
1 files changed, 73 insertions, 6 deletions
diff --git a/src/components/script/dom/bindings/codegen/parser/WebIDL.py b/src/components/script/dom/bindings/codegen/parser/WebIDL.py
index 98273a419e6..1aab3debc6a 100644
--- a/src/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/src/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -429,17 +429,19 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
pass
class IDLInterface(IDLObjectWithScope):
- def __init__(self, location, parentScope, name, parent, members):
+ def __init__(self, location, parentScope, name, parent, members,
+ isPartial):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
- assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
+ assert not isPartial or not parent
- self.parent = parent
+ self.parent = None
self._callback = False
self._finished = False
- self.members = list(members) # clone the list
+ self.members = []
self.implementedInterfaces = set()
self._consequential = False
+ self._isPartial = True
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
# self or have self as a consequential interface, including self itself.
# Used for distinguishability checking.
@@ -447,6 +449,12 @@ class IDLInterface(IDLObjectWithScope):
IDLObjectWithScope.__init__(self, location, parentScope, name)
+ if not isPartial:
+ self.setNonPartial(location, parent, members)
+ else:
+ # Just remember our members for now
+ self.members = list(members) # clone the list
+
def __str__(self):
return "Interface '%s'" % self.identifier.name
@@ -482,6 +490,11 @@ class IDLInterface(IDLObjectWithScope):
self._finished = True
+ if self._isPartial:
+ raise WebIDLError("Interface %s does not have a non-partial "
+ "declaration" % self.identifier.name,
+ [self.location])
+
assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
parent = self.parent.finish(scope) if self.parent else None
if parent and isinstance(parent, IDLExternalInterface):
@@ -749,6 +762,21 @@ class IDLInterface(IDLObjectWithScope):
def getExtendedAttribute(self, name):
return self._extendedAttrDict.get(name, None)
+ def setNonPartial(self, location, parent, members):
+ assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
+ if not self._isPartial:
+ raise WebIDLError("Two non-partial definitions for the "
+ "same interface",
+ [location, self.location])
+ self._isPartial = False
+ # Now make it look like we were parsed at this new location, since
+ # that's the place where the interface is "really" defined
+ self.location = location
+ assert not self.parent
+ self.parent = parent
+ # Put the new members at the beginning
+ self.members = members + self.members
+
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@@ -2742,9 +2770,25 @@ class Parser(Tokenizer):
"""
location = self.getLocation(p, 1)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
-
members = p[5]
- p[0] = IDLInterface(location, self.globalScope(), identifier, p[3], members)
+ parent = p[3]
+
+ try:
+ if self.globalScope()._lookupIdentifier(identifier):
+ p[0] = self.globalScope()._lookupIdentifier(identifier)
+ if not isinstance(p[0], IDLInterface):
+ raise WebIDLError("Partial interface has the same name as "
+ "non-interface object",
+ [location, p[0].location])
+ p[0].setNonPartial(location, parent, members)
+ return
+ except Exception, ex:
+ if isinstance(ex, WebIDLError):
+ raise ex
+ pass
+
+ p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
+ members, isPartial=False)
def p_InterfaceForwardDecl(self, p):
"""
@@ -2766,6 +2810,29 @@ class Parser(Tokenizer):
"""
PartialInterface : PARTIAL INTERFACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON
"""
+ location = self.getLocation(p, 2)
+ identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
+ members = p[5]
+
+ try:
+ if self.globalScope()._lookupIdentifier(identifier):
+ p[0] = self.globalScope()._lookupIdentifier(identifier)
+ if not isinstance(p[0], IDLInterface):
+ raise WebIDLError("Partial interface has the same name as "
+ "non-interface object",
+ [location, p[0].location])
+ # Just throw our members into the existing IDLInterface. If we
+ # have extended attributes, those will get added to it
+ # automatically.
+ p[0].members.extend(members)
+ return
+ except Exception, ex:
+ if isinstance(ex, WebIDLError):
+ raise ex
+ pass
+
+ p[0] = IDLInterface(location, self.globalScope(), identifier, None,
+ members, isPartial=True)
pass
def p_Inheritance(self, p):