diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
| commit | efbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch) | |
| tree | 2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/webpack/lib/util/StackedMap.js | |
| parent | 43acceb75957c880a5ba5a31aae221394a36d5f6 (diff) | |
node fixes, updates
Diffstat (limited to 'node_modules/webpack/lib/util/StackedMap.js')
| -rw-r--r-- | node_modules/webpack/lib/util/StackedMap.js | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/util/StackedMap.js b/node_modules/webpack/lib/util/StackedMap.js new file mode 100644 index 00000000..0f4011d0 --- /dev/null +++ b/node_modules/webpack/lib/util/StackedMap.js @@ -0,0 +1,164 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const TOMBSTONE = Symbol("tombstone"); +const UNDEFINED_MARKER = Symbol("undefined"); + +/** + * @template T + * @typedef {T | undefined} Cell<T> + */ + +/** + * @template T + * @typedef {T | typeof TOMBSTONE | typeof UNDEFINED_MARKER} InternalCell<T> + */ + +/** + * @template K + * @template V + * @param {[K, InternalCell<V>]} pair the internal cell + * @returns {[K, Cell<V>]} its “safe” representation + */ +const extractPair = pair => { + const key = pair[0]; + const val = pair[1]; + if (val === UNDEFINED_MARKER || val === TOMBSTONE) { + return [key, undefined]; + } + return /** @type {[K, Cell<V>]} */ (pair); +}; + +/** + * @template K + * @template V + */ +class StackedMap { + /** + * @param {Map<K, InternalCell<V>>[]=} parentStack an optional parent + */ + constructor(parentStack) { + /** @type {Map<K, InternalCell<V>>} */ + this.map = new Map(); + /** @type {Map<K, InternalCell<V>>[]} */ + this.stack = parentStack === undefined ? [] : parentStack.slice(); + this.stack.push(this.map); + } + + /** + * @param {K} item the key of the element to add + * @param {V} value the value of the element to add + * @returns {void} + */ + set(item, value) { + this.map.set(item, value === undefined ? UNDEFINED_MARKER : value); + } + + /** + * @param {K} item the item to delete + * @returns {void} + */ + delete(item) { + if (this.stack.length > 1) { + this.map.set(item, TOMBSTONE); + } else { + this.map.delete(item); + } + } + + /** + * @param {K} item the item to test + * @returns {boolean} true if the item exists in this set + */ + has(item) { + const topValue = this.map.get(item); + if (topValue !== undefined) { + return topValue !== TOMBSTONE; + } + if (this.stack.length > 1) { + for (let i = this.stack.length - 2; i >= 0; i--) { + const value = this.stack[i].get(item); + if (value !== undefined) { + this.map.set(item, value); + return value !== TOMBSTONE; + } + } + this.map.set(item, TOMBSTONE); + } + return false; + } + + /** + * @param {K} item the key of the element to return + * @returns {Cell<V>} the value of the element + */ + get(item) { + const topValue = this.map.get(item); + if (topValue !== undefined) { + return topValue === TOMBSTONE || topValue === UNDEFINED_MARKER + ? undefined + : topValue; + } + if (this.stack.length > 1) { + for (let i = this.stack.length - 2; i >= 0; i--) { + const value = this.stack[i].get(item); + if (value !== undefined) { + this.map.set(item, value); + return value === TOMBSTONE || value === UNDEFINED_MARKER + ? undefined + : value; + } + } + this.map.set(item, TOMBSTONE); + } + } + + _compress() { + if (this.stack.length === 1) return; + this.map = new Map(); + for (const data of this.stack) { + for (const pair of data) { + if (pair[1] === TOMBSTONE) { + this.map.delete(pair[0]); + } else { + this.map.set(pair[0], pair[1]); + } + } + } + this.stack = [this.map]; + } + + asArray() { + this._compress(); + return Array.from(this.map.keys()); + } + + asSet() { + this._compress(); + return new Set(this.map.keys()); + } + + asPairArray() { + this._compress(); + return Array.from(this.map.entries(), extractPair); + } + + asMap() { + return new Map(this.asPairArray()); + } + + get size() { + this._compress(); + return this.map.size; + } + + createChild() { + return new StackedMap(this.stack); + } +} + +module.exports = StackedMap; |
