diff options
author | Kagami Sascha Rosylight <saschanaz@outlook.com> | 2019-10-19 20:26:20 +0900 |
---|---|---|
committer | Kagami Sascha Rosylight <saschanaz@outlook.com> | 2019-10-19 20:55:45 +0900 |
commit | e271edad927c6cfb304e9df8719d7ed5fe0309f9 (patch) | |
tree | 4420f5db7dc55b7d36f560880b85833ae4d7a696 /components/script/dom/bindings/codegen/parser | |
parent | 175c0d56ca48cea180500931f8a44acd1ac713be (diff) | |
download | servo-e271edad927c6cfb304e9df8719d7ed5fe0309f9.tar.gz servo-e271edad927c6cfb304e9df8719d7ed5fe0309f9.zip |
Convert [HTMLConstructor] as constructor extension
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
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(); }; """) |