Bug 1270349 part 1. Add IDL parser support for [LegacyUnenumerableNamedProperties]. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 09 May 2016 22:25:40 -0400
changeset 365162 c13bb8a0b16bd17864c36f6e923f76366fbf0f3c
parent 365161 44a8024b450ff138569767474e58d30823bf4eb9
child 365163 a3361d3f04b345eda3605b45f325c0987083dd06
push id17650
push usermartin.thomson@gmail.com
push dateTue, 10 May 2016 05:06:10 +0000
reviewerspeterv
bugs1270349
milestone49.0a1
Bug 1270349 part 1. Add IDL parser support for [LegacyUnenumerableNamedProperties]. r=peterv
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_unenumerable_own_properties.py
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1073,16 +1073,33 @@ class IDLInterface(IDLObjectWithScope, I
             if memberType in specialMembersSeen:
                 raise WebIDLError("Multiple " + memberType + " on %s" % (self),
                                   [self.location,
                                    specialMembersSeen[memberType].location,
                                    member.location])
 
             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"]:
                 memberId = "named " + memberType + "s"
                 if memberId in specialMembersSeen:
                     raise WebIDLError("Interface with [Global] has a named %s" %
                                       memberType,
                                       [self.location,
@@ -1460,16 +1477,17 @@ class IDLInterface(IDLObjectWithScope, I
                 self._isOnGlobalProtoChain = True
             elif (identifier == "NeedResolve" or
                   identifier == "OverrideBuiltins" or
                   identifier == "ChromeOnly" or
                   identifier == "Unforgeable" or
                   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():
                     raise WebIDLError("[%s] must take no arguments" % identifier,
                                       [attr.location])
             elif identifier == "Exposed":
                 convertExposedAttrToGlobalNameSet(attr,
                                                   self._exposureGlobalNames)
new file mode 100644
--- /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.")