Skip to content

Commit

Permalink
Update: allow continue instead of if wrap in guard-for-in (fixes #7567)…
Browse files Browse the repository at this point in the history
… (#9796)
  • Loading branch information
michaelficarra authored and platinumazure committed Jan 20, 2018
1 parent af043eb commit e26a25f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
42 changes: 35 additions & 7 deletions lib/rules/guard-for-in.js
Expand Up @@ -26,16 +26,44 @@ module.exports = {
return {

ForInStatement(node) {
const body = node.body;

/*
* If the for-in statement has {}, then the real body is the body
* of the BlockStatement. Otherwise, just use body as provided.
*/
const body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body;
// empty statement
if (body.type === "EmptyStatement") {
return;
}

// if statement
if (body.type === "IfStatement") {
return;
}

// empty block
if (body.type === "BlockStatement" && body.body.length === 0) {
return;
}

if (body && body.type !== "IfStatement") {
context.report({ node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." });
// block with just if statement
if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") {
return;
}

// block that starts with if statement
if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") {
const i = body.body[0];

// ... whose consequent is a continue
if (i.consequent.type === "ContinueStatement") {
return;
}

// ... whose consequent is a block that contains only a continue
if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") {
return;
}
}

context.report({ node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." });
}
};

Expand Down
10 changes: 9 additions & 1 deletion tests/lib/rules/guard-for-in.js
Expand Up @@ -20,10 +20,18 @@ const ruleTester = new RuleTester();

ruleTester.run("guard-for-in", rule, {
valid: [
"for (var x in o);",
"for (var x in o) {}",
"for (var x in o) { if (x) {}}"
"for (var x in o) if (x) f();",
"for (var x in o) { if (x) { f(); } }",
"for (var x in o) { if (x) continue; f(); }",
"for (var x in o) { if (x) { continue; } f(); }"
],
invalid: [
{ code: "for (var x in o) { if (x) { f(); continue; } g(); }", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] },
{ code: "for (var x in o) { if (x) { continue; f(); } g(); }", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] },
{ code: "for (var x in o) { if (x) { f(); } g(); }", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] },
{ code: "for (var x in o) { if (x) f(); g(); }", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] },
{ code: "for (var x in o) { foo() }", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] },
{ code: "for (var x in o) foo();", errors: [{ message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", type: "ForInStatement" }] }
]
Expand Down

0 comments on commit e26a25f

Please sign in to comment.