Skip to content

Commit

Permalink
Update: fix false negative in no-use-before-define (fixes #10227) (#1…
Browse files Browse the repository at this point in the history
…0396)

* Update: fix false negative in no-use-before-define (fixes #10227)

* reorder tests
  • Loading branch information
mysticatea authored and kaicataldo committed Jun 9, 2018
1 parent 3721841 commit dc4075e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 39 deletions.
43 changes: 4 additions & 39 deletions lib/rules/no-use-before-define.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,49 +219,14 @@ module.exports = {
data: reference.identifier
});
});
}

/**
* Validates variables inside of a node's scope.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function findVariables() {
const scope = context.getScope();

findVariablesInScope(scope);
scope.childScopes.forEach(findVariablesInScope);
}

const ruleDefinition = {
"Program:exit"(node) {
const scope = context.getScope(),
ecmaFeatures = context.parserOptions.ecmaFeatures || {};

findVariablesInScope(scope);

// both Node.js and Modules have an extra scope
if (ecmaFeatures.globalReturn || node.sourceType === "module") {
findVariablesInScope(scope.childScopes[0]);
}
return {
Program() {
findVariablesInScope(context.getScope());
}
};

if (context.parserOptions.ecmaVersion >= 6) {
ruleDefinition["BlockStatement:exit"] =
ruleDefinition["SwitchStatement:exit"] = findVariables;

ruleDefinition["ArrowFunctionExpression:exit"] = function(node) {
if (node.body.type !== "BlockStatement") {
findVariables();
}
};
} else {
ruleDefinition["FunctionExpression:exit"] =
ruleDefinition["FunctionDeclaration:exit"] =
ruleDefinition["ArrowFunctionExpression:exit"] = findVariables;
}

return ruleDefinition;
}
};
49 changes: 49 additions & 0 deletions tests/lib/rules/no-use-before-define.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,55 @@ ruleTester.run("no-use-before-define", rule, {
code: "foo; var foo;",
options: [{ variables: false }],
errors: [{ message: "'foo' was used before it was defined.", type: "Identifier" }]
},

// https://github.com/eslint/eslint/issues/10227
{
code: "for (let x = x;;); let x = 0",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},
{
code: "for (let x in xs); let xs = []",
parserOptions: { ecmaVersion: 2015 },
errors: ["'xs' was used before it was defined."]
},
{
code: "for (let x of xs); let xs = []",
parserOptions: { ecmaVersion: 2015 },
errors: ["'xs' was used before it was defined."]
},
{
code: "try {} catch ({message = x}) {} let x = ''",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},
{
code: "with (obj) x; let x = {}",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},

// WithStatements.
{
code: "with (x); let x = {}",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},
{
code: "with (obj) { x } let x = {}",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},
{
code: "with (obj) { if (a) { x } } let x = {}",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
},
{
code: "with (obj) { (() => { if (a) { x } })() } let x = {}",
parserOptions: { ecmaVersion: 2015 },
errors: ["'x' was used before it was defined."]
}
]
});

0 comments on commit dc4075e

Please sign in to comment.