[79a0317] | 1 | 'use strict';
|
---|
| 2 | var $ = require('../internals/export');
|
---|
| 3 | var globalThis = require('../internals/global-this');
|
---|
| 4 | var uncurryThis = require('../internals/function-uncurry-this');
|
---|
| 5 | var isForced = require('../internals/is-forced');
|
---|
| 6 | var defineBuiltIn = require('../internals/define-built-in');
|
---|
| 7 | var InternalMetadataModule = require('../internals/internal-metadata');
|
---|
| 8 | var iterate = require('../internals/iterate');
|
---|
| 9 | var anInstance = require('../internals/an-instance');
|
---|
| 10 | var isCallable = require('../internals/is-callable');
|
---|
| 11 | var isNullOrUndefined = require('../internals/is-null-or-undefined');
|
---|
| 12 | var isObject = require('../internals/is-object');
|
---|
| 13 | var fails = require('../internals/fails');
|
---|
| 14 | var checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');
|
---|
| 15 | var setToStringTag = require('../internals/set-to-string-tag');
|
---|
| 16 | var inheritIfRequired = require('../internals/inherit-if-required');
|
---|
| 17 |
|
---|
| 18 | module.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 = globalThis[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 | };
|
---|