Skip to content

Commit

Permalink
Update: no-unused-vars Improve message to include the allowed patterns (
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSavior authored and not-an-aardvark committed Aug 31, 2017
1 parent 8fbaf0a commit 2db356b
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 17 deletions.
51 changes: 47 additions & 4 deletions lib/rules/no-unused-vars.js
Expand Up @@ -64,8 +64,6 @@ module.exports = {
create(context) {
const sourceCode = context.getSourceCode();

const DEFINED_MESSAGE = "'{{name}}' is defined but never used.";
const ASSIGNED_MESSAGE = "'{{name}}' is assigned a value but never used.";
const REST_PROPERTY_TYPE = /^(?:Experimental)?RestProperty$/;

const config = {
Expand Down Expand Up @@ -100,6 +98,49 @@ module.exports = {
}
}

/**
* Generate the warning message about the variable being
* defined and unused, including the ignore pattern if configured.
* @param {Variable} unusedVar - eslint-scope variable object.
* @returns {string} The warning message to be used with this unused variable.
*/
function getDefinedMessage(unusedVar) {
let type;
let pattern;

if (config.varsIgnorePattern) {
type = "vars";
pattern = config.varsIgnorePattern.toString();
}

if (unusedVar.defs && unusedVar.defs[0] && unusedVar.defs[0].type) {
const defType = unusedVar.defs[0].type;

if (defType === "CatchClause" && config.caughtErrorsIgnorePattern) {
type = "args";
pattern = config.caughtErrorsIgnorePattern.toString();
} else if (defType === "Parameter" && config.argsIgnorePattern) {
type = "args";
pattern = config.argsIgnorePattern.toString();
}
}

const additional = type ? ` Allowed unused ${type} must match ${pattern}.` : "";

return `'{{name}}' is defined but never used.${additional}`;
}

/**
* Generate the warning message about the variable being
* assigned and unused, including the ignore pattern if configured.
* @returns {string} The warning message to be used with this unused variable.
*/
function getAssignedMessage() {
const additional = config.varsIgnorePattern ? ` Allowed unused vars must match ${config.varsIgnorePattern.toString()}.` : "";

return `'{{name}}' is assigned a value but never used.${additional}`;
}

//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
Expand Down Expand Up @@ -586,13 +627,15 @@ module.exports = {
context.report({
node: programNode,
loc: getLocation(unusedVar),
message: DEFINED_MESSAGE,
message: getDefinedMessage(unusedVar),
data: unusedVar
});
} else if (unusedVar.defs.length > 0) {
context.report({
node: unusedVar.identifiers[0],
message: unusedVar.references.some(ref => ref.isWrite()) ? ASSIGNED_MESSAGE : DEFINED_MESSAGE,
message: unusedVar.references.some(ref => ref.isWrite())
? getAssignedMessage()
: getDefinedMessage(unusedVar),
data: unusedVar
});
}
Expand Down
52 changes: 39 additions & 13 deletions tests/lib/rules/no-unused-vars.js
Expand Up @@ -326,11 +326,37 @@ ruleTester.run("no-unused-vars", rule, {
{ code: "/*exported x*/ var { x, y } = z", parserOptions: { ecmaVersion: 6 }, errors: [assignedError("y")] },

// ignore pattern
{ code: "var _a; var b;", options: [{ vars: "all", varsIgnorePattern: "^_" }], errors: [{ message: "'b' is defined but never used.", line: 1, column: 13 }] },
{ code: "var a; function foo() { var _b; var c_; } foo();", options: [{ vars: "local", varsIgnorePattern: "^_" }], errors: [{ message: "'c_' is defined but never used.", line: 1, column: 37 }] },
{ code: "function foo(a, _b) { } foo();", options: [{ args: "all", argsIgnorePattern: "^_" }], errors: [{ message: "'a' is defined but never used.", line: 1, column: 14 }] },
{ code: "function foo(a, _b, c) { return a; } foo();", options: [{ args: "after-used", argsIgnorePattern: "^_" }], errors: [{ message: "'c' is defined but never used.", line: 1, column: 21 }] },
{ code: "var [ firstItemIgnored, secondItem ] = items;", options: [{ vars: "all", varsIgnorePattern: "[iI]gnored" }], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'secondItem' is assigned a value but never used.", line: 1, column: 25 }] },
{
code: "var _a; var b;",
options: [{ vars: "all", varsIgnorePattern: "^_" }],
errors: [{ message: "'b' is defined but never used. Allowed unused vars must match /^_/.", line: 1, column: 13 }]
},
{
code: "var a; function foo() { var _b; var c_; } foo();",
options: [{ vars: "local", varsIgnorePattern: "^_" }],
errors: [{ message: "'c_' is defined but never used. Allowed unused vars must match /^_/.", line: 1, column: 37 }]
},
{
code: "function foo(a, _b) { } foo();",
options: [{ args: "all", argsIgnorePattern: "^_" }],
errors: [{ message: "'a' is defined but never used. Allowed unused args must match /^_/.", line: 1, column: 14 }]
},
{
code: "function foo(a, _b, c) { return a; } foo();",
options: [{ args: "after-used", argsIgnorePattern: "^_" }],
errors: [{ message: "'c' is defined but never used. Allowed unused args must match /^_/.", line: 1, column: 21 }]
},
{
code: "function foo(_a) { } foo();",
options: [{ args: "all", argsIgnorePattern: "[iI]gnored" }],
errors: [{ message: "'_a' is defined but never used. Allowed unused args must match /[iI]gnored/.", line: 1, column: 14 }]
},
{
code: "var [ firstItemIgnored, secondItem ] = items;",
options: [{ vars: "all", varsIgnorePattern: "[iI]gnored" }],
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "'secondItem' is assigned a value but never used. Allowed unused vars must match /[iI]gnored/.", line: 1, column: 25 }]
},

// for-in loops (see #2342)
{ code: "(function(obj) { var name; for ( name in obj ) { i(); return; } })({});", errors: [{ message: "'name' is assigned a value but never used.", line: 1, column: 22 }] },
Expand Down Expand Up @@ -491,23 +517,23 @@ ruleTester.run("no-unused-vars", rule, {
{
code: "try{}catch(err){};",
options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
errors: [{ message: "'err' is defined but never used." }]
errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }]
},

// multiple try catch with one success
{
code: "try{}catch(ignoreErr){}try{}catch(err){};",
options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
errors: [{ message: "'err' is defined but never used." }]
errors: [{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }]
},

// multiple try catch both fail
{
code: "try{}catch(error){}try{}catch(err){};",
options: [{ caughtErrors: "all", caughtErrorsIgnorePattern: "^ignore" }],
errors: [
{ message: "'error' is defined but never used." },
{ message: "'err' is defined but never used." }
{ message: "'error' is defined but never used. Allowed unused args must match /^ignore/." },
{ message: "'err' is defined but never used. Allowed unused args must match /^ignore/." }
]
},

Expand Down Expand Up @@ -578,25 +604,25 @@ ruleTester.run("no-unused-vars", rule, {
{
code: "(function(a, b, c) {})",
options: [{ argsIgnorePattern: "c" }],
errors: [{ message: "'b' is defined but never used." }]
errors: [{ message: "'b' is defined but never used. Allowed unused args must match /c/." }]
},
{
code: "(function(a, b, {c, d}) {})",
options: [{ argsIgnorePattern: "[cd]" }],
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "'b' is defined but never used." }]
errors: [{ message: "'b' is defined but never used. Allowed unused args must match /[cd]/." }]
},
{
code: "(function(a, b, {c, d}) {})",
options: [{ argsIgnorePattern: "c" }],
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "'d' is defined but never used." }]
errors: [{ message: "'d' is defined but never used. Allowed unused args must match /c/." }]
},
{
code: "(function(a, b, {c, d}) {})",
options: [{ argsIgnorePattern: "d" }],
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "'c' is defined but never used." }]
errors: [{ message: "'c' is defined but never used. Allowed unused args must match /d/." }]
},
{
code: "/*global\rfoo*/",
Expand Down

0 comments on commit 2db356b

Please sign in to comment.