Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update: no-use-before-define false negative on for-in/of (fixes #6699
…) (#6719)
  • Loading branch information
mysticatea authored and nzakas committed Jul 22, 2016
1 parent a2090cb commit 5320a6c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
14 changes: 14 additions & 0 deletions lib/rules/no-use-before-define.js
Expand Up @@ -10,6 +10,7 @@
//------------------------------------------------------------------------------

var SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/;
var FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/;

/**
* Parses a given value as options.
Expand Down Expand Up @@ -87,6 +88,14 @@ function isInRange(node, location) {
/**
* Checks whether or not a given reference is inside of the initializers of a given variable.
*
* This returns `true` in the following cases:
*
* var a = a
* var [a = a] = list
* var {a = a} = obj
* for (var a in a) {}
* for (var a of a) {}
*
* @param {Variable} variable - A variable to check.
* @param {Reference} reference - A reference to check.
* @returns {boolean} `true` if the reference is inside of the initializers.
Expand All @@ -104,6 +113,11 @@ function isInInitializer(variable, reference) {
if (isInRange(node.init, location)) {
return true;
}
if (FOR_IN_OF_TYPE.test(node.parent.parent.type) &&
isInRange(node.parent.parent.right, location)
) {
return true;
}
break;
} else if (node.type === "AssignmentPattern") {
if (isInRange(node.right, location)) {
Expand Down
6 changes: 5 additions & 1 deletion tests/lib/rules/no-use-before-define.js
Expand Up @@ -33,6 +33,8 @@ ruleTester.run("no-use-before-define", rule, {
{ code: "var [a = 0, b = a] = {};", parserOptions: { ecmaVersion: 6 } },
"function foo() { foo(); }",
"var foo = function() { foo(); };",
{ code: "var a; for (a in a) {}" },
{ code: "var a; for (a of a) {}", parserOptions: { ecmaVersion: 6 } },

// Block-level bindings
{ code: "\"use strict\"; a(); { function a() {} }", parserOptions: { ecmaVersion: 6 } },
Expand Down Expand Up @@ -87,6 +89,8 @@ ruleTester.run("no-use-before-define", rule, {
{ code: "var {b = a, a} = {};", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
{ code: "var [b = a, a] = {};", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
{ code: "var {a = 0} = a;", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
{ code: "var [a = 0] = a;", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] }
{ code: "var [a = 0] = a;", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
{ code: "for (var a in a) {}", errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
{ code: "for (var a of a) {}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "'a' was used before it was defined", type: "Identifier"}] },
]
});

0 comments on commit 5320a6c

Please sign in to comment.