WXL
3 天以前 9bce51f651aad297ef9eb6df832bfdaf1de05d84
node_modules/webpack/lib/util/compileBooleanMatcher.js
@@ -6,12 +6,88 @@
"use strict";
/**
 * Returns quoted meta.
 * @param {string} str string
 * @returns {string} quoted meta
 */
const quoteMeta = (str) => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
/**
 * Quote meta in char class.
 * @param {string} char character to escape for use in character class
 * @returns {string} escaped character
 */
const quoteMetaInCharClass = (char) => {
   // In character class, only these need escaping: ] \ ^ -
   if (char === "]" || char === "\\" || char === "^" || char === "-") {
      return `\\${char}`;
   }
   return char;
};
/**
 * Converts an array of single characters into an optimized character class string
 * using ranges where possible. E.g., ["1","2","3","4","a"] => "1-4a"
 * @param {string[]} chars array of single characters (should be sorted)
 * @returns {string} optimized character class content (without the brackets)
 */
const charsToCharClassContent = (chars) => {
   if (chars.length === 0) return "";
   if (chars.length === 1) return quoteMetaInCharClass(chars[0]);
   // Sort by char code
   const sorted = [...chars].sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));
   /** @type {string[]} */
   const parts = [];
   let rangeStart = sorted[0];
   let rangeEnd = sorted[0];
   for (let i = 1; i < sorted.length; i++) {
      const char = sorted[i];
      const prevCode = rangeEnd.charCodeAt(0);
      const currCode = char.charCodeAt(0);
      if (currCode === prevCode + 1) {
         // Extend the range
         rangeEnd = char;
      } else {
         // Flush the current range
         parts.push(formatRange(rangeStart, rangeEnd));
         rangeStart = char;
         rangeEnd = char;
      }
   }
   // Flush the last range
   parts.push(formatRange(rangeStart, rangeEnd));
   return parts.join("");
};
/**
 * Formats a range of characters for use in a character class
 * @param {string} start start character
 * @param {string} end end character
 * @returns {string} formatted range
 */
const formatRange = (start, end) => {
   const startCode = start.charCodeAt(0);
   const endCode = end.charCodeAt(0);
   const length = endCode - startCode + 1;
   if (length === 1) {
      return quoteMetaInCharClass(start);
   }
   if (length === 2) {
      // For 2 chars, just list them (e.g., "ab" instead of "a-b")
      return quoteMetaInCharClass(start) + quoteMetaInCharClass(end);
   }
   // For 3+ chars, use range notation
   return `${quoteMetaInCharClass(start)}-${quoteMetaInCharClass(end)}`;
};
/**
 * Returns string.
 * @param {string} str string
 * @returns {string} string
 */
@@ -23,6 +99,7 @@
};
/**
 * Compile boolean matcher.
 * @param {Record<string | number, boolean>} map value map
 * @returns {boolean | ((value: string) => string)} true/false, when unconditionally true/false, or a template function to determine the value at runtime
 */
@@ -35,6 +112,7 @@
};
/**
 * Compile boolean matcher from lists.
 * @param {string[]} positiveItems positive items
 * @param {string[]} negativeItems negative items
 * @returns {(value: string) => string} a template function to determine the value at runtime
@@ -59,6 +137,7 @@
/** @typedef {string[][]} ListOfCommonItems */
/**
 * Returns list of common items.
 * @param {Set<string>} itemsSet items set
 * @param {(str: string) => string | false} getKey get key function
 * @param {(str: string[]) => boolean} condition condition
@@ -93,6 +172,7 @@
};
/**
 * Gets common prefix.
 * @param {string[]} items items
 * @returns {string} common prefix
 */
@@ -111,6 +191,7 @@
};
/**
 * Gets common suffix.
 * @param {string[]} items items
 * @returns {string} common suffix
 */
@@ -129,6 +210,7 @@
};
/**
 * Returns regexp.
 * @param {string[]} itemsArr array of items
 * @returns {string} regexp
 */
@@ -148,19 +230,20 @@
   }
   // special case for only single char items
   if (countOfSingleCharItems === itemsArr.length) {
      return `[${quoteMeta(itemsArr.sort().join(""))}]`;
      return `[${charsToCharClassContent(itemsArr)}]`;
   }
   /** @type {Set<string>} */
   const items = new Set(itemsArr.sort());
   if (countOfSingleCharItems > 2) {
      let singleCharItems = "";
      /** @type {string[]} */
      const singleCharItems = [];
      for (const item of items) {
         if (item.length === 1) {
            singleCharItems += item;
            singleCharItems.push(item);
            items.delete(item);
         }
      }
      finishedItems.push(`[${quoteMeta(singleCharItems)}]`);
      finishedItems.push(`[${charsToCharClassContent(singleCharItems)}]`);
   }
   // special case for 2 items with common prefix/suffix
@@ -178,10 +261,10 @@
   // special case for 2 items with common suffix
   if (finishedItems.length === 0 && items.size === 2) {
      /** @type {Iterator<string>} */
      /** @type {SetIterator<string>} */
      const it = items[Symbol.iterator]();
      const a = it.next().value;
      const b = it.next().value;
      const a = /** @type {string} */ (it.next().value);
      const b = /** @type {string} */ (it.next().value);
      if (a.length > 0 && b.length > 0 && a.slice(-1) === b.slice(-1)) {
         return `${itemsToRegexp([a.slice(0, -1), b.slice(0, -1)])}${quoteMeta(
            a.slice(-1)
@@ -227,8 +310,6 @@
      );
   }
   // TODO further optimize regexp, i. e.
   // use ranges: (1|2|3|4|a) => [1-4a]
   /** @type {string[]} */
   const conditional = [...finishedItems, ...Array.from(items, quoteMeta)];
   if (conditional.length === 1) return conditional[0];