From 5023ff05133a173b9e4413fb4e8d3f76d50611f0 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Mon, 29 Mar 2021 01:29:51 +0900 Subject: [PATCH] Fix: Check assignment reference in no-unused-vars (fixes #14163) --- lib/rules/no-unused-vars.js | 25 +++++++++++++++---------- tests/lib/rules/no-unused-vars.js | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js index 4dc6dc2bab3..90abb053c52 100644 --- a/lib/rules/no-unused-vars.js +++ b/lib/rules/no-unused-vars.js @@ -196,6 +196,17 @@ module.exports = { } + /** + * Checks whether a node is a sibling of the rest property. + * @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 hasRestSiblingDef = variable.defs.some(def => hasRestSibling(def.name.parent)); + const hasRestSiblingRef = variable.references.some(ref => hasRestSibling(ref.identifier.parent)); + + return hasRestSiblingDef || hasRestSiblingRef; } return false; diff --git a/tests/lib/rules/no-unused-vars.js b/tests/lib/rules/no-unused-vars.js index 061ac08d51f..db041d46b89 100644 --- a/tests/lib/rules/no-unused-vars.js +++ b/tests/lib/rules/no-unused-vars.js @@ -291,6 +291,13 @@ ruleTester.run("no-unused-vars", rule, { parserOptions: { ecmaVersion: 2018 } }, + // https://github.com/eslint/eslint/issues/14163 + { + code: "let foo, rest;\n({ foo, ...rest } = something);\nconsole.log(rest);", + options: [{ ignoreRestSiblings: true }], + parserOptions: { ecmaVersion: 2020 } + }, + // https://github.com/eslint/eslint/issues/10952 "/*eslint use-every-a:1*/ !function(b, a) { return 1 }", @@ -588,6 +595,23 @@ ruleTester.run("no-unused-vars", rule, { } ] }, + { + code: "let type, coords;\n({ type, ...coords } = data);\n console.log(type)", + options: [{ ignoreRestSiblings: true }], + parserOptions: { ecmaVersion: 2018 }, + errors: [ + { + line: 2, + column: 13, + messageId: "unusedVar", + data: { + varName: "coords", + action: "assigned a value", + additional: "" + } + } + ] + }, // Unused rest property without ignoreRestSiblings {