From efbc2ffe6a1ee5ec38a4396305561d6515d0943e Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Fri, 30 Aug 2024 17:21:18 +0800 Subject: node fixes, updates --- node_modules/webpack/lib/util/comparators.js | 522 +++++++++++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 node_modules/webpack/lib/util/comparators.js (limited to 'node_modules/webpack/lib/util/comparators.js') diff --git a/node_modules/webpack/lib/util/comparators.js b/node_modules/webpack/lib/util/comparators.js new file mode 100644 index 00000000..8d228026 --- /dev/null +++ b/node_modules/webpack/lib/util/comparators.js @@ -0,0 +1,522 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { compareRuntime } = require("./runtime"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ +/** @typedef {import("../ChunkGroup")} ChunkGroup */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ + +/** + * @template T + * @typedef {function(T, T): -1|0|1} Comparator + */ +/** + * @template TArg + * @template T + * @typedef {function(TArg, T, T): -1|0|1} RawParameterizedComparator + */ +/** + * @template TArg + * @template T + * @typedef {function(TArg): Comparator} ParameterizedComparator + */ + +/** + * @template T + * @param {RawParameterizedComparator} fn comparator with argument + * @returns {ParameterizedComparator} comparator + */ +const createCachedParameterizedComparator = fn => { + /** @type {WeakMap>} */ + const map = new WeakMap(); + return arg => { + const cachedResult = map.get(arg); + if (cachedResult !== undefined) return cachedResult; + /** + * @param {T} a first item + * @param {T} b second item + * @returns {-1|0|1} compare result + */ + const result = fn.bind(null, arg); + map.set(arg, result); + return result; + }; +}; + +/** + * @param {Chunk} a chunk + * @param {Chunk} b chunk + * @returns {-1|0|1} compare result + */ +module.exports.compareChunksById = (a, b) => + compareIds(/** @type {ChunkId} */ (a.id), /** @type {ChunkId} */ (b.id)); + +/** + * @param {Module} a module + * @param {Module} b module + * @returns {-1|0|1} compare result + */ +module.exports.compareModulesByIdentifier = (a, b) => + compareIds(a.identifier(), b.identifier()); + +/** + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {Module} a module + * @param {Module} b module + * @returns {-1|0|1} compare result + */ +const compareModulesById = (chunkGraph, a, b) => + compareIds( + /** @type {ModuleId} */ (chunkGraph.getModuleId(a)), + /** @type {ModuleId} */ (chunkGraph.getModuleId(b)) + ); +/** @type {ParameterizedComparator} */ +module.exports.compareModulesById = + createCachedParameterizedComparator(compareModulesById); + +/** + * @param {number} a number + * @param {number} b number + * @returns {-1|0|1} compare result + */ +const compareNumbers = (a, b) => { + if (typeof a !== typeof b) { + return typeof a < typeof b ? -1 : 1; + } + if (a < b) return -1; + if (a > b) return 1; + return 0; +}; +module.exports.compareNumbers = compareNumbers; + +/** + * @param {string} a string + * @param {string} b string + * @returns {-1|0|1} compare result + */ +const compareStringsNumeric = (a, b) => { + const aLength = a.length; + const bLength = b.length; + + let aChar = 0; + let bChar = 0; + + let aIsDigit = false; + let bIsDigit = false; + let i = 0; + let j = 0; + while (i < aLength && j < bLength) { + aChar = a.charCodeAt(i); + bChar = b.charCodeAt(j); + + aIsDigit = aChar >= 48 && aChar <= 57; + bIsDigit = bChar >= 48 && bChar <= 57; + + if (!aIsDigit && !bIsDigit) { + if (aChar < bChar) return -1; + if (aChar > bChar) return 1; + i++; + j++; + } else if (aIsDigit && !bIsDigit) { + // This segment of a is shorter than in b + return 1; + } else if (!aIsDigit && bIsDigit) { + // This segment of b is shorter than in a + return -1; + } else { + let aNumber = aChar - 48; + let bNumber = bChar - 48; + + while (++i < aLength) { + aChar = a.charCodeAt(i); + if (aChar < 48 || aChar > 57) break; + aNumber = aNumber * 10 + aChar - 48; + } + + while (++j < bLength) { + bChar = b.charCodeAt(j); + if (bChar < 48 || bChar > 57) break; + bNumber = bNumber * 10 + bChar - 48; + } + + if (aNumber < bNumber) return -1; + if (aNumber > bNumber) return 1; + } + } + + if (j < bLength) { + // a is shorter than b + bChar = b.charCodeAt(j); + bIsDigit = bChar >= 48 && bChar <= 57; + return bIsDigit ? -1 : 1; + } + if (i < aLength) { + // b is shorter than a + aChar = a.charCodeAt(i); + aIsDigit = aChar >= 48 && aChar <= 57; + return aIsDigit ? 1 : -1; + } + + return 0; +}; +module.exports.compareStringsNumeric = compareStringsNumeric; + +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {Module} a module + * @param {Module} b module + * @returns {-1|0|1} compare result + */ +const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => { + const cmp = compareNumbers( + /** @type {number} */ (moduleGraph.getPostOrderIndex(a)), + /** @type {number} */ (moduleGraph.getPostOrderIndex(b)) + ); + if (cmp !== 0) return cmp; + return compareIds(a.identifier(), b.identifier()); +}; +/** @type {ParameterizedComparator} */ +module.exports.compareModulesByPostOrderIndexOrIdentifier = + createCachedParameterizedComparator( + compareModulesByPostOrderIndexOrIdentifier + ); + +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {Module} a module + * @param {Module} b module + * @returns {-1|0|1} compare result + */ +const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => { + const cmp = compareNumbers( + /** @type {number} */ (moduleGraph.getPreOrderIndex(a)), + /** @type {number} */ (moduleGraph.getPreOrderIndex(b)) + ); + if (cmp !== 0) return cmp; + return compareIds(a.identifier(), b.identifier()); +}; +/** @type {ParameterizedComparator} */ +module.exports.compareModulesByPreOrderIndexOrIdentifier = + createCachedParameterizedComparator( + compareModulesByPreOrderIndexOrIdentifier + ); + +/** + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {Module} a module + * @param {Module} b module + * @returns {-1|0|1} compare result + */ +const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => { + const cmp = compareIds( + /** @type {ModuleId} */ (chunkGraph.getModuleId(a)), + /** @type {ModuleId} */ (chunkGraph.getModuleId(b)) + ); + if (cmp !== 0) return cmp; + return compareIds(a.identifier(), b.identifier()); +}; +/** @type {ParameterizedComparator} */ +module.exports.compareModulesByIdOrIdentifier = + createCachedParameterizedComparator(compareModulesByIdOrIdentifier); + +/** + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {Chunk} a chunk + * @param {Chunk} b chunk + * @returns {-1|0|1} compare result + */ +const compareChunks = (chunkGraph, a, b) => chunkGraph.compareChunks(a, b); +/** @type {ParameterizedComparator} */ +module.exports.compareChunks = + createCachedParameterizedComparator(compareChunks); + +/** + * @param {string|number} a first id + * @param {string|number} b second id + * @returns {-1|0|1} compare result + */ +const compareIds = (a, b) => { + if (typeof a !== typeof b) { + return typeof a < typeof b ? -1 : 1; + } + if (a < b) return -1; + if (a > b) return 1; + return 0; +}; + +module.exports.compareIds = compareIds; + +/** + * @param {string} a first string + * @param {string} b second string + * @returns {-1|0|1} compare result + */ +const compareStrings = (a, b) => { + if (a < b) return -1; + if (a > b) return 1; + return 0; +}; + +module.exports.compareStrings = compareStrings; + +/** + * @param {ChunkGroup} a first chunk group + * @param {ChunkGroup} b second chunk group + * @returns {-1|0|1} compare result + */ +const compareChunkGroupsByIndex = (a, b) => + /** @type {number} */ (a.index) < /** @type {number} */ (b.index) ? -1 : 1; +module.exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex; + +/** + * @template K1 {Object} + * @template K2 + * @template T + */ +class TwoKeyWeakMap { + constructor() { + /** + * @private + * @type {WeakMap>} + */ + this._map = new WeakMap(); + } + + /** + * @param {K1} key1 first key + * @param {K2} key2 second key + * @returns {T | undefined} value + */ + get(key1, key2) { + const childMap = this._map.get(key1); + if (childMap === undefined) { + return; + } + return childMap.get(key2); + } + + /** + * @param {K1} key1 first key + * @param {K2} key2 second key + * @param {T | undefined} value new value + * @returns {void} + */ + set(key1, key2, value) { + let childMap = this._map.get(key1); + if (childMap === undefined) { + childMap = new WeakMap(); + this._map.set(key1, childMap); + } + childMap.set(key2, value); + } +} + +/** @type {TwoKeyWeakMap, Comparator, Comparator>}} */ +const concatComparatorsCache = new TwoKeyWeakMap(); + +/** + * @template T + * @param {Comparator} c1 comparator + * @param {Comparator} c2 comparator + * @param {Comparator[]} cRest comparators + * @returns {Comparator} comparator + */ +const concatComparators = (c1, c2, ...cRest) => { + if (cRest.length > 0) { + const [c3, ...cRest2] = cRest; + return concatComparators(c1, concatComparators(c2, c3, ...cRest2)); + } + const cacheEntry = /** @type {Comparator} */ ( + concatComparatorsCache.get(c1, c2) + ); + if (cacheEntry !== undefined) return cacheEntry; + /** + * @param {T} a first value + * @param {T} b second value + * @returns {-1|0|1} compare result + */ + const result = (a, b) => { + const res = c1(a, b); + if (res !== 0) return res; + return c2(a, b); + }; + concatComparatorsCache.set(c1, c2, result); + return result; +}; +module.exports.concatComparators = concatComparators; + +/** + * @template A, B + * @typedef {(input: A) => B | undefined | null} Selector + */ + +/** @type {TwoKeyWeakMap, Comparator, Comparator>}} */ +const compareSelectCache = new TwoKeyWeakMap(); + +/** + * @template T + * @template R + * @param {Selector} getter getter for value + * @param {Comparator} comparator comparator + * @returns {Comparator} comparator + */ +const compareSelect = (getter, comparator) => { + const cacheEntry = compareSelectCache.get(getter, comparator); + if (cacheEntry !== undefined) return cacheEntry; + /** + * @param {T} a first value + * @param {T} b second value + * @returns {-1|0|1} compare result + */ + const result = (a, b) => { + const aValue = getter(a); + const bValue = getter(b); + if (aValue !== undefined && aValue !== null) { + if (bValue !== undefined && bValue !== null) { + return comparator(aValue, bValue); + } + return -1; + } + if (bValue !== undefined && bValue !== null) { + return 1; + } + return 0; + }; + compareSelectCache.set(getter, comparator, result); + return result; +}; +module.exports.compareSelect = compareSelect; + +/** @type {WeakMap, Comparator>>} */ +const compareIteratorsCache = new WeakMap(); + +/** + * @template T + * @param {Comparator} elementComparator comparator for elements + * @returns {Comparator>} comparator for iterables of elements + */ +const compareIterables = elementComparator => { + const cacheEntry = compareIteratorsCache.get(elementComparator); + if (cacheEntry !== undefined) return cacheEntry; + /** + * @param {Iterable} a first value + * @param {Iterable} b second value + * @returns {-1|0|1} compare result + */ + const result = (a, b) => { + const aI = a[Symbol.iterator](); + const bI = b[Symbol.iterator](); + while (true) { + const aItem = aI.next(); + const bItem = bI.next(); + if (aItem.done) { + return bItem.done ? 0 : -1; + } else if (bItem.done) { + return 1; + } + const res = elementComparator(aItem.value, bItem.value); + if (res !== 0) return res; + } + }; + compareIteratorsCache.set(elementComparator, result); + return result; +}; +module.exports.compareIterables = compareIterables; + +// TODO this is no longer needed when minimum node.js version is >= 12 +// since these versions ship with a stable sort function +/** + * @template T + * @param {Iterable} iterable original ordered list + * @returns {Comparator} comparator + */ +module.exports.keepOriginalOrder = iterable => { + /** @type {Map} */ + const map = new Map(); + let i = 0; + for (const item of iterable) { + map.set(item, i++); + } + return (a, b) => + compareNumbers( + /** @type {number} */ (map.get(a)), + /** @type {number} */ (map.get(b)) + ); +}; + +/** + * @param {ChunkGraph} chunkGraph the chunk graph + * @returns {Comparator} comparator + */ +module.exports.compareChunksNatural = chunkGraph => { + const cmpFn = module.exports.compareModulesById(chunkGraph); + const cmpIterableFn = compareIterables(cmpFn); + return concatComparators( + compareSelect( + chunk => /** @type {string|number} */ (chunk.name), + compareIds + ), + compareSelect(chunk => chunk.runtime, compareRuntime), + compareSelect( + /** + * @param {Chunk} chunk a chunk + * @returns {Iterable} modules + */ + chunk => chunkGraph.getOrderedChunkModulesIterable(chunk, cmpFn), + cmpIterableFn + ) + ); +}; + +/** + * Compare two locations + * @param {DependencyLocation} a A location node + * @param {DependencyLocation} b A location node + * @returns {-1|0|1} sorting comparator value + */ +module.exports.compareLocations = (a, b) => { + const isObjectA = typeof a === "object" && a !== null; + const isObjectB = typeof b === "object" && b !== null; + if (!isObjectA || !isObjectB) { + if (isObjectA) return 1; + if (isObjectB) return -1; + return 0; + } + if ("start" in a) { + if ("start" in b) { + const ap = a.start; + const bp = b.start; + if (ap.line < bp.line) return -1; + if (ap.line > bp.line) return 1; + if (/** @type {number} */ (ap.column) < /** @type {number} */ (bp.column)) + return -1; + if (/** @type {number} */ (ap.column) > /** @type {number} */ (bp.column)) + return 1; + } else return -1; + } else if ("start" in b) return 1; + if ("name" in a) { + if ("name" in b) { + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + } else return -1; + } else if ("name" in b) return 1; + if ("index" in a) { + if ("index" in b) { + if (/** @type {number} */ (a.index) < /** @type {number} */ (b.index)) + return -1; + if (/** @type {number} */ (a.index) > /** @type {number} */ (b.index)) + return 1; + } else return -1; + } else if ("index" in b) return 1; + return 0; +}; -- cgit v1.2.3