Skip to content

Commit de69cec

Browse files
authored
feat: update no-inner-declarations for class static blocks (#15290)
Updates the `no-inner-declarations` rule to allow declarations at the top level of class static blocks. Refs #15016
1 parent e2fe7ef commit de69cec

File tree

3 files changed

+123
-9
lines changed

3 files changed

+123
-9
lines changed

docs/rules/no-inner-declarations.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function doSomething() {
5656

5757
## Rule Details
5858

59-
This rule requires that function declarations and, optionally, variable declarations be in the root of a program or the body of a function.
59+
This rule requires that function declarations and, optionally, variable declarations be in the root of a program, or in the root of the body of a function, or in the root of the body of a class static block.
6060

6161
## Options
6262

@@ -83,6 +83,14 @@ function doSomethingElse() {
8383
}
8484

8585
if (foo) function f(){}
86+
87+
class C {
88+
static {
89+
if (test) {
90+
function doSomething() { }
91+
}
92+
}
93+
}
8694
```
8795

8896
Examples of **correct** code for this rule with the default `"functions"` option:
@@ -96,6 +104,12 @@ function doSomethingElse() {
96104
function doAnotherThing() { }
97105
}
98106

107+
class C {
108+
static {
109+
function doSomething() { }
110+
}
111+
}
112+
99113
if (test) {
100114
asyncCall(id, function (err, data) { });
101115
}
@@ -125,17 +139,23 @@ function doAnotherThing() {
125139
}
126140
}
127141

128-
129142
if (foo) var a;
130143

131144
if (foo) function f(){}
145+
146+
class C {
147+
static {
148+
if (test) {
149+
var something;
150+
}
151+
}
152+
}
132153
```
133154

134155
Examples of **correct** code for this rule with the `"both"` option:
135156

136157
```js
137158
/*eslint no-inner-declarations: ["error", "both"]*/
138-
/*eslint-env es6*/
139159

140160
var bar = 42;
141161

@@ -146,6 +166,12 @@ if (test) {
146166
function doAnotherThing() {
147167
var baz = 81;
148168
}
169+
170+
class C {
171+
static {
172+
var something;
173+
}
174+
}
149175
```
150176

151177
## When Not To Use It

lib/rules/no-inner-declarations.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,33 @@ const astUtils = require("./utils/ast-utils");
1515
// Rule Definition
1616
//------------------------------------------------------------------------------
1717

18-
const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]);
18+
const validParent = new Set(["Program", "StaticBlock", "ExportNamedDeclaration", "ExportDefaultDeclaration"]);
1919
const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
2020

21+
/**
22+
* Finds the nearest enclosing context where this rule allows declarations and returns its description.
23+
* @param {ASTNode} node Node to search from.
24+
* @returns {string} Description. One of "program", "function body", "class static block body".
25+
*/
26+
function getAllowedBodyDescription(node) {
27+
let { parent } = node;
28+
29+
while (parent) {
30+
31+
if (parent.type === "StaticBlock") {
32+
return "class static block body";
33+
}
34+
35+
if (astUtils.isFunction(parent)) {
36+
return "function body";
37+
}
38+
39+
({ parent } = parent);
40+
}
41+
42+
return "program";
43+
}
44+
2145
module.exports = {
2246
meta: {
2347
type: "problem",
@@ -59,14 +83,12 @@ module.exports = {
5983
return;
6084
}
6185

62-
const upperFunction = astUtils.getUpperFunction(parent);
63-
6486
context.report({
6587
node,
6688
messageId: "moveDeclToRoot",
6789
data: {
6890
type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
69-
body: (upperFunction === null ? "program" : "function body")
91+
body: getAllowedBodyDescription(node)
7092
}
7193
});
7294
}

tests/lib/rules/no-inner-declarations.js

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,27 @@ ruleTester.run("no-inner-declarations", rule, {
7373
{
7474
code: "module.exports = function foo(){}",
7575
options: ["both"]
76+
},
77+
{
78+
code: "class C { method() { function foo() {} } }",
79+
options: ["both"],
80+
parserOptions: { ecmaVersion: 2022 }
81+
},
82+
{
83+
code: "class C { method() { var x; } }",
84+
options: ["both"],
85+
parserOptions: { ecmaVersion: 2022 }
86+
},
87+
{
88+
code: "class C { static { function foo() {} } }",
89+
options: ["both"],
90+
parserOptions: { ecmaVersion: 2022 }
91+
},
92+
{
93+
code: "class C { static { var x; } }",
94+
options: ["both"],
95+
parserOptions: { ecmaVersion: 2022 }
7696
}
77-
7897
],
7998

8099
// Examples of code that should trigger the rule
@@ -271,7 +290,54 @@ ruleTester.run("no-inner-declarations", rule, {
271290
},
272291
type: "VariableDeclaration"
273292
}]
293+
}, {
294+
code: "class C { method() { if(test) { var foo; } } }",
295+
options: ["both"],
296+
parserOptions: { ecmaVersion: 6 },
297+
errors: [{
298+
messageId: "moveDeclToRoot",
299+
data: {
300+
type: "variable",
301+
body: "function body"
302+
},
303+
type: "VariableDeclaration"
304+
}]
305+
}, {
306+
code: "class C { static { if (test) { function foo() {} } } }",
307+
options: ["both"],
308+
parserOptions: { ecmaVersion: 2022 },
309+
errors: [{
310+
messageId: "moveDeclToRoot",
311+
data: {
312+
type: "function",
313+
body: "class static block body"
314+
},
315+
type: "FunctionDeclaration"
316+
}]
317+
}, {
318+
code: "class C { static { if (test) { var foo; } } }",
319+
options: ["both"],
320+
parserOptions: { ecmaVersion: 2022 },
321+
errors: [{
322+
messageId: "moveDeclToRoot",
323+
data: {
324+
type: "variable",
325+
body: "class static block body"
326+
},
327+
type: "VariableDeclaration"
328+
}]
329+
}, {
330+
code: "class C { static { if (test) { if (anotherTest) { var foo; } } } }",
331+
options: ["both"],
332+
parserOptions: { ecmaVersion: 2022 },
333+
errors: [{
334+
messageId: "moveDeclToRoot",
335+
data: {
336+
type: "variable",
337+
body: "class static block body"
338+
},
339+
type: "VariableDeclaration"
340+
}]
274341
}
275-
276342
]
277343
});

0 commit comments

Comments
 (0)