diff --git a/packages/core-js/internals/iterator-create-proxy.js b/packages/core-js/internals/iterator-create-proxy.js index 8245828a7c17..7073d8afadc7 100644 --- a/packages/core-js/internals/iterator-create-proxy.js +++ b/packages/core-js/internals/iterator-create-proxy.js @@ -75,6 +75,7 @@ module.exports = function (nextHandler, IS_ITERATOR) { } else state = record; state.type = ITERATOR_PROXY; state.nextHandler = nextHandler; + state.counter = 0; state.done = false; setInternalState(this, state); }; diff --git a/packages/core-js/modules/esnext.iterator.every.js b/packages/core-js/modules/esnext.iterator.every.js index 2ddd445f26d7..f7fbe35c5d19 100644 --- a/packages/core-js/modules/esnext.iterator.every.js +++ b/packages/core-js/modules/esnext.iterator.every.js @@ -8,9 +8,10 @@ var getIteratorDirect = require('../internals/get-iterator-direct'); $({ target: 'Iterator', proto: true, real: true, forced: true }, { every: function every(fn) { var record = getIteratorDirect(this); + var counter = 0; aCallable(fn); return !iterate(record, function (value, stop) { - if (!fn(value)) return stop(); + if (!fn(value, counter++)) return stop(); }, { IS_RECORD: true, INTERRUPTED: true }).stopped; } }); diff --git a/packages/core-js/modules/esnext.iterator.filter.js b/packages/core-js/modules/esnext.iterator.filter.js index d3205885065f..fb8081e959ce 100644 --- a/packages/core-js/modules/esnext.iterator.filter.js +++ b/packages/core-js/modules/esnext.iterator.filter.js @@ -18,7 +18,7 @@ var IteratorProxy = createIteratorProxy(function () { done = this.done = !!result.done; if (done) return; value = result.value; - if (callWithSafeIterationClosing(iterator, filterer, value)) return value; + if (callWithSafeIterationClosing(iterator, filterer, [value, this.counter++], true)) return value; } }); diff --git a/packages/core-js/modules/esnext.iterator.find.js b/packages/core-js/modules/esnext.iterator.find.js index 25096bf4a89e..39a0e1308a77 100644 --- a/packages/core-js/modules/esnext.iterator.find.js +++ b/packages/core-js/modules/esnext.iterator.find.js @@ -8,9 +8,10 @@ var getIteratorDirect = require('../internals/get-iterator-direct'); $({ target: 'Iterator', proto: true, real: true, forced: true }, { find: function find(fn) { var record = getIteratorDirect(this); + var counter = 0; aCallable(fn); return iterate(record, function (value, stop) { - if (fn(value)) return stop(value); + if (fn(value, counter++)) return stop(value); }, { IS_RECORD: true, INTERRUPTED: true }).result; } }); diff --git a/packages/core-js/modules/esnext.iterator.flat-map.js b/packages/core-js/modules/esnext.iterator.flat-map.js index e30abcc4a142..9f45e49a75e1 100644 --- a/packages/core-js/modules/esnext.iterator.flat-map.js +++ b/packages/core-js/modules/esnext.iterator.flat-map.js @@ -28,7 +28,7 @@ var IteratorProxy = createIteratorProxy(function () { if (this.done = !!result.done) return; try { - mapped = mapper(result.value); + mapped = mapper(result.value, this.counter++); iteratorMethod = getIteratorMethod(mapped); if (!iteratorMethod) { diff --git a/packages/core-js/modules/esnext.iterator.for-each.js b/packages/core-js/modules/esnext.iterator.for-each.js index ffc40963dfcb..107f778d4209 100644 --- a/packages/core-js/modules/esnext.iterator.for-each.js +++ b/packages/core-js/modules/esnext.iterator.for-each.js @@ -2,10 +2,16 @@ // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); var iterate = require('../internals/iterate'); +var aCallable = require('../internals/a-callable'); var getIteratorDirect = require('../internals/get-iterator-direct'); $({ target: 'Iterator', proto: true, real: true, forced: true }, { forEach: function forEach(fn) { - iterate(getIteratorDirect(this), fn, { IS_RECORD: true }); + var record = getIteratorDirect(this); + var counter = 0; + aCallable(fn); + iterate(record, function (value) { + fn(value, counter++); + }, { IS_RECORD: true }); } }); diff --git a/packages/core-js/modules/esnext.iterator.indexed.js b/packages/core-js/modules/esnext.iterator.indexed.js index b68c9fc12bd9..ed3eb16641cb 100644 --- a/packages/core-js/modules/esnext.iterator.indexed.js +++ b/packages/core-js/modules/esnext.iterator.indexed.js @@ -1,3 +1,4 @@ +// TODO: Remove from `core-js@4` // https://github.com/tc39/proposal-iterator-helpers var $ = require('../internals/export'); var indexed = require('../internals/iterator-indexed'); diff --git a/packages/core-js/modules/esnext.iterator.map.js b/packages/core-js/modules/esnext.iterator.map.js index c1b4b1963ab2..fc68061228af 100644 --- a/packages/core-js/modules/esnext.iterator.map.js +++ b/packages/core-js/modules/esnext.iterator.map.js @@ -12,7 +12,7 @@ var IteratorProxy = createIteratorProxy(function () { var iterator = this.iterator; var result = anObject(call(this.next, iterator)); var done = this.done = !!result.done; - if (!done) return callWithSafeIterationClosing(iterator, this.mapper, result.value); + if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true); }); $({ target: 'Iterator', proto: true, real: true, forced: true }, { diff --git a/packages/core-js/modules/esnext.iterator.reduce.js b/packages/core-js/modules/esnext.iterator.reduce.js index b046d8f66bdf..ca4587d56822 100644 --- a/packages/core-js/modules/esnext.iterator.reduce.js +++ b/packages/core-js/modules/esnext.iterator.reduce.js @@ -13,13 +13,15 @@ $({ target: 'Iterator', proto: true, real: true, forced: true }, { aCallable(reducer); var noInitial = arguments.length < 2; var accumulator = noInitial ? undefined : arguments[1]; + var counter = 0; iterate(record, function (value) { if (noInitial) { noInitial = false; accumulator = value; } else { - accumulator = reducer(accumulator, value); + accumulator = reducer(accumulator, value, counter); } + counter++; }, { IS_RECORD: true }); if (noInitial) throw $TypeError('Reduce of empty iterator with no initial value'); return accumulator; diff --git a/packages/core-js/modules/esnext.iterator.some.js b/packages/core-js/modules/esnext.iterator.some.js index 660ef02c5c1d..a679e2dba3ca 100644 --- a/packages/core-js/modules/esnext.iterator.some.js +++ b/packages/core-js/modules/esnext.iterator.some.js @@ -8,9 +8,10 @@ var getIteratorDirect = require('../internals/get-iterator-direct'); $({ target: 'Iterator', proto: true, real: true, forced: true }, { some: function some(fn) { var record = getIteratorDirect(this); + var counter = 0; aCallable(fn); return iterate(record, function (value, stop) { - if (fn(value)) return stop(); + if (fn(value, counter++)) return stop(); }, { IS_RECORD: true, INTERRUPTED: true }).stopped; } }); diff --git a/tests/pure/esnext.iterator.every.js b/tests/pure/esnext.iterator.every.js index 2c58bac90392..be836c72bc8d 100644 --- a/tests/pure/esnext.iterator.every.js +++ b/tests/pure/esnext.iterator.every.js @@ -12,10 +12,11 @@ QUnit.test('Iterator#every', assert => { assert.true(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); assert.false(every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); - every.call(createIterator([1]), function (arg) { + every.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/pure/esnext.iterator.filter.js b/tests/pure/esnext.iterator.filter.js index 65b7afdac8c9..fa48a11a57b0 100644 --- a/tests/pure/esnext.iterator.filter.js +++ b/tests/pure/esnext.iterator.filter.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#filter', assert => { assert.nonEnumerable(Iterator.prototype, 'filter'); assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); - filter.call(createIterator([1]), function (arg) { + filter.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }).toArray(); assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/pure/esnext.iterator.find.js b/tests/pure/esnext.iterator.find.js index 6e9c9f0eab7d..049b2b51564d 100644 --- a/tests/pure/esnext.iterator.find.js +++ b/tests/pure/esnext.iterator.find.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#find', assert => { assert.nonEnumerable(Iterator.prototype, 'find'); assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); - find.call(createIterator([1]), function (arg) { + find.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/pure/esnext.iterator.flat-map.js b/tests/pure/esnext.iterator.flat-map.js index 70e55fdc6d0b..123bbe408be9 100644 --- a/tests/pure/esnext.iterator.flat-map.js +++ b/tests/pure/esnext.iterator.flat-map.js @@ -15,10 +15,11 @@ QUnit.test('Iterator#flatMap', assert => { [-1, -2, 3, 4, 5, 6, 'a', 'b'], 'basic functionality', ); - flatMap.call(createIterator([1]), function (arg) { + flatMap.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); return [arg]; }).toArray(); diff --git a/tests/pure/esnext.iterator.for-each.js b/tests/pure/esnext.iterator.for-each.js index 6afb6531482a..ad965bbc0ec7 100644 --- a/tests/pure/esnext.iterator.for-each.js +++ b/tests/pure/esnext.iterator.for-each.js @@ -16,10 +16,11 @@ QUnit.test('Iterator#forEach', assert => { assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - forEach.call(createIterator([1]), function (arg) { + forEach.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/pure/esnext.iterator.map.js b/tests/pure/esnext.iterator.map.js index 67b48dfb2294..a3dfed410744 100644 --- a/tests/pure/esnext.iterator.map.js +++ b/tests/pure/esnext.iterator.map.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#map', assert => { assert.nonEnumerable(Iterator.prototype, 'map'); assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); - map.call(createIterator([1]), function (arg) { + map.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }).toArray(); assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/pure/esnext.iterator.reduce.js b/tests/pure/esnext.iterator.reduce.js index 4951a79733e3..15dc7c2f812e 100644 --- a/tests/pure/esnext.iterator.reduce.js +++ b/tests/pure/esnext.iterator.reduce.js @@ -12,11 +12,12 @@ QUnit.test('Iterator#reduce', assert => { assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); - reduce.call(createIterator([2]), function (a, b) { + reduce.call(createIterator([2]), function (a, b, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); + assert.same(arguments.length, 3, 'arguments length'); assert.same(a, 1, 'argument 1'); assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); }, 1); assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); diff --git a/tests/pure/esnext.iterator.some.js b/tests/pure/esnext.iterator.some.js index a8c1d4c8f1d2..724c7c5d0142 100644 --- a/tests/pure/esnext.iterator.some.js +++ b/tests/pure/esnext.iterator.some.js @@ -12,10 +12,11 @@ QUnit.test('Iterator#some', assert => { assert.true(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); assert.false(some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); - some.call(createIterator([1]), function (arg) { + some.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.every.js b/tests/tests/esnext.iterator.every.js index f65b566c4e05..2c9a790754ce 100644 --- a/tests/tests/esnext.iterator.every.js +++ b/tests/tests/esnext.iterator.every.js @@ -12,10 +12,11 @@ QUnit.test('Iterator#every', assert => { assert.true(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); assert.false(every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); - every.call(createIterator([1]), function (arg) { + every.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.filter.js b/tests/tests/esnext.iterator.filter.js index 5e2fcb5e8a70..ca38448a469f 100644 --- a/tests/tests/esnext.iterator.filter.js +++ b/tests/tests/esnext.iterator.filter.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#filter', assert => { assert.nonEnumerable(Iterator.prototype, 'filter'); assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); - filter.call(createIterator([1]), function (arg) { + filter.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.find.js b/tests/tests/esnext.iterator.find.js index 65522b28cb99..42dcced0483d 100644 --- a/tests/tests/esnext.iterator.find.js +++ b/tests/tests/esnext.iterator.find.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#find', assert => { assert.nonEnumerable(Iterator.prototype, 'find'); assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); - find.call(createIterator([1]), function (arg) { + find.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.flat-map.js b/tests/tests/esnext.iterator.flat-map.js index 0b982623af2c..295d3c02d603 100644 --- a/tests/tests/esnext.iterator.flat-map.js +++ b/tests/tests/esnext.iterator.flat-map.js @@ -15,10 +15,11 @@ QUnit.test('Iterator#flatMap', assert => { [-1, -2, 3, 4, 5, 6, 'a', 'b'], 'basic functionality', ); - flatMap.call(createIterator([1]), function (arg) { + flatMap.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); return [arg]; }).toArray(); diff --git a/tests/tests/esnext.iterator.for-each.js b/tests/tests/esnext.iterator.for-each.js index 8f1905da12ae..546a9a519d94 100644 --- a/tests/tests/esnext.iterator.for-each.js +++ b/tests/tests/esnext.iterator.for-each.js @@ -16,10 +16,11 @@ QUnit.test('Iterator#forEach', assert => { assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - forEach.call(createIterator([1]), function (arg) { + forEach.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.map.js b/tests/tests/esnext.iterator.map.js index b63542f4a366..da912c5b889f 100644 --- a/tests/tests/esnext.iterator.map.js +++ b/tests/tests/esnext.iterator.map.js @@ -11,10 +11,11 @@ QUnit.test('Iterator#map', assert => { assert.nonEnumerable(Iterator.prototype, 'map'); assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); - map.call(createIterator([1]), function (arg) { + map.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }).toArray(); assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); diff --git a/tests/tests/esnext.iterator.reduce.js b/tests/tests/esnext.iterator.reduce.js index b423232fcf4d..bf66794d66b9 100644 --- a/tests/tests/esnext.iterator.reduce.js +++ b/tests/tests/esnext.iterator.reduce.js @@ -12,11 +12,12 @@ QUnit.test('Iterator#reduce', assert => { assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); - reduce.call(createIterator([2]), function (a, b) { + reduce.call(createIterator([2]), function (a, b, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); + assert.same(arguments.length, 3, 'arguments length'); assert.same(a, 1, 'argument 1'); assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); }, 1); assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); diff --git a/tests/tests/esnext.iterator.some.js b/tests/tests/esnext.iterator.some.js index 749fe6b39946..3d9ecc9e3623 100644 --- a/tests/tests/esnext.iterator.some.js +++ b/tests/tests/esnext.iterator.some.js @@ -12,10 +12,11 @@ QUnit.test('Iterator#some', assert => { assert.true(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); assert.false(some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); - some.call(createIterator([1]), function (arg) { + some.call(createIterator([1]), function (arg, counter) { assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); + assert.same(arguments.length, 2, 'arguments length'); assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); }); assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError);