Skip to content

Commit

Permalink
feat: update max-statements for class static blocks (#15315)
Browse files Browse the repository at this point in the history
Updates the `max-statements` rule so that it does not apply to class static blocks and does not count statements in them as statements in the enclosing function.

Refs #15016
  • Loading branch information
mdjermanovic committed Nov 19, 2021
1 parent fd5a0b8 commit df2f1cc
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
24 changes: 24 additions & 0 deletions docs/rules/max-statements.md
Expand Up @@ -112,6 +112,30 @@ let foo = () => {
}
```

Note that this rule does not apply to class static blocks, and that statements in class static blocks do not count as statements in the enclosing function.

Examples of **correct** code for this rule with `{ "max": 2 }` option:

```js
/*eslint max-statements: ["error", 2]*/

function foo() {
let one;
let two = class {
static {
let three;
let four;
let five;
if (six) {
let seven;
let eight;
let nine;
}
}
};
}
```

### ignoreTopLevelFunctions

Examples of additional **correct** code for this rule with the `{ "max": 10 }, { "ignoreTopLevelFunctions": true }` options:
Expand Down
10 changes: 10 additions & 0 deletions lib/rules/max-statements.js
Expand Up @@ -123,6 +123,14 @@ module.exports = {
function endFunction(node) {
const count = functionStack.pop();

/*
* This rule does not apply to class static blocks, but we have to track them so
* that stataments in them do not count as statements in the enclosing function.
*/
if (node.type === "StaticBlock") {
return;
}

if (ignoreTopLevelFunctions && functionStack.length === 0) {
topLevelFunctions.push({ node, count });
} else {
Expand All @@ -148,12 +156,14 @@ module.exports = {
FunctionDeclaration: startFunction,
FunctionExpression: startFunction,
ArrowFunctionExpression: startFunction,
StaticBlock: startFunction,

BlockStatement: countStatements,

"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction,
"StaticBlock:exit": endFunction,

"Program:exit"() {
if (topLevelFunctions.length === 1) {
Expand Down
52 changes: 51 additions & 1 deletion tests/lib/rules/max-statements.js
Expand Up @@ -33,7 +33,33 @@ ruleTester.run("max-statements", rule, {
{ code: "var foo = { thing() { var bar = 1; var baz = 2; } }", options: [2], parserOptions: { ecmaVersion: 6 } },
{ code: "var foo = { ['thing']() { var bar = 1; var baz = 2; } }", options: [2], parserOptions: { ecmaVersion: 6 } },
{ code: "var foo = { thing: () => { var bar = 1; var baz = 2; } }", options: [2], parserOptions: { ecmaVersion: 6 } },
{ code: "var foo = { thing: function() { var bar = 1; var baz = 2; } }", options: [{ max: 2 }] }
{ code: "var foo = { thing: function() { var bar = 1; var baz = 2; } }", options: [{ max: 2 }] },

// this rule does not apply to class static blocks, and statements in them should not count as statements in the enclosing function
{ code: "class C { static { one; two; three; { four; five; six; } } }", options: [2], parserOptions: { ecmaVersion: 2022 } },
{ code: "function foo() { class C { static { one; two; three; { four; five; six; } } } }", options: [2], parserOptions: { ecmaVersion: 2022 } },
{ code: "class C { static { one; two; three; function foo() { 1; 2; } four; five; six; } }", options: [2], parserOptions: { ecmaVersion: 2022 } },
{ code: "class C { static { { one; two; three; function foo() { 1; 2; } four; five; six; } } }", options: [2], parserOptions: { ecmaVersion: 2022 } },
{
code: "function top_level() { 1; /* 2 */ class C { static { one; two; three; { four; five; six; } } } 3;}",
options: [2, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "function top_level() { 1; 2; } class C { static { one; two; three; { four; five; six; } } }",
options: [1, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { one; two; three; { four; five; six; } } } function top_level() { 1; 2; } ",
options: [1, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "function foo() { let one; let two = class { static { let three; let four; let five; if (six) { let seven; let eight; let nine; } } }; }",
options: [2],
parserOptions: { ecmaVersion: 2022 }
}
],
invalid: [
{
Expand Down Expand Up @@ -143,6 +169,30 @@ ruleTester.run("max-statements", rule, {
code: "function foo() { 1; }",
options: [{ max: 0 }],
errors: [{ messageId: "exceed", data: { name: "Function 'foo'", count: 1, max: 0 } }]
},
{
code: "function foo() { foo_1; /* foo_ 2 */ class C { static { one; two; three; four; { five; six; seven; eight; } } } foo_3 }",
options: [2],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "exceed", data: { name: "Function 'foo'", count: 3, max: 2 } }]
},
{
code: "class C { static { one; two; three; four; function not_top_level() { 1; 2; 3; } five; six; seven; eight; } }",
options: [2, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "exceed", data: { name: "Function 'not_top_level'", count: 3, max: 2 } }]
},
{
code: "class C { static { { one; two; three; four; function not_top_level() { 1; 2; 3; } five; six; seven; eight; } } }",
options: [2, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "exceed", data: { name: "Function 'not_top_level'", count: 3, max: 2 } }]
},
{
code: "class C { static { { one; two; three; four; } function not_top_level() { 1; 2; 3; } { five; six; seven; eight; } } }",
options: [2, { ignoreTopLevelFunctions: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "exceed", data: { name: "Function 'not_top_level'", count: 3, max: 2 } }]
}
]
});

0 comments on commit df2f1cc

Please sign in to comment.