massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-unused-vars.js
index 4dc6dc2bab34bc074264772921694a6c0572c370..f04818f8e9d5979f2879af8954dfd6207df254ab 100644 (file)
@@ -196,6 +196,17 @@ module.exports = {
 
         }
 
+        /**
+         * Checks whether a node is a sibling of the rest property or not.
+         * @param {ASTNode} node a node to check
+         * @returns {boolean} True if the node is a sibling of the rest property, otherwise false.
+         */
+        function hasRestSibling(node) {
+            return node.type === "Property" &&
+                node.parent.type === "ObjectPattern" &&
+                REST_PROPERTY_TYPE.test(node.parent.properties[node.parent.properties.length - 1].type);
+        }
+
         /**
          * Determines if a variable has a sibling rest property
          * @param {Variable} variable eslint-scope variable object.
@@ -204,16 +215,10 @@ module.exports = {
          */
         function hasRestSpreadSibling(variable) {
             if (config.ignoreRestSiblings) {
-                return variable.defs.some(def => {
-                    const propertyNode = def.name.parent;
-                    const patternNode = propertyNode.parent;
-
-                    return (
-                        propertyNode.type === "Property" &&
-                        patternNode.type === "ObjectPattern" &&
-                        REST_PROPERTY_TYPE.test(patternNode.properties[patternNode.properties.length - 1].type)
-                    );
-                });
+                const hasRestSiblingDefinition = variable.defs.some(def => hasRestSibling(def.name.parent));
+                const hasRestSiblingReference = variable.references.some(ref => hasRestSibling(ref.identifier.parent));
+
+                return hasRestSiblingDefinition || hasRestSiblingReference;
             }
 
             return false;
@@ -405,6 +410,31 @@ module.exports = {
             );
         }
 
+        /**
+         * Checks whether a given node is unused expression or not.
+         * @param {ASTNode} node The node itself
+         * @returns {boolean} The node is an unused expression.
+         * @private
+         */
+        function isUnusedExpression(node) {
+            const parent = node.parent;
+
+            if (parent.type === "ExpressionStatement") {
+                return true;
+            }
+
+            if (parent.type === "SequenceExpression") {
+                const isLastExpression = parent.expressions[parent.expressions.length - 1] === node;
+
+                if (!isLastExpression) {
+                    return true;
+                }
+                return isUnusedExpression(parent);
+            }
+
+            return false;
+        }
+
         /**
          * Checks whether a given reference is a read to update itself or not.
          * @param {eslint-scope.Reference} ref A reference to check.
@@ -415,23 +445,28 @@ module.exports = {
         function isReadForItself(ref, rhsNode) {
             const id = ref.identifier;
             const parent = id.parent;
-            const grandparent = parent.parent;
 
             return ref.isRead() && (
 
                 // self update. e.g. `a += 1`, `a++`
-                (// in RHS of an assignment for itself. e.g. `a = a + 1`
-                    ((
+                (
+                    (
                         parent.type === "AssignmentExpression" &&
-                    grandparent.type === "ExpressionStatement" &&
-                    parent.left === id
+                        parent.left === id &&
+                        isUnusedExpression(parent)
                     ) ||
+                    (
+                        parent.type === "UpdateExpression" &&
+                        isUnusedExpression(parent)
+                    )
+                ) ||
+
+                // in RHS of an assignment for itself. e.g. `a = a + 1`
                 (
-                    parent.type === "UpdateExpression" &&
-                    grandparent.type === "ExpressionStatement"
-                ) || rhsNode &&
-                isInside(id, rhsNode) &&
-                !isInsideOfStorableFunction(id, rhsNode)))
+                    rhsNode &&
+                    isInside(id, rhsNode) &&
+                    !isInsideOfStorableFunction(id, rhsNode)
+                )
             );
         }
 
@@ -619,10 +654,18 @@ module.exports = {
 
                     // Report the first declaration.
                     if (unusedVar.defs.length > 0) {
+
+                        // report last write reference, https://github.com/eslint/eslint/issues/14324
+                        const writeReferences = unusedVar.references.filter(ref => ref.isWrite() && ref.from.variableScope === unusedVar.scope.variableScope);
+
+                        let referenceToReport;
+
+                        if (writeReferences.length > 0) {
+                            referenceToReport = writeReferences[writeReferences.length - 1];
+                        }
+
                         context.report({
-                            node: unusedVar.references.length ? unusedVar.references[
-                                unusedVar.references.length - 1
-                            ].identifier : unusedVar.identifiers[0],
+                            node: referenceToReport ? referenceToReport.identifier : unusedVar.identifiers[0],
                             messageId: "unusedVar",
                             data: unusedVar.references.some(ref => ref.isWrite())
                                 ? getAssignedMessageData(unusedVar)