mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Convert [HTMLConstructor] as constructor extension
This commit is contained in:
parent
175c0d56ca
commit
e271edad92
71 changed files with 322 additions and 216 deletions
|
@ -1084,18 +1084,11 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
"Can't have both a constructor and [Global]",
|
||||
[self.location, ctor.location])
|
||||
|
||||
assert(len(ctor._exposureGlobalNames) == 0 or
|
||||
ctor._exposureGlobalNames == self._exposureGlobalNames)
|
||||
assert(ctor._exposureGlobalNames == self._exposureGlobalNames)
|
||||
ctor._exposureGlobalNames.update(self._exposureGlobalNames)
|
||||
if ctor in self.members:
|
||||
# constructor operation.
|
||||
self.members.remove(ctor)
|
||||
else:
|
||||
# extended attribute. This can only happen with
|
||||
# [HTMLConstructor] and this is the only way we can get into this
|
||||
# code with len(ctor._exposureGlobalNames) !=
|
||||
# self._exposureGlobalNames.
|
||||
ctor.finish(scope)
|
||||
# Remove the constructor operation from our member list so
|
||||
# it doesn't get in the way later.
|
||||
self.members.remove(ctor)
|
||||
|
||||
for ctor in self.namedConstructors:
|
||||
if self.globalNames:
|
||||
|
@ -1653,60 +1646,45 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
[attr.location])
|
||||
|
||||
self._noInterfaceObject = True
|
||||
elif identifier == "NamedConstructor" or identifier == "HTMLConstructor":
|
||||
if identifier == "NamedConstructor" and not attr.hasValue():
|
||||
elif identifier == "NamedConstructor":
|
||||
if not attr.hasValue():
|
||||
raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list",
|
||||
[attr.location])
|
||||
|
||||
if identifier == "HTMLConstructor":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError(str(identifier) + " must take no arguments",
|
||||
[attr.location])
|
||||
|
||||
args = attr.args() if attr.hasArgs() else []
|
||||
|
||||
retType = IDLWrapperType(self.location, self)
|
||||
|
||||
if identifier == "HTMLConstructor":
|
||||
name = "constructor"
|
||||
allowForbidden = True
|
||||
else:
|
||||
name = attr.value()
|
||||
allowForbidden = False
|
||||
|
||||
method = IDLConstructor(
|
||||
attr.location, args, name,
|
||||
htmlConstructor=(identifier == "HTMLConstructor"))
|
||||
method = IDLConstructor(attr.location, args, attr.value())
|
||||
method.reallyInit(self)
|
||||
|
||||
# Are always assumed to be able to throw (since there's no way to
|
||||
# indicate otherwise).
|
||||
# Named constructors are always assumed to be able to
|
||||
# throw (since there's no way to indicate otherwise).
|
||||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("Throws",))])
|
||||
|
||||
if identifier == "HTMLConstructor":
|
||||
method.resolve(self)
|
||||
else:
|
||||
# We need to detect conflicts for NamedConstructors across
|
||||
# interfaces. We first call resolve on the parentScope,
|
||||
# which will merge all NamedConstructors with the same
|
||||
# identifier accross interfaces as overloads.
|
||||
method.resolve(self.parentScope)
|
||||
# We need to detect conflicts for NamedConstructors across
|
||||
# interfaces. We first call resolve on the parentScope,
|
||||
# which will merge all NamedConstructors with the same
|
||||
# identifier accross interfaces as overloads.
|
||||
method.resolve(self.parentScope)
|
||||
|
||||
# Then we look up the identifier on the parentScope. If the
|
||||
# result is the same as the method we're adding then it
|
||||
# hasn't been added as an overload and it's the first time
|
||||
# we've encountered a NamedConstructor with that identifier.
|
||||
# If the result is not the same as the method we're adding
|
||||
# then it has been added as an overload and we need to check
|
||||
# whether the result is actually one of our existing
|
||||
# NamedConstructors.
|
||||
newMethod = self.parentScope.lookupIdentifier(method.identifier)
|
||||
if newMethod == method:
|
||||
self.namedConstructors.append(method)
|
||||
elif newMethod not in self.namedConstructors:
|
||||
raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
|
||||
[method.location, newMethod.location])
|
||||
# Then we look up the identifier on the parentScope. If the
|
||||
# result is the same as the method we're adding then it
|
||||
# hasn't been added as an overload and it's the first time
|
||||
# we've encountered a NamedConstructor with that identifier.
|
||||
# If the result is not the same as the method we're adding
|
||||
# then it has been added as an overload and we need to check
|
||||
# whether the result is actually one of our existing
|
||||
# NamedConstructors.
|
||||
newMethod = self.parentScope.lookupIdentifier(method.identifier)
|
||||
if newMethod == method:
|
||||
self.namedConstructors.append(method)
|
||||
elif newMethod not in self.namedConstructors:
|
||||
raise WebIDLError("NamedConstructor conflicts with a "
|
||||
"NamedConstructor of a different interface",
|
||||
[method.location, newMethod.location])
|
||||
elif (identifier == "ExceptionClass"):
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[ExceptionClass] must take no arguments",
|
||||
|
@ -1777,6 +1755,11 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
if not attr.hasValue():
|
||||
raise WebIDLError("[%s] must have a value" % identifier,
|
||||
[attr.location])
|
||||
elif identifier == "InstrumentedProps":
|
||||
# Known extended attributes that take a list
|
||||
if not attr.hasArgs():
|
||||
raise WebIDLError("[%s] must have arguments" % identifier,
|
||||
[attr.location])
|
||||
else:
|
||||
raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
|
||||
[attr.location])
|
||||
|
@ -4884,7 +4867,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
static=False, getter=False, setter=False,
|
||||
deleter=False, specialType=NamedOrIndexed.Neither,
|
||||
legacycaller=False, stringifier=False,
|
||||
maplikeOrSetlikeOrIterable=None, htmlConstructor=False):
|
||||
maplikeOrSetlikeOrIterable=None):
|
||||
# REVIEW: specialType is NamedOrIndexed -- wow, this is messed up.
|
||||
IDLInterfaceMember.__init__(self, location, identifier,
|
||||
IDLInterfaceMember.Tags.Method)
|
||||
|
@ -4910,10 +4893,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
self._stringifier = stringifier
|
||||
assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase)
|
||||
self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable
|
||||
assert isinstance(htmlConstructor, bool)
|
||||
# The identifier of a HTMLConstructor must be 'constructor'.
|
||||
assert not htmlConstructor or identifier.name == "constructor"
|
||||
self._htmlConstructor = htmlConstructor
|
||||
self._htmlConstructor = False
|
||||
self._specialType = specialType
|
||||
self._unforgeable = False
|
||||
self.dependsOn = "Everything"
|
||||
|
@ -5408,14 +5388,13 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
|
||||
|
||||
class IDLConstructor(IDLMethod):
|
||||
def __init__(self, location, args, name, htmlConstructor=False):
|
||||
def __init__(self, location, args, name):
|
||||
# We can't actually init our IDLMethod yet, because we do not know the
|
||||
# return type yet. Just save the info we have for now and we will init
|
||||
# it later.
|
||||
self._initLocation = location
|
||||
self._initArgs = args
|
||||
self._initName = name
|
||||
self._htmlConstructor = htmlConstructor
|
||||
self._inited = False
|
||||
self._initExtendedAttrs = []
|
||||
|
||||
|
@ -5432,6 +5411,18 @@ class IDLConstructor(IDLMethod):
|
|||
identifier == "SecureContext" or
|
||||
identifier == "Throws"):
|
||||
IDLMethod.handleExtendedAttribute(self, attr)
|
||||
elif identifier == "HTMLConstructor":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[HTMLConstructor] must take no arguments",
|
||||
[attr.location])
|
||||
# We shouldn't end up here for named constructors.
|
||||
assert(self.identifier.name == "constructor")
|
||||
|
||||
if any(len(sig[1]) != 0 for sig in self.signatures()):
|
||||
raise WebIDLError("[HTMLConstructor] must not be applied to a "
|
||||
"constructor operation that has arguments.",
|
||||
[attr.location])
|
||||
self._htmlConstructor = True
|
||||
else:
|
||||
raise WebIDLError("Unknown extended attribute %s on method" % identifier,
|
||||
[attr.location])
|
||||
|
@ -5442,7 +5433,7 @@ class IDLConstructor(IDLMethod):
|
|||
identifier = IDLUnresolvedIdentifier(location, name, allowForbidden=True)
|
||||
retType = IDLWrapperType(parentInterface.location, parentInterface)
|
||||
IDLMethod.__init__(self, location, identifier, retType, self._initArgs,
|
||||
static=True, htmlConstructor=self._htmlConstructor)
|
||||
static=True)
|
||||
self._inited = True;
|
||||
# Propagate through whatever extended attributes we already had
|
||||
self.addExtendedAttributes(self._initExtendedAttrs)
|
||||
|
@ -5660,6 +5651,8 @@ class Tokenizer(object):
|
|||
"namespace": "NAMESPACE",
|
||||
"ReadableStream": "READABLESTREAM",
|
||||
"constructor": "CONSTRUCTOR",
|
||||
"symbol": "SYMBOL",
|
||||
"async": "ASYNC",
|
||||
}
|
||||
|
||||
tokens.extend(keywords.values())
|
||||
|
@ -6746,37 +6739,54 @@ class Parser(Tokenizer):
|
|||
def p_ArgumentName(self, p):
|
||||
"""
|
||||
ArgumentName : IDENTIFIER
|
||||
| ATTRIBUTE
|
||||
| CALLBACK
|
||||
| CONST
|
||||
| CONSTRUCTOR
|
||||
| DELETER
|
||||
| DICTIONARY
|
||||
| ENUM
|
||||
| EXCEPTION
|
||||
| GETTER
|
||||
| INHERIT
|
||||
| INTERFACE
|
||||
| ITERABLE
|
||||
| LEGACYCALLER
|
||||
| MAPLIKE
|
||||
| PARTIAL
|
||||
| REQUIRED
|
||||
| SERIALIZER
|
||||
| SETLIKE
|
||||
| SETTER
|
||||
| STATIC
|
||||
| STRINGIFIER
|
||||
| TYPEDEF
|
||||
| UNRESTRICTED
|
||||
| NAMESPACE
|
||||
| ArgumentNameKeyword
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_ArgumentNameKeyword(self, p):
|
||||
"""
|
||||
ArgumentNameKeyword : ASYNC
|
||||
| ATTRIBUTE
|
||||
| CALLBACK
|
||||
| CONST
|
||||
| CONSTRUCTOR
|
||||
| DELETER
|
||||
| DICTIONARY
|
||||
| ENUM
|
||||
| EXCEPTION
|
||||
| GETTER
|
||||
| INCLUDES
|
||||
| INHERIT
|
||||
| INTERFACE
|
||||
| ITERABLE
|
||||
| LEGACYCALLER
|
||||
| MAPLIKE
|
||||
| MIXIN
|
||||
| NAMESPACE
|
||||
| PARTIAL
|
||||
| READONLY
|
||||
| REQUIRED
|
||||
| SERIALIZER
|
||||
| SETLIKE
|
||||
| SETTER
|
||||
| STATIC
|
||||
| STRINGIFIER
|
||||
| TYPEDEF
|
||||
| UNRESTRICTED
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_AttributeName(self, p):
|
||||
"""
|
||||
AttributeName : IDENTIFIER
|
||||
| REQUIRED
|
||||
| AttributeNameKeyword
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_AttributeNameKeyword(self, p):
|
||||
"""
|
||||
AttributeNameKeyword : ASYNC
|
||||
| REQUIRED
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
|
@ -6868,36 +6878,27 @@ class Parser(Tokenizer):
|
|||
| BYTESTRING
|
||||
| USVSTRING
|
||||
| JSSTRING
|
||||
| PROMISE
|
||||
| ANY
|
||||
| ATTRIBUTE
|
||||
| BOOLEAN
|
||||
| BYTE
|
||||
| LEGACYCALLER
|
||||
| CONST
|
||||
| CONSTRUCTOR
|
||||
| DELETER
|
||||
| DOUBLE
|
||||
| EXCEPTION
|
||||
| FALSE
|
||||
| FLOAT
|
||||
| GETTER
|
||||
| INHERIT
|
||||
| INTERFACE
|
||||
| LONG
|
||||
| NULL
|
||||
| OBJECT
|
||||
| OCTET
|
||||
| OR
|
||||
| OPTIONAL
|
||||
| SEQUENCE
|
||||
| RECORD
|
||||
| SETTER
|
||||
| SEQUENCE
|
||||
| SHORT
|
||||
| STATIC
|
||||
| STRINGIFIER
|
||||
| SYMBOL
|
||||
| TRUE
|
||||
| TYPEDEF
|
||||
| UNSIGNED
|
||||
| VOID
|
||||
| ArgumentNameKeyword
|
||||
"""
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue