Skip to content

Commit

Permalink
add more fixes for nested patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
Tanujkanti4441 committed May 18, 2024
1 parent 96db861 commit f9b96e7
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 47 deletions.
116 changes: 69 additions & 47 deletions lib/rules/no-unused-vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,54 @@ module.exports = {
return null;
}

/**
* fix unused variables inside object and array pattern
* @param {ASTNode} node parent node to check
* @returns {Object} fixer object
*/
function fixObjectAndArrayVariable(node) {
if (node.parent.type === "VariableDeclarator") {

// skip variable in for (const [ foo ] of bar);
if (isLoop(node.parent.parent.parent)) {
return null;
}

if (node.parent.parent.declarations.length === 1) {
return fixer.removeRange(node.parent.parent.range);
}

if (getTokenBeforeValue(node.parent) === ",") {
return fixer.removeRange([getBeforeToken(node.parent), node.parent.range[1]]);
}

return fixer.removeRange([node.parent.range[0], getAfterToken(node.parent)]);
}

if (isTypeFunction(node.parent)) {
if (node.parent.params.length === 1) {
return fixer.removeRange(node.range);
}

if (getTokenBeforeValue(node) === "(" && getTokenAfterValue(node) === ",") {
return fixer.removeRange([node.range[0], getAfterToken(node)]);
}

return fixer.removeRange([getBeforeToken(node), node.range[1]]);
}

if (getTokenBeforeValue(node) === ":") {
if (node.parent.parent.type === "ObjectPattern") {

// fixes [{a: k}], [{a: {k}}], [{a: [k]}]
// eslint-disable-next-line no-use-before-define -- due to interdependency of functions
return fixObjectWithValueSeperator(node);
}
}

return null;
}

/**
* fix nested object like { a: { b } }
* @param {ASTNode} node parent node to check
Expand Down Expand Up @@ -1021,6 +1069,18 @@ module.exports = {
}

if (node.parent.elements.length === 1 || hasSingleElement(node.parent)) {

// fixes { a: [{ b }] } or { a: [[ b ]] }
if (getTokenBeforeValue(node.parent) === ":") {
return fixObjectAndArrayVariable(node.parent);
}

// fixes [a, ...[[ b ]]] or [a, ...[{ b }]]
if (node.parent.parent.type === "RestElement") {
// eslint-disable-next-line no-use-before-define -- due to interdependency of functions
return fixRestInPattern(node.parent.parent);
}

return fixVariables(node.parent);
}

Expand All @@ -1035,57 +1095,19 @@ module.exports = {
}

/**
* fix unused variables inside object and array pattern
* fix {a: k}, {a: {k}} or {a: [k]} like cases
* @param {ASTNode} node parent node to check
* @returns {Object} fixer object
*/
function fixObjectAndArrayVariable(node) {
if (node.parent.type === "VariableDeclarator") {

// skip variable in for (const [ foo ] of bar);
if (isLoop(node.parent.parent.parent)) {
return null;
}

if (node.parent.parent.declarations.length === 1) {
return fixer.removeRange(node.parent.parent.range);
}

if (getTokenBeforeValue(node.parent) === ",") {
return fixer.removeRange([getBeforeToken(node.parent), node.parent.range[1]]);
}

return fixer.removeRange([node.parent.range[0], getAfterToken(node.parent)]);
}

if (isTypeFunction(node.parent)) {
if (node.parent.params.length === 1) {
return fixer.removeRange(node.range);
}

if (getTokenBeforeValue(node) === "(" && getTokenAfterValue(node) === ",") {
return fixer.removeRange([node.range[0], getAfterToken(node)]);
}

return fixer.removeRange([getBeforeToken(node), node.range[1]]);
}

if (getTokenBeforeValue(node) === ":") {
if (node.parent.parent.type === "ObjectPattern") {

// fixes [{a: k}], [{a: {k}}], [{a: [k]}]
if (
node.parent.parent.parent.type === "ArrayPattern" &&
node.parent.parent.properties.length === 1
) {
return fixNestedArrayVariable(node.parent.parent);
}

return fixNestedObjectVariable(node);
}
function fixObjectWithValueSeperator(node) {
if (
node.parent.parent.parent.type === "ArrayPattern" &&
node.parent.parent.properties.length === 1
) {
return fixNestedArrayVariable(node.parent.parent);
}

return null;
return fixNestedObjectVariable(node);
}

/**
Expand Down Expand Up @@ -1113,7 +1135,7 @@ module.exports = {
return fixVariables(node.parent);
}

return fixer.removeRange([getBeforeToken(id, 2), tokenAfter.range[1]]);
return fixer.removeRange([getBeforeToken(node), node.range[1]]);
}

return null;
Expand Down
66 changes: 66 additions & 0 deletions tests/lib/rules/no-unused-vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -2060,6 +2060,42 @@ ruleTester.run("no-unused-vars", rule, {
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("a", [{ output: "const [, ...[b]] = array; alert(b);", messageId: "removeVar", data: { varName: "a" } }])]
},
{
code: "const [a, ...[[ b ]]] = array; alert(a);",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "const [a] = array; alert(a);", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "const [a, ...[{ b }]] = array; alert(a);",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "const [a] = array; alert(a);", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "function foo([a, ...[[ b ]]]) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [
definedError("a", [{ output: "function foo([, ...[[ b ]]]) {} foo();", messageId: "removeVar", data: { varName: "a" } }]),
definedError("b", [{ output: "function foo([a]) {} foo();", messageId: "removeVar", data: { varName: "b" } }])
]
},
{
code: "function foo([a, ...[{ b }]]) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [
definedError("a", [{ output: "function foo([, ...[{ b }]]) {} foo();", messageId: "removeVar", data: { varName: "a" } }]),
definedError("b", [{ output: "function foo([a]) {} foo();", messageId: "removeVar", data: { varName: "b" } }])
]
},
{
code: "function foo(...[[ a ]]) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [definedError("a", [{ output: "function foo() {} foo();", messageId: "removeVar", data: { varName: "a" } }])]
},
{
code: "function foo(...[{ a }]) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [definedError("a", [{ output: "function foo() {} foo();", messageId: "removeVar", data: { varName: "a" } }])]
},
{
code: "const [a, [b]] = array; alert(a);",
languageOptions: { ecmaVersion: 2023 },
Expand Down Expand Up @@ -2124,6 +2160,36 @@ ruleTester.run("no-unused-vars", rule, {
code: "const [{ a: { b }, c }] = foo; alert(c);",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "const [{ c }] = foo; alert(c);", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "const { a: [{ b }]} = foo;",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "const { a: [[ b ]]} = foo;",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "const [{ a: [{ b }]}] = foo;",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "const { a: [{ b }], c} = foo; alert(c);",
languageOptions: { ecmaVersion: 2023 },
errors: [assignedError("b", [{ output: "const { c} = foo; alert(c);", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "function foo({ a: [{ b }]}) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [definedError("b", [{ output: "function foo() {} foo();", messageId: "removeVar", data: { varName: "b" } }])]
},
{
code: "function foo({ a: [[ b ]]}) {} foo();",
languageOptions: { ecmaVersion: 2023 },
errors: [definedError("b", [{ output: "function foo() {} foo();", messageId: "removeVar", data: { varName: "b" } }])]
}
]
});

0 comments on commit f9b96e7

Please sign in to comment.