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