Skip to content

Commit 7726a8e

Browse files
committed
Bug 1578173 part 1. Add support for constructor operations in the parser. r=edgar
The grammar changes parallel those in whatwg/webidl#700 We don't prevent having both a constructor operation and [Constructor] or [ChromeConstructor], because those extended attributes are about to get removed, once they are no longer used in our IDL. Differential Revision: https://phabricator.services.mozilla.com/D45387 UltraBlame original commit: 937448e0b594ed4108b7e376305dcdd877325354
1 parent 71eefb9 commit 7726a8e

File tree

2 files changed

+366
-32
lines changed

2 files changed

+366
-32
lines changed

dom/bindings/parser/WebIDL.py

Lines changed: 108 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,9 +1077,20 @@ def finish(self, scope):
10771077

10781078
ctor = self.ctor()
10791079
if ctor is not None:
1080-
assert len(ctor._exposureGlobalNames) == 0
1080+
if not self.hasInterfaceObject():
1081+
raise WebIDLError(
1082+
"Can't have both a constructor and [NoInterfaceObject]",
1083+
[self.location, ctor.location])
1084+
1085+
assert(len(ctor._exposureGlobalNames) == 0 or
1086+
ctor._exposureGlobalNames == self._exposureGlobalNames)
10811087
ctor._exposureGlobalNames.update(self._exposureGlobalNames)
1082-
ctor.finish(scope)
1088+
if ctor in self.members:
1089+
1090+
self.members.remove(ctor)
1091+
else:
1092+
1093+
ctor.finish(scope)
10831094

10841095
for ctor in self.namedConstructors:
10851096
assert len(ctor._exposureGlobalNames) == 0
@@ -1741,19 +1752,15 @@ def addExtendedAttributes(self, attrs):
17411752
name = attr.value()
17421753
allowForbidden = False
17431754

1744-
methodIdentifier = IDLUnresolvedIdentifier(self.location, name,
1745-
allowForbidden=allowForbidden)
1755+
method = IDLConstructor(
1756+
attr.location, args, name,
1757+
htmlConstructor=(identifier == "HTMLConstructor"))
1758+
method.reallyInit(self)
17461759

1747-
method = IDLMethod(self.location, methodIdentifier, retType,
1748-
args, static=True,
1749-
htmlConstructor=(identifier == "HTMLConstructor"))
1750-
1751-
17521760

17531761

17541762
method.addExtendedAttributes(
1755-
[IDLExtendedAttribute(self.location, ("NewObject",)),
1756-
IDLExtendedAttribute(self.location, ("Throws",))])
1763+
[IDLExtendedAttribute(self.location, ("Throws",))])
17571764
if identifier == "ChromeConstructor":
17581765
method.addExtendedAttributes(
17591766
[IDLExtendedAttribute(self.location, ("ChromeOnly",))])
@@ -1887,6 +1894,17 @@ def validate(self):
18871894
def isSerializable(self):
18881895
return self.getExtendedAttribute("Serializable")
18891896

1897+
def setNonPartial(self, location, parent, members):
1898+
1899+
1900+
1901+
1902+
for member in members:
1903+
if isinstance(member, IDLConstructor):
1904+
member.reallyInit(self)
1905+
1906+
IDLInterfaceOrNamespace.setNonPartial(self, location, parent, members)
1907+
18901908

18911909
class IDLNamespace(IDLInterfaceOrNamespace):
18921910
def __init__(self, location, parentScope, name, members, isKnownNonPartial):
@@ -5481,6 +5499,52 @@ def _getDependentObjects(self):
54815499
return deps
54825500

54835501

5502+
class IDLConstructor(IDLMethod):
5503+
def __init__(self, location, args, name, htmlConstructor=False):
5504+
5505+
5506+
5507+
self._initLocation = location
5508+
self._initArgs = args
5509+
self._initName = name
5510+
self._htmlConstructor = htmlConstructor
5511+
self._inited = False
5512+
self._initExtendedAttrs = []
5513+
5514+
def addExtendedAttributes(self, attrs):
5515+
if self._inited:
5516+
return IDLMethod.addExtendedAttributes(self, attrs)
5517+
self._initExtendedAttrs.extend(attrs)
5518+
5519+
def handleExtendedAttribute(self, attr):
5520+
identifier = attr.identifier()
5521+
if (identifier == "BinaryName" or
5522+
identifier == "ChromeOnly" or
5523+
identifier == "NewObject" or
5524+
identifier == "SecureContext" or
5525+
identifier == "Throws"):
5526+
IDLMethod.handleExtendedAttribute(self, attr)
5527+
else:
5528+
raise WebIDLError("Unknown extended attribute %s on method" % identifier,
5529+
[attr.location])
5530+
5531+
def reallyInit(self, parentInterface):
5532+
name = self._initName
5533+
location = self._initLocation
5534+
identifier = IDLUnresolvedIdentifier(location, name, allowForbidden=True)
5535+
retType = IDLWrapperType(parentInterface.location, parentInterface)
5536+
IDLMethod.__init__(self, location, identifier, retType, self._initArgs,
5537+
static=True, htmlConstructor=self._htmlConstructor)
5538+
self._inited = True;
5539+
5540+
self.addExtendedAttributes(self._initExtendedAttrs)
5541+
self._initExtendedAttrs = []
5542+
5543+
5544+
self.addExtendedAttributes(
5545+
[IDLExtendedAttribute(self.location, ("NewObject",))])
5546+
5547+
54845548
class IDLImplementsStatement(IDLObject):
54855549
def __init__(self, location, implementor, implementee):
54865550
IDLObject.__init__(self, location)
@@ -6061,7 +6125,7 @@ def p_PartialInterfaceOrPartialMixin(self, p):
60616125

60626126
def p_PartialInterfaceRest(self, p):
60636127
"""
6064-
PartialInterfaceRest : IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON
6128+
PartialInterfaceRest : IDENTIFIER LBRACE PartialInterfaceMembers RBRACE SEMICOLON
60656129
"""
60666130
location = self.getLocation(p, 1)
60676131
identifier = IDLUnresolvedIdentifier(location, p[1])
@@ -6142,8 +6206,38 @@ def p_InterfaceMembersEmpty(self, p):
61426206

61436207
def p_InterfaceMember(self, p):
61446208
"""
6145-
InterfaceMember : Const
6146-
| AttributeOrOperationOrMaplikeOrSetlikeOrIterable
6209+
InterfaceMember : PartialInterfaceMember
6210+
| Constructor
6211+
"""
6212+
p[0] = p[1]
6213+
6214+
def p_Constructor(self, p):
6215+
"""
6216+
Constructor : CONSTRUCTOR LPAREN ArgumentList RPAREN SEMICOLON
6217+
"""
6218+
p[0] = IDLConstructor(self.getLocation(p, 1), p[3], "constructor")
6219+
6220+
def p_PartialInterfaceMembers(self, p):
6221+
"""
6222+
PartialInterfaceMembers : ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers
6223+
"""
6224+
p[0] = [p[2]]
6225+
6226+
assert not p[1] or p[2]
6227+
p[2].addExtendedAttributes(p[1])
6228+
6229+
p[0].extend(p[3])
6230+
6231+
def p_PartialInterfaceMembersEmpty(self, p):
6232+
"""
6233+
PartialInterfaceMembers :
6234+
"""
6235+
p[0] = []
6236+
6237+
def p_PartialInterfaceMember(self, p):
6238+
"""
6239+
PartialInterfaceMember : Const
6240+
| AttributeOrOperationOrMaplikeOrSetlikeOrIterable
61476241
"""
61486242
p[0] = p[1]
61496243

0 commit comments

Comments
 (0)