| 1 | 'use strict';
|
|---|
| 2 | var uncurryThis = require('../internals/function-uncurry-this');
|
|---|
| 3 | var defineBuiltIns = require('../internals/define-built-ins');
|
|---|
| 4 | var getWeakData = require('../internals/internal-metadata').getWeakData;
|
|---|
| 5 | var anInstance = require('../internals/an-instance');
|
|---|
| 6 | var anObject = require('../internals/an-object');
|
|---|
| 7 | var isNullOrUndefined = require('../internals/is-null-or-undefined');
|
|---|
| 8 | var isObject = require('../internals/is-object');
|
|---|
| 9 | var iterate = require('../internals/iterate');
|
|---|
| 10 | var ArrayIterationModule = require('../internals/array-iteration');
|
|---|
| 11 | var hasOwn = require('../internals/has-own-property');
|
|---|
| 12 | var InternalStateModule = require('../internals/internal-state');
|
|---|
| 13 |
|
|---|
| 14 | var setInternalState = InternalStateModule.set;
|
|---|
| 15 | var internalStateGetterFor = InternalStateModule.getterFor;
|
|---|
| 16 | var find = ArrayIterationModule.find;
|
|---|
| 17 | var findIndex = ArrayIterationModule.findIndex;
|
|---|
| 18 | var splice = uncurryThis([].splice);
|
|---|
| 19 | var id = 0;
|
|---|
| 20 |
|
|---|
| 21 | // fallback for uncaught frozen keys
|
|---|
| 22 | var uncaughtFrozenStore = function (state) {
|
|---|
| 23 | return state.frozen || (state.frozen = new UncaughtFrozenStore());
|
|---|
| 24 | };
|
|---|
| 25 |
|
|---|
| 26 | var UncaughtFrozenStore = function () {
|
|---|
| 27 | this.entries = [];
|
|---|
| 28 | };
|
|---|
| 29 |
|
|---|
| 30 | var findUncaughtFrozen = function (store, key) {
|
|---|
| 31 | return find(store.entries, function (it) {
|
|---|
| 32 | return it[0] === key;
|
|---|
| 33 | });
|
|---|
| 34 | };
|
|---|
| 35 |
|
|---|
| 36 | UncaughtFrozenStore.prototype = {
|
|---|
| 37 | get: function (key) {
|
|---|
| 38 | var entry = findUncaughtFrozen(this, key);
|
|---|
| 39 | if (entry) return entry[1];
|
|---|
| 40 | },
|
|---|
| 41 | has: function (key) {
|
|---|
| 42 | return !!findUncaughtFrozen(this, key);
|
|---|
| 43 | },
|
|---|
| 44 | set: function (key, value) {
|
|---|
| 45 | var entry = findUncaughtFrozen(this, key);
|
|---|
| 46 | if (entry) entry[1] = value;
|
|---|
| 47 | else this.entries.push([key, value]);
|
|---|
| 48 | },
|
|---|
| 49 | 'delete': function (key) {
|
|---|
| 50 | var index = findIndex(this.entries, function (it) {
|
|---|
| 51 | return it[0] === key;
|
|---|
| 52 | });
|
|---|
| 53 | if (~index) splice(this.entries, index, 1);
|
|---|
| 54 | return !!~index;
|
|---|
| 55 | }
|
|---|
| 56 | };
|
|---|
| 57 |
|
|---|
| 58 | module.exports = {
|
|---|
| 59 | getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
|
|---|
| 60 | var Constructor = wrapper(function (that, iterable) {
|
|---|
| 61 | anInstance(that, Prototype);
|
|---|
| 62 | setInternalState(that, {
|
|---|
| 63 | type: CONSTRUCTOR_NAME,
|
|---|
| 64 | id: id++,
|
|---|
| 65 | frozen: null
|
|---|
| 66 | });
|
|---|
| 67 | if (!isNullOrUndefined(iterable)) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP });
|
|---|
| 68 | });
|
|---|
| 69 |
|
|---|
| 70 | var Prototype = Constructor.prototype;
|
|---|
| 71 |
|
|---|
| 72 | var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
|
|---|
| 73 |
|
|---|
| 74 | var define = function (that, key, value) {
|
|---|
| 75 | var state = getInternalState(that);
|
|---|
| 76 | var data = getWeakData(anObject(key), true);
|
|---|
| 77 | if (data === true) uncaughtFrozenStore(state).set(key, value);
|
|---|
| 78 | else data[state.id] = value;
|
|---|
| 79 | return that;
|
|---|
| 80 | };
|
|---|
| 81 |
|
|---|
| 82 | defineBuiltIns(Prototype, {
|
|---|
| 83 | // `{ WeakMap, WeakSet }.prototype.delete(key)` methods
|
|---|
| 84 | // https://tc39.es/ecma262/#sec-weakmap.prototype.delete
|
|---|
| 85 | // https://tc39.es/ecma262/#sec-weakset.prototype.delete
|
|---|
| 86 | 'delete': function (key) {
|
|---|
| 87 | var state = getInternalState(this);
|
|---|
| 88 | if (!isObject(key)) return false;
|
|---|
| 89 | var data = getWeakData(key);
|
|---|
| 90 | if (data === true) return uncaughtFrozenStore(state)['delete'](key);
|
|---|
| 91 | return data && hasOwn(data, state.id) && delete data[state.id];
|
|---|
| 92 | },
|
|---|
| 93 | // `{ WeakMap, WeakSet }.prototype.has(key)` methods
|
|---|
| 94 | // https://tc39.es/ecma262/#sec-weakmap.prototype.has
|
|---|
| 95 | // https://tc39.es/ecma262/#sec-weakset.prototype.has
|
|---|
| 96 | has: function has(key) {
|
|---|
| 97 | var state = getInternalState(this);
|
|---|
| 98 | if (!isObject(key)) return false;
|
|---|
| 99 | var data = getWeakData(key);
|
|---|
| 100 | if (data === true) return uncaughtFrozenStore(state).has(key);
|
|---|
| 101 | return data && hasOwn(data, state.id);
|
|---|
| 102 | }
|
|---|
| 103 | });
|
|---|
| 104 |
|
|---|
| 105 | defineBuiltIns(Prototype, IS_MAP ? {
|
|---|
| 106 | // `WeakMap.prototype.get(key)` method
|
|---|
| 107 | // https://tc39.es/ecma262/#sec-weakmap.prototype.get
|
|---|
| 108 | get: function get(key) {
|
|---|
| 109 | var state = getInternalState(this);
|
|---|
| 110 | if (isObject(key)) {
|
|---|
| 111 | var data = getWeakData(key);
|
|---|
| 112 | if (data === true) return uncaughtFrozenStore(state).get(key);
|
|---|
| 113 | if (data) return data[state.id];
|
|---|
| 114 | }
|
|---|
| 115 | },
|
|---|
| 116 | // `WeakMap.prototype.set(key, value)` method
|
|---|
| 117 | // https://tc39.es/ecma262/#sec-weakmap.prototype.set
|
|---|
| 118 | set: function set(key, value) {
|
|---|
| 119 | return define(this, key, value);
|
|---|
| 120 | }
|
|---|
| 121 | } : {
|
|---|
| 122 | // `WeakSet.prototype.add(value)` method
|
|---|
| 123 | // https://tc39.es/ecma262/#sec-weakset.prototype.add
|
|---|
| 124 | add: function add(value) {
|
|---|
| 125 | return define(this, value, true);
|
|---|
| 126 | }
|
|---|
| 127 | });
|
|---|
| 128 |
|
|---|
| 129 | return Constructor;
|
|---|
| 130 | }
|
|---|
| 131 | };
|
|---|