aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/parser
diff options
context:
space:
mode:
authorKagami Sascha Rosylight <saschanaz@outlook.com>2019-10-19 20:26:20 +0900
committerKagami Sascha Rosylight <saschanaz@outlook.com>2019-10-19 20:55:45 +0900
commite271edad927c6cfb304e9df8719d7ed5fe0309f9 (patch)
tree4420f5db7dc55b7d36f560880b85833ae4d7a696 /components/script/dom/bindings/codegen/parser
parent175c0d56ca48cea180500931f8a44acd1ac713be (diff)
downloadservo-e271edad927c6cfb304e9df8719d7ed5fe0309f9.tar.gz
servo-e271edad927c6cfb304e9df8719d7ed5fe0309f9.zip
Convert [HTMLConstructor] as constructor extension
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py199
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_constructor.py22
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py18
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py19
4 files changed, 115 insertions, 143 deletions
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index a36b1b3ecfe..215d9c1212f 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -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)
-
- # 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])
+ # 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])
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
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
index 20eb152cdab..721f9c2089e 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor.py
@@ -105,8 +105,8 @@ def WebIDLTest(parser, harness):
parser = parser.reset()
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructor {
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -138,8 +138,8 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor(DOMString a)]
interface TestHTMLConstructorWithArgs {
+ [HTMLConstructor] constructor(DOMString a);
};
""")
results = parser.finish()
@@ -153,8 +153,8 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
callback interface TestHTMLConstructorOnCallbackInterface {
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -168,9 +168,9 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
constructor();
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -183,10 +183,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[Throws]
constructor();
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -200,9 +200,9 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
constructor(DOMString a);
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -216,10 +216,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[Throws]
constructor(DOMString a);
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -235,10 +235,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[ChromeOnly]
constructor();
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -252,10 +252,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[Throws, ChromeOnly]
constructor();
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -270,10 +270,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[ChromeOnly]
constructor(DOMString a);
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
@@ -288,10 +288,10 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [HTMLConstructor]
interface TestHTMLConstructorAndConstructor {
[Throws, ChromeOnly]
constructor(DOMString a);
+ [HTMLConstructor] constructor();
};
""")
results = parser.finish()
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py
index 31c5d95317f..b7eabb1e35b 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor_global.py
@@ -50,23 +50,9 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [Global, HTMLConstructor, Exposed=TestHTMLConstructorGlobal]
- interface TestHTMLConstructorGlobal {
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- parser = parser.reset()
- threw = False
- try:
- parser.parse("""
- [HTMLConstructor, Global, Exposed=TestHTMLConstructorGlobal]
+ [Global, Exposed=TestHTMLConstructorGlobal]
interface TestHTMLConstructorGlobal {
+ [HTMLConstructor] constructor();
};
""")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
index d4175094911..24cc36066cd 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
@@ -28,24 +28,9 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
- [NoInterfaceObject, HTMLConstructor]
- interface TestHTMLConstructorNoInterfaceObject {
- };
- """)
-
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Should have thrown.")
-
- parser = parser.reset()
-
- threw = False
- try:
- parser.parse("""
- [HTMLConstructor, NoInterfaceObject]
+ [NoInterfaceObject]
interface TestHTMLConstructorNoInterfaceObject {
+ [HTMLConstructor] constructor();
};
""")