Bug 1216751 part 3. For pair iterators, @@iterator should be an alias for "entries". Similarly for maplikes and "entries" and setlikes and "values". r=qdot

This commit is contained in:
Boris Zbarsky 2016-02-17 22:58:02 -05:00
parent 352810bf10
commit 75f36aaf95
4 changed files with 16 additions and 38 deletions

View File

@ -2283,39 +2283,8 @@ class MethodDefiner(PropertyDefiner):
"condition": MemberCondition()
})
# Generate the maplike/setlike/iterable iterator, if one wasn't already
# generated by a method. If we already have an @@iterator symbol, fail.
# Note that for value iterators we don't need to do that, since those
# are only supported on interfaces that support indexed properties,
# which get an @@iterator automatically.
# Generate the keys/values/entries aliases for value iterables.
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
if (maplikeOrSetlikeOrIterable and
(not maplikeOrSetlikeOrIterable.isIterable() or
not maplikeOrSetlikeOrIterable.isValueIterator())):
if hasIterator(methods, self.regular):
raise TypeError("Cannot have maplike/setlike/iterable interface with "
"other members that generate @@iterator "
"on interface %s, such as indexed getters "
"or aliased functions." %
self.descriptor.interface.identifier.name)
for m in methods:
if (m.isMaplikeOrSetlikeOrIterableMethod() and
(((m.maplikeOrSetlikeOrIterable.isMaplike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
m.maplikeOrSetlikeOrIterable.isPairIterator())) and
m.identifier.name == "entries") or
(m.maplikeOrSetlikeOrIterable.isSetlike() and
m.identifier.name == "values"))):
self.regular.append({
"name": "@@iterator",
"methodName": m.identifier.name,
"length": methodLength(m),
"flags": "0",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor),
})
break
if (not static and
maplikeOrSetlikeOrIterable and
maplikeOrSetlikeOrIterable.isIterable() and

View File

@ -3514,7 +3514,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
[self.location, member.location])
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
isIteratorAlias=False):
"""
Create an IDLMethod based on the parameters passed in.
@ -3574,6 +3575,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if newObject:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NewObject",))])
if isIteratorAlias:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
members.append(method)
def resolve(self, parentScope):
@ -3639,7 +3643,8 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
# object entries()
self.addMethod("entries", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
affectsNothing=True, newObject=True,
isIteratorAlias=True)
# object keys()
self.addMethod("keys", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
@ -3689,13 +3694,13 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isMaplike())
# object keys()
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isSetlike())
# void forEach(callback(valueType, keyType), thisVal)
foreachArguments = [IDLArgument(self.location,

View File

@ -93,7 +93,8 @@
is(e[1], 1, "SimpleMap: iterable second array element should be value");
}
is(m[Symbol.iterator].length, 0, "SimpleMap: @@iterator symbol is correct length");
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleMap: @@iterator symbol has correct name");
is(m[Symbol.iterator].name, "entries", "SimpleMap: @@iterator symbol has correct name");
is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for "entries"');
ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
for (var k of m.keys()) {
is(k, "test", "SimpleMap: first keys element should be 'test'");
@ -139,7 +140,8 @@
is(e, "test", "SimpleSet: iterable first array element should be key");
}
is(m[Symbol.iterator].length, 0, "SimpleSet: @@iterator symbol is correct length");
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleSet: @@iterator symbol has correct name");
is(m[Symbol.iterator].name, "values", "SimpleSet: @@iterator symbol has correct name");
is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for "values"');
ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
for (var k of m.keys()) {
is(k, "test", "SimpleSet: first keys element should be 'test'");

View File

@ -98,6 +98,8 @@
info("IterableDouble: Testing simple iterable creation and functionality");
itr = new TestInterfaceIterableDouble();
testExistence("IterableDouble: ", itr, base_properties);
is(itr.entries, itr[Symbol.iterator],
"IterableDouble: Should be using @@iterator for 'entries'");
var elements = [["a", "b"], ["c", "d"], ["e", "f"]]
var keys = [...itr.keys()];
var values = [...itr.values()];