UNPKG

4.51 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var call = require('../internals/function-call');
4var IS_PURE = require('../internals/is-pure');
5var FunctionName = require('../internals/function-name');
6var isCallable = require('../internals/is-callable');
7var createIteratorConstructor = require('../internals/iterator-create-constructor');
8var getPrototypeOf = require('../internals/object-get-prototype-of');
9var setPrototypeOf = require('../internals/object-set-prototype-of');
10var setToStringTag = require('../internals/set-to-string-tag');
11var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
12var defineBuiltIn = require('../internals/define-built-in');
13var wellKnownSymbol = require('../internals/well-known-symbol');
14var Iterators = require('../internals/iterators');
15var IteratorsCore = require('../internals/iterators-core');
16
17var PROPER_FUNCTION_NAME = FunctionName.PROPER;
18var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE;
19var IteratorPrototype = IteratorsCore.IteratorPrototype;
20var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
21var ITERATOR = wellKnownSymbol('iterator');
22var KEYS = 'keys';
23var VALUES = 'values';
24var ENTRIES = 'entries';
25
26var returnThis = function () { return this; };
27
28module.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
29 createIteratorConstructor(IteratorConstructor, NAME, next);
30
31 var getIterationMethod = function (KIND) {
32 if (KIND === DEFAULT && defaultIterator) return defaultIterator;
33 if (!BUGGY_SAFARI_ITERATORS && KIND && KIND in IterablePrototype) return IterablePrototype[KIND];
34
35 switch (KIND) {
36 case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
37 case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
38 case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
39 }
40
41 return function () { return new IteratorConstructor(this); };
42 };
43
44 var TO_STRING_TAG = NAME + ' Iterator';
45 var INCORRECT_VALUES_NAME = false;
46 var IterablePrototype = Iterable.prototype;
47 var nativeIterator = IterablePrototype[ITERATOR]
48 || IterablePrototype['@@iterator']
49 || DEFAULT && IterablePrototype[DEFAULT];
50 var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
51 var anyNativeIterator = NAME === 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
52 var CurrentIteratorPrototype, methods, KEY;
53
54 // fix native
55 if (anyNativeIterator) {
56 CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));
57 if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
58 if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {
59 if (setPrototypeOf) {
60 setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);
61 } else if (!isCallable(CurrentIteratorPrototype[ITERATOR])) {
62 defineBuiltIn(CurrentIteratorPrototype, ITERATOR, returnThis);
63 }
64 }
65 // Set @@toStringTag to native iterators
66 setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
67 if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;
68 }
69 }
70
71 // fix Array.prototype.{ values, @@iterator }.name in V8 / FF
72 if (PROPER_FUNCTION_NAME && DEFAULT === VALUES && nativeIterator && nativeIterator.name !== VALUES) {
73 if (!IS_PURE && CONFIGURABLE_FUNCTION_NAME) {
74 createNonEnumerableProperty(IterablePrototype, 'name', VALUES);
75 } else {
76 INCORRECT_VALUES_NAME = true;
77 defaultIterator = function values() { return call(nativeIterator, this); };
78 }
79 }
80
81 // export additional methods
82 if (DEFAULT) {
83 methods = {
84 values: getIterationMethod(VALUES),
85 keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
86 entries: getIterationMethod(ENTRIES)
87 };
88 if (FORCED) for (KEY in methods) {
89 if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
90 defineBuiltIn(IterablePrototype, KEY, methods[KEY]);
91 }
92 } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
93 }
94
95 // define iterator
96 if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {
97 defineBuiltIn(IterablePrototype, ITERATOR, defaultIterator, { name: DEFAULT });
98 }
99 Iterators[NAME] = defaultIterator;
100
101 return methods;
102};