You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.3 KiB
130 lines
4.3 KiB
'use strict'; |
|
var uncurryThis = require('../internals/function-uncurry-this'); |
|
var redefineAll = require('../internals/redefine-all'); |
|
var getWeakData = require('../internals/internal-metadata').getWeakData; |
|
var anObject = require('../internals/an-object'); |
|
var isObject = require('../internals/is-object'); |
|
var anInstance = require('../internals/an-instance'); |
|
var iterate = require('../internals/iterate'); |
|
var ArrayIterationModule = require('../internals/array-iteration'); |
|
var hasOwn = require('../internals/has-own-property'); |
|
var InternalStateModule = require('../internals/internal-state'); |
|
|
|
var setInternalState = InternalStateModule.set; |
|
var internalStateGetterFor = InternalStateModule.getterFor; |
|
var find = ArrayIterationModule.find; |
|
var findIndex = ArrayIterationModule.findIndex; |
|
var splice = uncurryThis([].splice); |
|
var id = 0; |
|
|
|
// fallback for uncaught frozen keys |
|
var uncaughtFrozenStore = function (store) { |
|
return store.frozen || (store.frozen = new UncaughtFrozenStore()); |
|
}; |
|
|
|
var UncaughtFrozenStore = function () { |
|
this.entries = []; |
|
}; |
|
|
|
var findUncaughtFrozen = function (store, key) { |
|
return find(store.entries, function (it) { |
|
return it[0] === key; |
|
}); |
|
}; |
|
|
|
UncaughtFrozenStore.prototype = { |
|
get: function (key) { |
|
var entry = findUncaughtFrozen(this, key); |
|
if (entry) return entry[1]; |
|
}, |
|
has: function (key) { |
|
return !!findUncaughtFrozen(this, key); |
|
}, |
|
set: function (key, value) { |
|
var entry = findUncaughtFrozen(this, key); |
|
if (entry) entry[1] = value; |
|
else this.entries.push([key, value]); |
|
}, |
|
'delete': function (key) { |
|
var index = findIndex(this.entries, function (it) { |
|
return it[0] === key; |
|
}); |
|
if (~index) splice(this.entries, index, 1); |
|
return !!~index; |
|
} |
|
}; |
|
|
|
module.exports = { |
|
getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { |
|
var Constructor = wrapper(function (that, iterable) { |
|
anInstance(that, Prototype); |
|
setInternalState(that, { |
|
type: CONSTRUCTOR_NAME, |
|
id: id++, |
|
frozen: undefined |
|
}); |
|
if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); |
|
}); |
|
|
|
var Prototype = Constructor.prototype; |
|
|
|
var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); |
|
|
|
var define = function (that, key, value) { |
|
var state = getInternalState(that); |
|
var data = getWeakData(anObject(key), true); |
|
if (data === true) uncaughtFrozenStore(state).set(key, value); |
|
else data[state.id] = value; |
|
return that; |
|
}; |
|
|
|
redefineAll(Prototype, { |
|
// `{ WeakMap, WeakSet }.prototype.delete(key)` methods |
|
// https://tc39.es/ecma262/#sec-weakmap.prototype.delete |
|
// https://tc39.es/ecma262/#sec-weakset.prototype.delete |
|
'delete': function (key) { |
|
var state = getInternalState(this); |
|
if (!isObject(key)) return false; |
|
var data = getWeakData(key); |
|
if (data === true) return uncaughtFrozenStore(state)['delete'](key); |
|
return data && hasOwn(data, state.id) && delete data[state.id]; |
|
}, |
|
// `{ WeakMap, WeakSet }.prototype.has(key)` methods |
|
// https://tc39.es/ecma262/#sec-weakmap.prototype.has |
|
// https://tc39.es/ecma262/#sec-weakset.prototype.has |
|
has: function has(key) { |
|
var state = getInternalState(this); |
|
if (!isObject(key)) return false; |
|
var data = getWeakData(key); |
|
if (data === true) return uncaughtFrozenStore(state).has(key); |
|
return data && hasOwn(data, state.id); |
|
} |
|
}); |
|
|
|
redefineAll(Prototype, IS_MAP ? { |
|
// `WeakMap.prototype.get(key)` method |
|
// https://tc39.es/ecma262/#sec-weakmap.prototype.get |
|
get: function get(key) { |
|
var state = getInternalState(this); |
|
if (isObject(key)) { |
|
var data = getWeakData(key); |
|
if (data === true) return uncaughtFrozenStore(state).get(key); |
|
return data ? data[state.id] : undefined; |
|
} |
|
}, |
|
// `WeakMap.prototype.set(key, value)` method |
|
// https://tc39.es/ecma262/#sec-weakmap.prototype.set |
|
set: function set(key, value) { |
|
return define(this, key, value); |
|
} |
|
} : { |
|
// `WeakSet.prototype.add(value)` method |
|
// https://tc39.es/ecma262/#sec-weakset.prototype.add |
|
add: function add(value) { |
|
return define(this, value, true); |
|
} |
|
}); |
|
|
|
return Constructor; |
|
} |
|
};
|
|
|