UNPKG

4.59 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var global = require('../internals/global');
4var uncurryThis = require('../internals/function-uncurry-this');
5var isForced = require('../internals/is-forced');
6var defineBuiltIn = require('../internals/define-built-in');
7var InternalMetadataModule = require('../internals/internal-metadata');
8var iterate = require('../internals/iterate');
9var anInstance = require('../internals/an-instance');
10var isCallable = require('../internals/is-callable');
11var isNullOrUndefined = require('../internals/is-null-or-undefined');
12var isObject = require('../internals/is-object');
13var fails = require('../internals/fails');
14var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');
15var setToStringTag = require('../internals/set-to-string-tag');
16var inheritIfRequired = require('../internals/inherit-if-required');
17
18module.exports = function (CONSTRUCTOR_NAME, wrapper, common) {
19 var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1;
20 var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1;
21 var ADDER = IS_MAP ? 'set' : 'add';
22 var NativeConstructor = global[CONSTRUCTOR_NAME];
23 var NativePrototype = NativeConstructor && NativeConstructor.prototype;
24 var Constructor = NativeConstructor;
25 var exported = {};
26
27 var fixMethod = function (KEY) {
28 var uncurriedNativeMethod = uncurryThis(NativePrototype[KEY]);
29 defineBuiltIn(NativePrototype, KEY,
30 KEY === 'add' ? function add(value) {
31 uncurriedNativeMethod(this, value === 0 ? 0 : value);
32 return this;
33 } : KEY === 'delete' ? function (key) {
34 return IS_WEAK && !isObject(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key);
35 } : KEY === 'get' ? function get(key) {
36 return IS_WEAK && !isObject(key) ? undefined : uncurriedNativeMethod(this, key === 0 ? 0 : key);
37 } : KEY === 'has' ? function has(key) {
38 return IS_WEAK && !isObject(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key);
39 } : function set(key, value) {
40 uncurriedNativeMethod(this, key === 0 ? 0 : key, value);
41 return this;
42 }
43 );
44 };
45
46 var REPLACE = isForced(
47 CONSTRUCTOR_NAME,
48 !isCallable(NativeConstructor) || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
49 new NativeConstructor().entries().next();
50 }))
51 );
52
53 if (REPLACE) {
54 // create collection constructor
55 Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
56 InternalMetadataModule.enable();
57 } else if (isForced(CONSTRUCTOR_NAME, true)) {
58 var instance = new Constructor();
59 // early implementations not supports chaining
60 var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) !== instance;
61 // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
62 var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
63 // most early implementations doesn't supports iterables, most modern - not close it correctly
64 // eslint-disable-next-line no-new -- required for testing
65 var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
66 // for early implementations -0 and +0 not the same
67 var BUGGY_ZERO = !IS_WEAK && fails(function () {
68 // V8 ~ Chromium 42- fails only with 5+ elements
69 var $instance = new NativeConstructor();
70 var index = 5;
71 while (index--) $instance[ADDER](index, index);
72 return !$instance.has(-0);
73 });
74
75 if (!ACCEPT_ITERABLES) {
76 Constructor = wrapper(function (dummy, iterable) {
77 anInstance(dummy, NativePrototype);
78 var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
79 if (!isNullOrUndefined(iterable)) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
80 return that;
81 });
82 Constructor.prototype = NativePrototype;
83 NativePrototype.constructor = Constructor;
84 }
85
86 if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
87 fixMethod('delete');
88 fixMethod('has');
89 IS_MAP && fixMethod('get');
90 }
91
92 if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
93
94 // weak collections should not contains .clear method
95 if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
96 }
97
98 exported[CONSTRUCTOR_NAME] = Constructor;
99 $({ global: true, constructor: true, forced: Constructor !== NativeConstructor }, exported);
100
101 setToStringTag(Constructor, CONSTRUCTOR_NAME);
102
103 if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
104
105 return Constructor;
106};