UNPKG

3.81 kBJavaScriptView Raw
1/**
2 * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction)
3 * @author Aladdin-ADD<hh_2013@foxmail.com>
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 docs: {
15 description: "enforce \"for\" loop update clause moving the counter in the right direction.",
16 category: "Possible Errors",
17 recommended: false,
18 url: "https://eslint.org/docs/rules/for-direction"
19 },
20 fixable: null,
21 schema: []
22 },
23
24 create(context) {
25
26 /**
27 * report an error.
28 * @param {ASTNode} node the node to report.
29 * @returns {void}
30 */
31 function report(node) {
32 context.report({
33 node,
34 message: "The update clause in this loop moves the variable in the wrong direction."
35 });
36 }
37
38 /**
39 * check UpdateExpression add/sub the counter
40 * @param {ASTNode} update UpdateExpression to check
41 * @param {string} counter variable name to check
42 * @returns {int} if add return 1, if sub return -1, if nochange, return 0
43 */
44 function getUpdateDirection(update, counter) {
45 if (update.argument.type === "Identifier" && update.argument.name === counter) {
46 if (update.operator === "++") {
47 return 1;
48 }
49 if (update.operator === "--") {
50 return -1;
51 }
52 }
53 return 0;
54 }
55
56 /**
57 * check AssignmentExpression add/sub the counter
58 * @param {ASTNode} update AssignmentExpression to check
59 * @param {string} counter variable name to check
60 * @returns {int} if add return 1, if sub return -1, if nochange, return 0
61 */
62 function getAssignmentDirection(update, counter) {
63 if (update.left.name === counter) {
64 if (update.operator === "+=") {
65 return 1;
66 }
67 if (update.operator === "-=") {
68 return -1;
69 }
70 }
71 return 0;
72 }
73 return {
74 ForStatement(node) {
75
76 if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) {
77 const counter = node.test.left.name;
78 const operator = node.test.operator;
79 const update = node.update;
80
81 if (operator === "<" || operator === "<=") {
82
83 // report error if update sub the counter (--, -=)
84 if (update.type === "UpdateExpression" && getUpdateDirection(update, counter) < 0) {
85 report(node);
86 }
87
88 if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) < 0) {
89 report(node);
90 }
91 } else if (operator === ">" || operator === ">=") {
92
93 // report error if update add the counter (++, +=)
94 if (update.type === "UpdateExpression" && getUpdateDirection(update, counter) > 0) {
95 report(node);
96 }
97
98 if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) > 0) {
99 report(node);
100 }
101 }
102 }
103 }
104 };
105 }
106};