UNPKG

2.36 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag for-in loops without if statements inside
3 * @author Nicholas C. Zakas
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 type: "suggestion",
15
16 docs: {
17 description: "require `for-in` loops to include an `if` statement",
18 category: "Best Practices",
19 recommended: false,
20 url: "https://eslint.org/docs/rules/guard-for-in"
21 },
22
23 schema: [],
24 messages: {
25 wrap: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype."
26 }
27 },
28
29 create(context) {
30
31 return {
32
33 ForInStatement(node) {
34 const body = node.body;
35
36 // empty statement
37 if (body.type === "EmptyStatement") {
38 return;
39 }
40
41 // if statement
42 if (body.type === "IfStatement") {
43 return;
44 }
45
46 // empty block
47 if (body.type === "BlockStatement" && body.body.length === 0) {
48 return;
49 }
50
51 // block with just if statement
52 if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") {
53 return;
54 }
55
56 // block that starts with if statement
57 if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") {
58 const i = body.body[0];
59
60 // ... whose consequent is a continue
61 if (i.consequent.type === "ContinueStatement") {
62 return;
63 }
64
65 // ... whose consequent is a block that contains only a continue
66 if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") {
67 return;
68 }
69 }
70
71 context.report({ node, messageId: "wrap" });
72 }
73 };
74
75 }
76};