Skip to content

Commit d88bf17

Browse files
committed
simplify iterator helpers detection
1 parent 6e3da21 commit d88bf17

15 files changed

+113
-149
lines changed

packages/core-js/internals/check-iterator-closing-on-early-error.js

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
var globalThis = require('../internals/global-this');
3+
4+
// https://github.com/tc39/ecma262/pull/3467
5+
module.exports = function (METHOD_NAME, ExpectedError) {
6+
var Iterator = globalThis.Iterator;
7+
var IteratorPrototype = Iterator && Iterator.prototype;
8+
var method = IteratorPrototype && IteratorPrototype[METHOD_NAME];
9+
10+
var CLOSED = false;
11+
12+
if (method) try {
13+
method.call({
14+
next: function () { return { done: true }; },
15+
'return': function () { CLOSED = true; }
16+
}, -1);
17+
} catch (error) {
18+
// https://bugs.webkit.org/show_bug.cgi?id=291195
19+
if (!(error instanceof ExpectedError)) CLOSED = false;
20+
}
21+
22+
if (!CLOSED) return method;
23+
};

packages/core-js/internals/iterator-indexed.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
2+
require('../modules/es.iterator.map');
23
var call = require('../internals/function-call');
3-
var map = require('../internals/iterator-map');
4+
var map = require('../internals/iterators-core').IteratorPrototype.map;
45

56
var callback = function (value, counter) {
67
return [counter, value];

packages/core-js/internals/iterator-map.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

packages/core-js/modules/es.iterator.drop.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
'use strict';
22
var $ = require('../internals/export');
33
var call = require('../internals/function-call');
4-
var globalThis = require('../internals/global-this');
54
var anObject = require('../internals/an-object');
65
var getIteratorDirect = require('../internals/get-iterator-direct');
76
var notANaN = require('../internals/not-a-nan');
87
var toPositiveInteger = require('../internals/to-positive-integer');
98
var iteratorClose = require('../internals/iterator-close');
109
var createIteratorProxy = require('../internals/iterator-create-proxy');
11-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
10+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
1211
var IS_PURE = require('../internals/is-pure');
1312

13+
var dropWithoutClosingOnEarlyError = !IS_PURE && iteratorHelperWithoutClosingOnEarlyError('drop', RangeError);
14+
1415
var IteratorProxy = createIteratorProxy(function () {
1516
var iterator = this.iterator;
1617
var next = this.next;
@@ -26,14 +27,9 @@ var IteratorProxy = createIteratorProxy(function () {
2627
if (!done) return result.value;
2728
});
2829

29-
var Iterator = globalThis.Iterator;
30-
var nativeDrop = Iterator && Iterator.prototype && Iterator.prototype.drop;
31-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = !IS_PURE && nativeDrop && !checkIteratorClosingOnEarlyError(RangeError, nativeDrop, -1);
32-
var FORCED = IS_PURE || !nativeDrop || NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR;
33-
3430
// `Iterator.prototype.drop` method
3531
// https://tc39.es/ecma262/#sec-iterator.prototype.drop
36-
$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
32+
$({ target: 'Iterator', proto: true, real: true, forced: IS_PURE || dropWithoutClosingOnEarlyError }, {
3733
drop: function drop(limit) {
3834
anObject(this);
3935
var remaining;
@@ -43,7 +39,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
4339
iteratorClose(this, 'throw', error);
4440
}
4541

46-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeDrop, this, remaining);
42+
if (dropWithoutClosingOnEarlyError) return call(dropWithoutClosingOnEarlyError, this, remaining);
4743

4844
return new IteratorProxy(getIteratorDirect(this), {
4945
remaining: remaining

packages/core-js/modules/es.iterator.every.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ var aCallable = require('../internals/a-callable');
66
var anObject = require('../internals/an-object');
77
var getIteratorDirect = require('../internals/get-iterator-direct');
88
var iteratorClose = require('../internals/iterator-close');
9-
var globalThis = require('../internals/global-this');
10-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
9+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
1110

12-
var Iterator = globalThis.Iterator;
13-
var nativeEvery = Iterator && Iterator.prototype && Iterator.prototype.every;
14-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeEvery && !checkIteratorClosingOnEarlyError(TypeError, nativeEvery, null);
11+
var everyWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('every', TypeError);
1512

1613
// `Iterator.prototype.every` method
1714
// https://tc39.es/ecma262/#sec-iterator.prototype.every
18-
$({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR }, {
15+
$({ target: 'Iterator', proto: true, real: true, forced: everyWithoutClosingOnEarlyError }, {
1916
every: function every(predicate) {
2017
anObject(this);
2118
try {
@@ -24,7 +21,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_C
2421
iteratorClose(this, 'throw', error);
2522
}
2623

27-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeEvery, this, predicate);
24+
if (everyWithoutClosingOnEarlyError) return call(everyWithoutClosingOnEarlyError, this, predicate);
2825

2926
var record = getIteratorDirect(this);
3027
var counter = 0;

packages/core-js/modules/es.iterator.filter.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ var createIteratorProxy = require('../internals/iterator-create-proxy');
88
var callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing');
99
var IS_PURE = require('../internals/is-pure');
1010
var iteratorClose = require('../internals/iterator-close');
11-
var globalThis = require('../internals/global-this');
12-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
11+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
12+
13+
var filterWithoutClosingOnEarlyError = !IS_PURE && iteratorHelperWithoutClosingOnEarlyError('filter', TypeError);
1314

1415
var IteratorProxy = createIteratorProxy(function () {
1516
var iterator = this.iterator;
@@ -25,14 +26,9 @@ var IteratorProxy = createIteratorProxy(function () {
2526
}
2627
});
2728

28-
var Iterator = globalThis.Iterator;
29-
var nativeFilter = Iterator && Iterator.prototype && Iterator.prototype.filter;
30-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeFilter && !checkIteratorClosingOnEarlyError(TypeError, nativeFilter, null);
31-
var FORCED = IS_PURE || !nativeFilter || NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR;
32-
3329
// `Iterator.prototype.filter` method
3430
// https://tc39.es/ecma262/#sec-iterator.prototype.filter
35-
$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
31+
$({ target: 'Iterator', proto: true, real: true, forced: IS_PURE || filterWithoutClosingOnEarlyError }, {
3632
filter: function filter(predicate) {
3733
anObject(this);
3834
try {
@@ -41,7 +37,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
4137
iteratorClose(this, 'throw', error);
4238
}
4339

44-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeFilter, this, predicate);
40+
if (filterWithoutClosingOnEarlyError) return call(filterWithoutClosingOnEarlyError, this, predicate);
4541

4642
return new IteratorProxy(getIteratorDirect(this), {
4743
predicate: predicate

packages/core-js/modules/es.iterator.find.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ var aCallable = require('../internals/a-callable');
66
var anObject = require('../internals/an-object');
77
var getIteratorDirect = require('../internals/get-iterator-direct');
88
var iteratorClose = require('../internals/iterator-close');
9-
var globalThis = require('../internals/global-this');
10-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
9+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
1110

12-
var Iterator = globalThis.Iterator;
13-
var nativeFind = Iterator && Iterator.prototype && Iterator.prototype.find;
14-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeFind && !checkIteratorClosingOnEarlyError(TypeError, nativeFind, null);
11+
var findWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('find', TypeError);
1512

1613
// `Iterator.prototype.find` method
1714
// https://tc39.es/ecma262/#sec-iterator.prototype.find
18-
$({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR }, {
15+
$({ target: 'Iterator', proto: true, real: true, forced: findWithoutClosingOnEarlyError }, {
1916
find: function find(predicate) {
2017
anObject(this);
2118
try {
@@ -24,7 +21,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_C
2421
iteratorClose(this, 'throw', error);
2522
}
2623

27-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeFind, this, predicate);
24+
if (findWithoutClosingOnEarlyError) return call(findWithoutClosingOnEarlyError, this, predicate);
2825

2926
var record = getIteratorDirect(this);
3027
var counter = 0;

packages/core-js/modules/es.iterator.flat-map.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ var getIteratorFlattenable = require('../internals/get-iterator-flattenable');
88
var createIteratorProxy = require('../internals/iterator-create-proxy');
99
var iteratorClose = require('../internals/iterator-close');
1010
var IS_PURE = require('../internals/is-pure');
11-
var globalThis = require('../internals/global-this');
12-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
11+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
12+
13+
var flatMapWithoutClosingOnEarlyError = !IS_PURE && iteratorHelperWithoutClosingOnEarlyError('flatMap', TypeError);
1314

1415
var IteratorProxy = createIteratorProxy(function () {
1516
var iterator = this.iterator;
@@ -33,14 +34,9 @@ var IteratorProxy = createIteratorProxy(function () {
3334
}
3435
});
3536

36-
var Iterator = globalThis.Iterator;
37-
var nativeFlatMap = Iterator && Iterator.prototype && Iterator.prototype.flatMap;
38-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeFlatMap && !checkIteratorClosingOnEarlyError(TypeError, nativeFlatMap, null);
39-
var FORCED = IS_PURE || !nativeFlatMap || NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR;
40-
4137
// `Iterator.prototype.flatMap` method
4238
// https://tc39.es/ecma262/#sec-iterator.prototype.flatmap
43-
$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
39+
$({ target: 'Iterator', proto: true, real: true, forced: IS_PURE || flatMapWithoutClosingOnEarlyError }, {
4440
flatMap: function flatMap(mapper) {
4541
anObject(this);
4642
try {
@@ -49,7 +45,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
4945
iteratorClose(this, 'throw', error);
5046
}
5147

52-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeFlatMap, this, mapper);
48+
if (flatMapWithoutClosingOnEarlyError) return call(flatMapWithoutClosingOnEarlyError, this, mapper);
5349

5450
return new IteratorProxy(getIteratorDirect(this), {
5551
mapper: mapper,

packages/core-js/modules/es.iterator.for-each.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ var aCallable = require('../internals/a-callable');
66
var anObject = require('../internals/an-object');
77
var getIteratorDirect = require('../internals/get-iterator-direct');
88
var iteratorClose = require('../internals/iterator-close');
9-
var globalThis = require('../internals/global-this');
10-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
9+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
1110

12-
var Iterator = globalThis.Iterator;
13-
var nativeForEach = Iterator && Iterator.prototype && Iterator.prototype.forEach;
14-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeForEach && !checkIteratorClosingOnEarlyError(TypeError, nativeForEach, null);
11+
var forEachWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('forEach', TypeError);
1512

1613
// `Iterator.prototype.forEach` method
1714
// https://tc39.es/ecma262/#sec-iterator.prototype.foreach
18-
$({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR }, {
15+
$({ target: 'Iterator', proto: true, real: true, forced: forEachWithoutClosingOnEarlyError }, {
1916
forEach: function forEach(fn) {
2017
anObject(this);
2118
try {
@@ -24,7 +21,7 @@ $({ target: 'Iterator', proto: true, real: true, forced: NATIVE_METHOD_WITHOUT_C
2421
iteratorClose(this, 'throw', error);
2522
}
2623

27-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) return call(nativeForEach, this, fn);
24+
if (forEachWithoutClosingOnEarlyError) return call(forEachWithoutClosingOnEarlyError, this, fn);
2825

2926
var record = getIteratorDirect(this);
3027
var counter = 0;
Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,39 @@
11
'use strict';
22
var $ = require('../internals/export');
3-
var map = require('../internals/iterator-map');
3+
var call = require('../internals/function-call');
4+
var aCallable = require('../internals/a-callable');
5+
var anObject = require('../internals/an-object');
6+
var getIteratorDirect = require('../internals/get-iterator-direct');
7+
var createIteratorProxy = require('../internals/iterator-create-proxy');
8+
var callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing');
9+
var iteratorClose = require('../internals/iterator-close');
10+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
411
var IS_PURE = require('../internals/is-pure');
5-
var globalThis = require('../internals/global-this');
612

7-
var Iterator = globalThis.Iterator;
8-
var nativeMap = Iterator && Iterator.prototype && Iterator.prototype.map;
9-
var FORCED = IS_PURE || nativeMap !== map;
13+
var IteratorProxy = createIteratorProxy(function () {
14+
var iterator = this.iterator;
15+
var result = anObject(call(this.next, iterator));
16+
var done = this.done = !!result.done;
17+
if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true);
18+
});
19+
20+
var mapWithoutClosingOnEarlyError = !IS_PURE && iteratorHelperWithoutClosingOnEarlyError('map', TypeError);
1021

1122
// `Iterator.prototype.map` method
1223
// https://tc39.es/ecma262/#sec-iterator.prototype.map
13-
$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
14-
map: map
24+
$({ target: 'Iterator', proto: true, real: true, forced: IS_PURE || mapWithoutClosingOnEarlyError }, {
25+
map: function map(mapper) {
26+
anObject(this);
27+
try {
28+
aCallable(mapper);
29+
} catch (error) {
30+
iteratorClose(this, 'throw', error);
31+
}
32+
33+
if (mapWithoutClosingOnEarlyError) return call(mapWithoutClosingOnEarlyError, this, mapper);
34+
35+
return new IteratorProxy(getIteratorDirect(this), {
36+
mapper: mapper
37+
});
38+
}
1539
});

packages/core-js/modules/es.iterator.reduce.js

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,23 @@ var aCallable = require('../internals/a-callable');
55
var anObject = require('../internals/an-object');
66
var getIteratorDirect = require('../internals/get-iterator-direct');
77
var iteratorClose = require('../internals/iterator-close');
8-
var globalThis = require('../internals/global-this');
9-
var checkIteratorClosingOnEarlyError = require('../internals/check-iterator-closing-on-early-error');
10-
var call = require('../internals/function-call');
8+
var iteratorHelperWithoutClosingOnEarlyError = require('../internals/iterator-helper-without-closing-on-early-error');
9+
var apply = require('../internals/function-apply');
1110
var fails = require('../internals/fails');
1211

1312
var $TypeError = TypeError;
14-
var Iterator = globalThis.Iterator;
15-
var nativeReduce = Iterator && Iterator.prototype && Iterator.prototype.reduce;
1613

1714
// https://bugs.webkit.org/show_bug.cgi?id=291651
18-
var FAILS_ON_INITIAL_UNDEFINED = nativeReduce && fails(function () {
15+
var FAILS_ON_INITIAL_UNDEFINED = fails(function () {
1916
// eslint-disable-next-line es/no-iterator-prototype-reduce, es/no-array-prototype-keys, array-callback-return -- required for testing
2017
[].keys().reduce(function () { /* empty */ }, undefined);
2118
});
2219

23-
var NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR = nativeReduce && !FAILS_ON_INITIAL_UNDEFINED &&
24-
!checkIteratorClosingOnEarlyError(TypeError, nativeReduce, null);
25-
26-
var FORCED = FAILS_ON_INITIAL_UNDEFINED || NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR;
20+
var reduceWithoutClosingOnEarlyError = !FAILS_ON_INITIAL_UNDEFINED && iteratorHelperWithoutClosingOnEarlyError('reduce', $TypeError);
2721

2822
// `Iterator.prototype.reduce` method
2923
// https://tc39.es/ecma262/#sec-iterator.prototype.reduce
30-
$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
24+
$({ target: 'Iterator', proto: true, real: true, forced: FAILS_ON_INITIAL_UNDEFINED || reduceWithoutClosingOnEarlyError }, {
3125
reduce: function reduce(reducer /* , initialValue */) {
3226
anObject(this);
3327
try {
@@ -38,8 +32,8 @@ $({ target: 'Iterator', proto: true, real: true, forced: FORCED }, {
3832

3933
var noInitial = arguments.length < 2;
4034
var accumulator = noInitial ? undefined : arguments[1];
41-
if (NATIVE_METHOD_WITHOUT_CLOSING_ON_EARLY_ERROR) {
42-
return noInitial ? call(nativeReduce, this, reducer) : call(nativeReduce, this, reducer, accumulator);
35+
if (reduceWithoutClosingOnEarlyError) {
36+
return apply(reduceWithoutClosingOnEarlyError, this, noInitial ? [reducer] : [reducer, accumulator]);
4337
}
4438
var record = getIteratorDirect(this);
4539
var counter = 0;

0 commit comments

Comments
 (0)