Bug 1311362. Fix webidl member name collision checking with ancestor interfaces to not claim name collisions on totally unrelated names. r=qdot
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 19 Oct 2016 16:03:00 -0400
changeset 318685 adc8d8b7c96752a758a153f66ca5c32cf0f6c23b
parent 318653 e6f320965d24073a97365a948a87240b640e9762
child 318686 0d66bd1c7489b5a792aa0fca5ed9a0c41e4e6b3b
push id30850
push usercbook@mozilla.com
push dateThu, 20 Oct 2016 14:47:50 +0000
treeherdermozilla-central@3f0aeafe59c4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1311362
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1311362. Fix webidl member name collision checking with ancestor interfaces to not claim name collisions on totally unrelated names. r=qdot Fixing this exposed the fact that the 'size' tests were passing quite accidentally, since we never added 'size' to the disallowed names sets.
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3532,18 +3532,20 @@ class IDLMaplikeOrSetlikeOrIterableBase(
             if (member.identifier.name in self.disallowedMemberNames and
                 not ((member.isMethod() and member.isMaplikeOrSetlikeOrIterableMethod()) or
                      (member.isAttr() and member.isMaplikeOrSetlikeAttr()))):
                 raise WebIDLError("Member '%s' conflicts "
                                   "with reserved %s name." %
                                   (member.identifier.name,
                                    self.maplikeOrSetlikeOrIterableType),
                                   [self.location, member.location])
-            # Check that there are no disallowed non-method members
-            if (isAncestor or (member.isAttr() or member.isConst()) and
+            # Check that there are no disallowed non-method members.
+            # Ancestor members are always disallowed here; own members
+            # are disallowed only if they're non-methods.
+            if ((isAncestor or member.isAttr() or member.isConst()) and
                 member.identifier.name in self.disallowedNonMethodNames):
                 raise WebIDLError("Member '%s' conflicts "
                                   "with reserved %s method." %
                                   (member.identifier.name,
                                    self.maplikeOrSetlikeOrIterableType),
                                   [self.location, member.location])
 
     def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
@@ -3735,16 +3737,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSe
         """
         # Both maplike and setlike have a size attribute
         members.append(IDLAttribute(self.location,
                                     IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), "size"),
                                     BuiltinTypes[IDLBuiltinType.Types.unsigned_long],
                                     True,
                                     maplikeOrSetlike=self))
         self.reserved_ro_names = ["size"]
+        self.disallowedMemberNames.append("size")
 
         # object entries()
         self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
                        affectsNothing=True, isIteratorAlias=self.isMaplike())
         # object keys()
         self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
                        affectsNothing=True)
         # object values()
--- a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
+++ b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
@@ -83,73 +83,170 @@ def WebIDLTest(parser, harness):
     valueIterableMembers.append(("length", WebIDL.IDLAttribute))
 
     disallowedIterableNames = ["keys", "entries", "values"]
     disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames
     mapDisallowedMemberNames = ["get"] + disallowedMemberNames
     disallowedNonMethodNames = ["clear", "delete"]
     mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames
     setDisallowedNonMethodNames = ["add"] + disallowedNonMethodNames
+    unrelatedMembers = [("unrelatedAttribute", WebIDL.IDLAttribute),
+                        ("unrelatedMethod", WebIDL.IDLMethod)]
 
     #
     # Simple Usage Tests
     #
 
     shouldPass("Iterable (key only)",
                """
                interface Foo1 {
                iterable<long>;
                readonly attribute unsigned long length;
                getter long(unsigned long index);
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, valueIterableMembers)
+               """, valueIterableMembers + unrelatedMembers)
+
+    shouldPass("Iterable (key only) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               iterable<long>;
+               readonly attribute unsigned long length;
+               getter long(unsigned long index);
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, valueIterableMembers, numProductions=2)
 
     shouldPass("Iterable (key and value)",
                """
                interface Foo1 {
                iterable<long, long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, iterableMembers + unrelatedMembers,
+               # numProductions == 2 because of the generated iterator iface,
+               numProductions=2)
+
+    shouldPass("Iterable (key and value) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               iterable<long, long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
                """, iterableMembers,
-               # numProductions == 2 because of the generated iterator iface,
-               numProductions=2)
+               # numProductions == 3 because of the generated iterator iface,
+               numProductions=3)
 
     shouldPass("Maplike (readwrite)",
                """
                interface Foo1 {
                maplike<long, long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, mapRWMembers)
+               """, mapRWMembers + unrelatedMembers)
+
+    shouldPass("Maplike (readwrite) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               maplike<long, long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, mapRWMembers, numProductions=2)
 
     shouldPass("Maplike (readwrite)",
                """
                interface Foo1 {
                maplike<long, long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, mapRWMembers)
+               """, mapRWMembers + unrelatedMembers)
+
+    shouldPass("Maplike (readwrite) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               maplike<long, long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, mapRWMembers, numProductions=2)
 
     shouldPass("Maplike (readonly)",
                """
                interface Foo1 {
                readonly maplike<long, long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, mapROMembers)
+               """, mapROMembers + unrelatedMembers)
+
+    shouldPass("Maplike (readonly) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               readonly maplike<long, long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, mapROMembers, numProductions=2)
 
     shouldPass("Setlike (readwrite)",
                """
                interface Foo1 {
                setlike<long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, setRWMembers)
+               """, setRWMembers + unrelatedMembers)
+
+    shouldPass("Setlike (readwrite) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               setlike<long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, setRWMembers, numProductions=2)
 
     shouldPass("Setlike (readonly)",
                """
                interface Foo1 {
                readonly setlike<long>;
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
                };
-               """, setROMembers)
+               """, setROMembers + unrelatedMembers)
+
+    shouldPass("Setlike (readonly) inheriting from parent",
+               """
+               interface Foo1 : Foo2 {
+               readonly setlike<long>;
+               };
+               interface Foo2 {
+               attribute long unrelatedAttribute;
+               long unrelatedMethod();
+               };
+               """, setROMembers, numProductions=2)
 
     shouldPass("Inheritance of maplike/setlike",
                """
                interface Foo1 {
                maplike<long, long>;
                };
                interface Foo2 : Foo1 {
                };