diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index f075a34f19c4..41613d869dfa 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -1078,6 +1078,23 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): specialMembersSeen[memberType] = member + if self.getExtendedAttribute("LegacyUnenumerableNamedProperties"): + # Check that we have a named getter. + if "named getters" not in specialMembersSeen: + raise WebIDLError( + "Interface with [LegacyUnenumerableNamedProperties] does " + "not have a named getter", + [self.location]) + ancestor = self.parent + while ancestor: + if ancestor.getExtendedAttribute("LegacyUnenumerableNamedProperties"): + raise WebIDLError( + "Interface with [LegacyUnenumerableNamedProperties] " + "inherits from another interface with " + "[LegacyUnenumerableNamedProperties]", + [self.location, ancestor.location]) + ancestor = ancestor.parent + if self._isOnGlobalProtoChain: # Make sure we have no named setters, creators, or deleters for memberType in ["setter", "creator", "deleter"]: @@ -1465,6 +1482,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): identifier == "UnsafeInPrerendering" or identifier == "LegacyEventInit" or identifier == "ProbablyShortLivingObject" or + identifier == "LegacyUnenumerableNamedProperties" or identifier == "NonOrdinaryGetPrototypeOf"): # Known extended attributes that do not take values if not attr.noArguments(): diff --git a/dom/bindings/parser/tests/test_unenumerable_own_properties.py b/dom/bindings/parser/tests/test_unenumerable_own_properties.py new file mode 100644 index 000000000000..d017d5ce0928 --- /dev/null +++ b/dom/bindings/parser/tests/test_unenumerable_own_properties.py @@ -0,0 +1,64 @@ +def WebIDLTest(parser, harness): + + parser.parse( + """ + interface Foo {}; + [LegacyUnenumerableNamedProperties] + interface Bar : Foo { + getter long(DOMString name); + }; + interface Baz : Bar { + getter long(DOMString name); + }; + """); + results = parser.finish(); + harness.check(len(results), 3, "Should have three interfaces") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [LegacyUnenumerableNamedProperties] + interface NoNamedGetter { + }; + """) + + results = parser.finish() + except Exception, x: + threw = True + harness.ok(threw, "Should have thrown.") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [LegacyUnenumerableNamedProperties=Foo] + interface ShouldNotHaveArg { + getter long(DOMString name); + }; + """) + + results = parser.finish() + except Exception, x: + threw = True + harness.ok(threw, "Should have thrown.") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [LegacyUnenumerableNamedProperties] + interface Foo { + getter long(DOMString name); + }; + interface Bar : Foo {}; + [LegacyUnenumerableNamedProperties] + interface Baz : Bar { + getter long(DOMString name); + }; + """) + + results = parser.finish() + except Exception, x: + threw = True + harness.ok(threw, "Should have thrown.")