Permalink
Cannot retrieve contributors at this time
150 lines (130 sloc)
4.77 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/eslint/lib/rules/no-constant-condition.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview Rule to flag use constant conditions | |
* @author Christian Schulz <http://rndm.de> | |
*/ | |
"use strict"; | |
const { isConstant } = require("./utils/ast-utils"); | |
//------------------------------------------------------------------------------ | |
// Helpers | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// Rule Definition | |
//------------------------------------------------------------------------------ | |
/** @type {import('../shared/types').Rule} */ | |
module.exports = { | |
meta: { | |
type: "problem", | |
docs: { | |
description: "Disallow constant expressions in conditions", | |
recommended: true, | |
url: "https://eslint.org/docs/latest/rules/no-constant-condition" | |
}, | |
schema: [ | |
{ | |
type: "object", | |
properties: { | |
checkLoops: { | |
type: "boolean", | |
default: true | |
} | |
}, | |
additionalProperties: false | |
} | |
], | |
messages: { | |
unexpected: "Unexpected constant condition." | |
} | |
}, | |
create(context) { | |
const options = context.options[0] || {}, | |
checkLoops = options.checkLoops !== false, | |
loopSetStack = []; | |
const sourceCode = context.sourceCode; | |
let loopsInCurrentScope = new Set(); | |
//-------------------------------------------------------------------------- | |
// Helpers | |
//-------------------------------------------------------------------------- | |
/** | |
* Tracks when the given node contains a constant condition. | |
* @param {ASTNode} node The AST node to check. | |
* @returns {void} | |
* @private | |
*/ | |
function trackConstantConditionLoop(node) { | |
if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) { | |
loopsInCurrentScope.add(node); | |
} | |
} | |
/** | |
* Reports when the set contains the given constant condition node | |
* @param {ASTNode} node The AST node to check. | |
* @returns {void} | |
* @private | |
*/ | |
function checkConstantConditionLoopInSet(node) { | |
if (loopsInCurrentScope.has(node)) { | |
loopsInCurrentScope.delete(node); | |
context.report({ node: node.test, messageId: "unexpected" }); | |
} | |
} | |
/** | |
* Reports when the given node contains a constant condition. | |
* @param {ASTNode} node The AST node to check. | |
* @returns {void} | |
* @private | |
*/ | |
function reportIfConstant(node) { | |
if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) { | |
context.report({ node: node.test, messageId: "unexpected" }); | |
} | |
} | |
/** | |
* Stores current set of constant loops in loopSetStack temporarily | |
* and uses a new set to track constant loops | |
* @returns {void} | |
* @private | |
*/ | |
function enterFunction() { | |
loopSetStack.push(loopsInCurrentScope); | |
loopsInCurrentScope = new Set(); | |
} | |
/** | |
* Reports when the set still contains stored constant conditions | |
* @returns {void} | |
* @private | |
*/ | |
function exitFunction() { | |
loopsInCurrentScope = loopSetStack.pop(); | |
} | |
/** | |
* Checks node when checkLoops option is enabled | |
* @param {ASTNode} node The AST node to check. | |
* @returns {void} | |
* @private | |
*/ | |
function checkLoop(node) { | |
if (checkLoops) { | |
trackConstantConditionLoop(node); | |
} | |
} | |
//-------------------------------------------------------------------------- | |
// Public | |
//-------------------------------------------------------------------------- | |
return { | |
ConditionalExpression: reportIfConstant, | |
IfStatement: reportIfConstant, | |
WhileStatement: checkLoop, | |
"WhileStatement:exit": checkConstantConditionLoopInSet, | |
DoWhileStatement: checkLoop, | |
"DoWhileStatement:exit": checkConstantConditionLoopInSet, | |
ForStatement: checkLoop, | |
"ForStatement > .test": node => checkLoop(node.parent), | |
"ForStatement:exit": checkConstantConditionLoopInSet, | |
FunctionDeclaration: enterFunction, | |
"FunctionDeclaration:exit": exitFunction, | |
FunctionExpression: enterFunction, | |
"FunctionExpression:exit": exitFunction, | |
YieldExpression: () => loopsInCurrentScope.clear() | |
}; | |
} | |
}; |