collection-weak.js 4.4 KB

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