diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js index 11b1f3722de..2114e6f6aac 100644 --- a/lib/rules/no-unused-vars.js +++ b/lib/rules/no-unused-vars.js @@ -484,12 +484,12 @@ module.exports = { } /** - * Determine if an identifier is used either in for-in loops. + * Determine if an identifier is used either in for-in or for-of loops. * @param {Reference} ref The reference to check. * @returns {boolean} whether reference is used in the for-in loops * @private */ - function isForInRef(ref) { + function isForInOfRef(ref) { let target = ref.identifier.parent; @@ -498,7 +498,7 @@ module.exports = { target = target.parent.parent; } - if (target.type !== "ForInStatement") { + if (target.type !== "ForInStatement" && target.type !== "ForOfStatement") { return false; } @@ -531,7 +531,7 @@ module.exports = { let rhsNode = null; return variable.references.some(ref => { - if (isForInRef(ref)) { + if (isForInOfRef(ref)) { return true; } diff --git a/tests/lib/rules/no-unused-vars.js b/tests/lib/rules/no-unused-vars.js index e7276f6d417..b723a29abcf 100644 --- a/tests/lib/rules/no-unused-vars.js +++ b/tests/lib/rules/no-unused-vars.js @@ -252,6 +252,15 @@ ruleTester.run("no-unused-vars", rule, { { code: "(function(obj) { for ( const name in obj ) { return true } })({})", parserOptions: { ecmaVersion: 6 } }, { code: "(function(obj) { for ( const name in obj ) return true })({})", parserOptions: { ecmaVersion: 6 } }, + // For-of loops + { code: "(function(iter) { let name; for ( name of iter ) return; })({});", parserOptions: { ecmaVersion: 6 } }, + { code: "(function(iter) { let name; for ( name of iter ) { return; } })({});", parserOptions: { ecmaVersion: 6 } }, + { code: "(function(iter) { for ( let name of iter ) { return true } })({})", parserOptions: { ecmaVersion: 6 } }, + { code: "(function(iter) { for ( let name of iter ) return true })({})", parserOptions: { ecmaVersion: 6 } }, + + { code: "(function(iter) { for ( const name of iter ) { return true } })({})", parserOptions: { ecmaVersion: 6 } }, + { code: "(function(iter) { for ( const name of iter ) return true })({})", parserOptions: { ecmaVersion: 6 } }, + // Sequence Expressions (See https://github.com/eslint/eslint/issues/14325) { code: "let x = 0; foo = (0, x++);", parserOptions: { ecmaVersion: 6 } }, { code: "let x = 0; foo = (0, x += 1);", parserOptions: { ecmaVersion: 6 } }, @@ -704,6 +713,50 @@ ruleTester.run("no-unused-vars", rule, { }] }, + // For-of loops + { + code: "(function(iter) { var name; for ( name of iter ) { i(); return; } })({});", + env: { es6: true }, + errors: [{ + line: 1, + column: 35, + messageId: "unusedVar", + data: { + varName: "name", + action: "assigned a value", + additional: "" + } + }] + }, + { + code: "(function(iter) { var name; for ( name of iter ) { } })({});", + env: { es6: true }, + errors: [{ + line: 1, + column: 35, + messageId: "unusedVar", + data: { + varName: "name", + action: "assigned a value", + additional: "" + } + }] + }, + { + code: "(function(iter) { for ( var name of iter ) { } })({});", + env: { es6: true }, + errors: [{ + line: 1, + column: 29, + messageId: "unusedVar", + data: { + varName: "name", + action: "assigned a value", + additional: "" + } + }] + }, + // https://github.com/eslint/eslint/issues/3617 { code: "\n/* global foobar, foo, bar */\nfoobar;",