massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / linter / node-event-generator.js
index fc7b879f64172b0cc895ef1565d1c2d72d3d763c..8b619fdff83e11fadd43857808062d0b2675e80a 100644 (file)
@@ -10,7 +10,6 @@
 //------------------------------------------------------------------------------
 
 const esquery = require("esquery");
-const lodash = require("lodash");
 
 //------------------------------------------------------------------------------
 // Typedefs
@@ -32,6 +31,35 @@ const lodash = require("lodash");
 // Helpers
 //------------------------------------------------------------------------------
 
+/**
+ * Computes the union of one or more arrays
+ * @param {...any[]} arrays One or more arrays to union
+ * @returns {any[]} The union of the input arrays
+ */
+function union(...arrays) {
+
+    // TODO(stephenwade): Replace this with arrays.flat() when we drop support for Node v10
+    return [...new Set([].concat(...arrays))];
+}
+
+/**
+ * Computes the intersection of one or more arrays
+ * @param {...any[]} arrays One or more arrays to intersect
+ * @returns {any[]} The intersection of the input arrays
+ */
+function intersection(...arrays) {
+    if (arrays.length === 0) {
+        return [];
+    }
+
+    let result = [...new Set(arrays[0])];
+
+    for (const array of arrays.slice(1)) {
+        result = result.filter(x => array.includes(x));
+    }
+    return result;
+}
+
 /**
  * Gets the possible types of a selector
  * @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector
@@ -46,7 +74,7 @@ function getPossibleTypes(parsedSelector) {
             const typesForComponents = parsedSelector.selectors.map(getPossibleTypes);
 
             if (typesForComponents.every(Boolean)) {
-                return lodash.union(...typesForComponents);
+                return union(...typesForComponents);
             }
             return null;
         }
@@ -63,7 +91,7 @@ function getPossibleTypes(parsedSelector) {
              * If at least one of the components could only match a particular type, the compound could only match
              * the intersection of those types.
              */
-            return lodash.intersection(...typesForComponents);
+            return intersection(...typesForComponents);
         }
 
         case "child":
@@ -159,22 +187,28 @@ function tryParseSelector(rawSelector) {
     try {
         return esquery.parse(rawSelector.replace(/:exit$/u, ""));
     } catch (err) {
-        if (typeof err.offset === "number") {
-            throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.offset}: ${err.message}`);
+        if (err.location && err.location.start && typeof err.location.start.offset === "number") {
+            throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.location.start.offset}: ${err.message}`);
         }
         throw err;
     }
 }
 
+const selectorCache = new Map();
+
 /**
  * Parses a raw selector string, and returns the parsed selector along with specificity and type information.
  * @param {string} rawSelector A raw AST selector
  * @returns {ASTSelector} A selector descriptor
  */
-const parseSelector = lodash.memoize(rawSelector => {
+function parseSelector(rawSelector) {
+    if (selectorCache.has(rawSelector)) {
+        return selectorCache.get(rawSelector);
+    }
+
     const parsedSelector = tryParseSelector(rawSelector);
 
-    return {
+    const result = {
         rawSelector,
         isExit: rawSelector.endsWith(":exit"),
         parsedSelector,
@@ -182,7 +216,10 @@ const parseSelector = lodash.memoize(rawSelector => {
         attributeCount: countClassAttributes(parsedSelector),
         identifierCount: countIdentifiers(parsedSelector)
     };
-});
+
+    selectorCache.set(rawSelector, result);
+    return result;
+}
 
 //------------------------------------------------------------------------------
 // Public Interface
@@ -208,10 +245,12 @@ class NodeEventGenerator {
      * An SafeEmitter which is the destination of events. This emitter must already
      * have registered listeners for all of the events that it needs to listen for.
      * (See lib/linter/safe-emitter.js for more details on `SafeEmitter`.)
+     * @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes.
      * @returns {NodeEventGenerator} new instance
      */
-    constructor(emitter) {
+    constructor(emitter, esqueryOptions) {
         this.emitter = emitter;
+        this.esqueryOptions = esqueryOptions;
         this.currentAncestry = [];
         this.enterSelectorsByNodeType = new Map();
         this.exitSelectorsByNodeType = new Map();
@@ -250,7 +289,7 @@ class NodeEventGenerator {
      * @returns {void}
      */
     applySelector(node, selector) {
-        if (esquery.matches(node, selector.parsedSelector, this.currentAncestry)) {
+        if (esquery.matches(node, selector.parsedSelector, this.currentAncestry, this.esqueryOptions)) {
             this.emitter.emit(selector.rawSelector, node);
         }
     }