codtracker-js/node_modules/eslint/lib/rules/max-statements-per-line.js
2025-04-19 23:12:19 -04:00

223 lines
7.1 KiB
JavaScript

/**
* @fileoverview Specify the maximum number of statements allowed per line.
* @author Kenneth Williams
* @deprecated in ESLint v8.53.0
*/
'use strict';
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require('./utils/ast-utils');
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
deprecated: {
message: 'Formatting rules are being moved out of ESLint core.',
url: 'https://eslint.org/blog/2023/10/deprecating-formatting-rules/',
deprecatedSince: '8.53.0',
availableUntil: '10.0.0',
replacedBy: [
{
message:
'ESLint Stylistic now maintains deprecated stylistic core rules.',
url: 'https://eslint.style/guide/migration',
plugin: {
name: '@stylistic/eslint-plugin-js',
url: 'https://eslint.style/packages/js',
},
rule: {
name: 'max-statements-per-line',
url: 'https://eslint.style/rules/js/max-statements-per-line',
},
},
],
},
type: 'layout',
docs: {
description: 'Enforce a maximum number of statements allowed per line',
recommended: false,
url: 'https://eslint.org/docs/latest/rules/max-statements-per-line',
},
schema: [
{
type: 'object',
properties: {
max: {
type: 'integer',
minimum: 1,
default: 1,
},
},
additionalProperties: false,
},
],
messages: {
exceed:
'This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}.',
},
},
create(context) {
const sourceCode = context.sourceCode,
options = context.options[0] || {},
maxStatementsPerLine =
typeof options.max !== 'undefined' ? options.max : 1;
let lastStatementLine = 0,
numberOfStatementsOnThisLine = 0,
firstExtraStatement;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
const SINGLE_CHILD_ALLOWED =
/^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u;
/**
* Reports with the first extra statement, and clears it.
* @returns {void}
*/
function reportFirstExtraStatementAndClear() {
if (firstExtraStatement) {
context.report({
node: firstExtraStatement,
messageId: 'exceed',
data: {
numberOfStatementsOnThisLine,
maxStatementsPerLine,
statements:
numberOfStatementsOnThisLine === 1 ? 'statement' : 'statements',
},
});
}
firstExtraStatement = null;
}
/**
* Gets the actual last token of a given node.
* @param {ASTNode} node A node to get. This is a node except EmptyStatement.
* @returns {Token} The actual last token.
*/
function getActualLastToken(node) {
return sourceCode.getLastToken(node, astUtils.isNotSemicolonToken);
}
/**
* Addresses a given node.
* It updates the state of this rule, then reports the node if the node violated this rule.
* @param {ASTNode} node A node to check.
* @returns {void}
*/
function enterStatement(node) {
const line = node.loc.start.line;
/*
* Skip to allow non-block statements if this is direct child of control statements.
* `if (a) foo();` is counted as 1.
* But `if (a) foo(); else foo();` should be counted as 2.
*/
if (
SINGLE_CHILD_ALLOWED.test(node.parent.type) &&
node.parent.alternate !== node
) {
return;
}
// Update state.
if (line === lastStatementLine) {
numberOfStatementsOnThisLine += 1;
} else {
reportFirstExtraStatementAndClear();
numberOfStatementsOnThisLine = 1;
lastStatementLine = line;
}
// Reports if the node violated this rule.
if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) {
firstExtraStatement = firstExtraStatement || node;
}
}
/**
* Updates the state of this rule with the end line of leaving node to check with the next statement.
* @param {ASTNode} node A node to check.
* @returns {void}
*/
function leaveStatement(node) {
const line = getActualLastToken(node).loc.end.line;
// Update state.
if (line !== lastStatementLine) {
reportFirstExtraStatementAndClear();
numberOfStatementsOnThisLine = 1;
lastStatementLine = line;
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
BreakStatement: enterStatement,
ClassDeclaration: enterStatement,
ContinueStatement: enterStatement,
DebuggerStatement: enterStatement,
DoWhileStatement: enterStatement,
ExpressionStatement: enterStatement,
ForInStatement: enterStatement,
ForOfStatement: enterStatement,
ForStatement: enterStatement,
FunctionDeclaration: enterStatement,
IfStatement: enterStatement,
ImportDeclaration: enterStatement,
LabeledStatement: enterStatement,
ReturnStatement: enterStatement,
SwitchStatement: enterStatement,
ThrowStatement: enterStatement,
TryStatement: enterStatement,
VariableDeclaration: enterStatement,
WhileStatement: enterStatement,
WithStatement: enterStatement,
ExportNamedDeclaration: enterStatement,
ExportDefaultDeclaration: enterStatement,
ExportAllDeclaration: enterStatement,
'BreakStatement:exit': leaveStatement,
'ClassDeclaration:exit': leaveStatement,
'ContinueStatement:exit': leaveStatement,
'DebuggerStatement:exit': leaveStatement,
'DoWhileStatement:exit': leaveStatement,
'ExpressionStatement:exit': leaveStatement,
'ForInStatement:exit': leaveStatement,
'ForOfStatement:exit': leaveStatement,
'ForStatement:exit': leaveStatement,
'FunctionDeclaration:exit': leaveStatement,
'IfStatement:exit': leaveStatement,
'ImportDeclaration:exit': leaveStatement,
'LabeledStatement:exit': leaveStatement,
'ReturnStatement:exit': leaveStatement,
'SwitchStatement:exit': leaveStatement,
'ThrowStatement:exit': leaveStatement,
'TryStatement:exit': leaveStatement,
'VariableDeclaration:exit': leaveStatement,
'WhileStatement:exit': leaveStatement,
'WithStatement:exit': leaveStatement,
'ExportNamedDeclaration:exit': leaveStatement,
'ExportDefaultDeclaration:exit': leaveStatement,
'ExportAllDeclaration:exit': leaveStatement,
'Program:exit': reportFirstExtraStatementAndClear,
};
},
};