2 * @fileoverview Rule to flag use constant conditions
3 * @author Christian Schulz <http://rndm.de>
8 const { isConstant
} = require("./utils/ast-utils");
10 //------------------------------------------------------------------------------
12 //------------------------------------------------------------------------------
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 /** @type {import('../shared/types').Rule} */
24 description
: "Disallow constant expressions in conditions",
26 url
: "https://eslint.org/docs/rules/no-constant-condition"
38 additionalProperties
: false
43 unexpected
: "Unexpected constant condition."
48 const options
= context
.options
[0] || {},
49 checkLoops
= options
.checkLoops
!== false,
52 let loopsInCurrentScope
= new Set();
54 //--------------------------------------------------------------------------
56 //--------------------------------------------------------------------------
59 * Tracks when the given node contains a constant condition.
60 * @param {ASTNode} node The AST node to check.
64 function trackConstantConditionLoop(node
) {
65 if (node
.test
&& isConstant(context
.getScope(), node
.test
, true)) {
66 loopsInCurrentScope
.add(node
);
71 * Reports when the set contains the given constant condition node
72 * @param {ASTNode} node The AST node to check.
76 function checkConstantConditionLoopInSet(node
) {
77 if (loopsInCurrentScope
.has(node
)) {
78 loopsInCurrentScope
.delete(node
);
79 context
.report({ node
: node
.test
, messageId
: "unexpected" });
84 * Reports when the given node contains a constant condition.
85 * @param {ASTNode} node The AST node to check.
89 function reportIfConstant(node
) {
90 if (node
.test
&& isConstant(context
.getScope(), node
.test
, true)) {
91 context
.report({ node
: node
.test
, messageId
: "unexpected" });
96 * Stores current set of constant loops in loopSetStack temporarily
97 * and uses a new set to track constant loops
101 function enterFunction() {
102 loopSetStack
.push(loopsInCurrentScope
);
103 loopsInCurrentScope
= new Set();
107 * Reports when the set still contains stored constant conditions
111 function exitFunction() {
112 loopsInCurrentScope
= loopSetStack
.pop();
116 * Checks node when checkLoops option is enabled
117 * @param {ASTNode} node The AST node to check.
121 function checkLoop(node
) {
123 trackConstantConditionLoop(node
);
127 //--------------------------------------------------------------------------
129 //--------------------------------------------------------------------------
132 ConditionalExpression
: reportIfConstant
,
133 IfStatement
: reportIfConstant
,
134 WhileStatement
: checkLoop
,
135 "WhileStatement:exit": checkConstantConditionLoopInSet
,
136 DoWhileStatement
: checkLoop
,
137 "DoWhileStatement:exit": checkConstantConditionLoopInSet
,
138 ForStatement
: checkLoop
,
139 "ForStatement > .test": node
=> checkLoop(node
.parent
),
140 "ForStatement:exit": checkConstantConditionLoopInSet
,
141 FunctionDeclaration
: enterFunction
,
142 "FunctionDeclaration:exit": exitFunction
,
143 FunctionExpression
: enterFunction
,
144 "FunctionExpression:exit": exitFunction
,
145 YieldExpression
: () => loopsInCurrentScope
.clear()