mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			122 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Tobias Koppers @sokra
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const TOMBSTONE = {};
 | |
| const UNDEFINED_MARKER = {};
 | |
| 
 | |
| class StackedSetMap {
 | |
| 	constructor(parentStack) {
 | |
| 		this.stack = parentStack === undefined ? [] : parentStack.slice();
 | |
| 		this.map = new Map();
 | |
| 		this.stack.push(this.map);
 | |
| 	}
 | |
| 
 | |
| 	add(item) {
 | |
| 		this.map.set(item, true);
 | |
| 	}
 | |
| 
 | |
| 	set(item, value) {
 | |
| 		this.map.set(item, value === undefined ? UNDEFINED_MARKER : value);
 | |
| 	}
 | |
| 
 | |
| 	delete(item) {
 | |
| 		if (this.stack.length > 1) {
 | |
| 			this.map.set(item, TOMBSTONE);
 | |
| 		} else {
 | |
| 			this.map.delete(item);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	has(item) {
 | |
| 		const topValue = this.map.get(item);
 | |
| 		if (topValue !== undefined) return topValue !== TOMBSTONE;
 | |
| 		if (this.stack.length > 1) {
 | |
| 			for (var 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;
 | |
| 	}
 | |
| 
 | |
| 	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 (var 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);
 | |
| 		}
 | |
| 		return undefined;
 | |
| 	}
 | |
| 
 | |
| 	_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.entries(), pair => pair[0]);
 | |
| 	}
 | |
| 
 | |
| 	asSet() {
 | |
| 		return new Set(this.asArray());
 | |
| 	}
 | |
| 
 | |
| 	asPairArray() {
 | |
| 		this._compress();
 | |
| 		return Array.from(
 | |
| 			this.map.entries(),
 | |
| 			pair =>
 | |
| 				/** @type {[TODO, TODO]} */ (pair[1] === UNDEFINED_MARKER
 | |
| 					? [pair[0], undefined]
 | |
| 					: pair)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	asMap() {
 | |
| 		return new Map(this.asPairArray());
 | |
| 	}
 | |
| 
 | |
| 	get size() {
 | |
| 		this._compress();
 | |
| 		return this.map.size;
 | |
| 	}
 | |
| 
 | |
| 	createChild() {
 | |
| 		return new StackedSetMap(this.stack);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module.exports = StackedSetMap;
 |