eslint 10.4.1 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/rules/array-callback-return.js +1 -15
- package/lib/rules/consistent-return.js +2 -16
- package/lib/rules/getter-return.js +1 -15
- package/lib/rules/max-depth.js +21 -2
- package/lib/rules/max-lines-per-function.js +1 -0
- package/lib/rules/max-nested-callbacks.js +19 -3
- package/lib/rules/max-statements.js +1 -0
- package/lib/rules/no-fallthrough.js +1 -15
- package/lib/rules/no-unreachable-loop.js +2 -15
- package/lib/rules/no-unreachable.js +7 -16
- package/lib/rules/no-useless-return.js +1 -15
- package/lib/rules/no-with.js +7 -1
- package/lib/rules/utils/code-path-utils.js +22 -0
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
|
|
|
45
45
|
|
|
46
46
|
### Prerequisites
|
|
47
47
|
|
|
48
|
-
To use ESLint, you must have [Node.js](https://nodejs.org/) (`^20.19.0`, `^22.13.0`, or `>=24`) installed and built with SSL support. (If you are using an official Node.js distribution, SSL
|
|
48
|
+
To use ESLint, you must have [Node.js](https://nodejs.org/) (`^20.19.0`, `^22.13.0`, or `>=24`) installed and built with SSL and ICU support. (If you are using an official Node.js distribution, both SSL and ICU are always built in.)
|
|
49
49
|
|
|
50
50
|
If you use ESLint's TypeScript type definitions, TypeScript 5.3 or later is required.
|
|
51
51
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
//------------------------------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
const astUtils = require("./utils/ast-utils");
|
|
13
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
13
14
|
|
|
14
15
|
//------------------------------------------------------------------------------
|
|
15
16
|
// Helpers
|
|
@@ -30,21 +31,6 @@ function isTargetMethod(node) {
|
|
|
30
31
|
return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
/**
|
|
34
|
-
* Checks all segments in a set and returns true if any are reachable.
|
|
35
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
36
|
-
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
37
|
-
*/
|
|
38
|
-
function isAnySegmentReachable(segments) {
|
|
39
|
-
for (const segment of segments) {
|
|
40
|
-
if (segment.reachable) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
34
|
/**
|
|
49
35
|
* Returns a human-legible description of an array method
|
|
50
36
|
* @param {string} arrayMethodName A method name to fully qualify
|
|
@@ -10,26 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
const astUtils = require("./utils/ast-utils");
|
|
12
12
|
const { upperCaseFirst } = require("../shared/string-utils");
|
|
13
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
13
14
|
|
|
14
15
|
//------------------------------------------------------------------------------
|
|
15
16
|
// Helpers
|
|
16
17
|
//------------------------------------------------------------------------------
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
-
* Checks all segments in a set and returns true if all are unreachable.
|
|
20
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
21
|
-
* @returns {boolean} True if all segments are unreachable; false otherwise.
|
|
22
|
-
*/
|
|
23
|
-
function areAllSegmentsUnreachable(segments) {
|
|
24
|
-
for (const segment of segments) {
|
|
25
|
-
if (segment.reachable) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
19
|
/**
|
|
34
20
|
* Checks whether a given node is a `constructor` method in an ES6 class
|
|
35
21
|
* @param {ASTNode} node A node to check
|
|
@@ -100,7 +86,7 @@ module.exports = {
|
|
|
100
86
|
*/
|
|
101
87
|
if (
|
|
102
88
|
!funcInfo.hasReturnValue ||
|
|
103
|
-
|
|
89
|
+
!isAnySegmentReachable(funcInfo.currentSegments) ||
|
|
104
90
|
astUtils.isES5Constructor(node) ||
|
|
105
91
|
isClassConstructor(node)
|
|
106
92
|
) {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
//------------------------------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
const astUtils = require("./utils/ast-utils");
|
|
13
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
13
14
|
|
|
14
15
|
//------------------------------------------------------------------------------
|
|
15
16
|
// Helpers
|
|
@@ -17,21 +18,6 @@ const astUtils = require("./utils/ast-utils");
|
|
|
17
18
|
|
|
18
19
|
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
|
|
19
20
|
|
|
20
|
-
/**
|
|
21
|
-
* Checks all segments in a set and returns true if any are reachable.
|
|
22
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
23
|
-
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
24
|
-
*/
|
|
25
|
-
function isAnySegmentReachable(segments) {
|
|
26
|
-
for (const segment of segments) {
|
|
27
|
-
if (segment.reachable) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
21
|
//------------------------------------------------------------------------------
|
|
36
22
|
// Rule Definition
|
|
37
23
|
//------------------------------------------------------------------------------
|
package/lib/rules/max-depth.js
CHANGED
|
@@ -54,6 +54,8 @@ module.exports = {
|
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
create(context) {
|
|
57
|
+
const sourceCode = context.sourceCode;
|
|
58
|
+
|
|
57
59
|
//--------------------------------------------------------------------------
|
|
58
60
|
// Helpers
|
|
59
61
|
//--------------------------------------------------------------------------
|
|
@@ -102,6 +104,7 @@ module.exports = {
|
|
|
102
104
|
if (len > maxDepth) {
|
|
103
105
|
context.report({
|
|
104
106
|
node,
|
|
107
|
+
loc: sourceCode.getFirstToken(node).loc,
|
|
105
108
|
messageId: "tooDeeply",
|
|
106
109
|
data: { depth: len, maxDepth },
|
|
107
110
|
});
|
|
@@ -117,6 +120,18 @@ module.exports = {
|
|
|
117
120
|
functionStack[functionStack.length - 1]--;
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Checks whether a node is an else-if statement.
|
|
125
|
+
* @param {ASTNode} node node to evaluate
|
|
126
|
+
* @returns {boolean} Whether the node is an else-if statement
|
|
127
|
+
*/
|
|
128
|
+
function isElseIf(node) {
|
|
129
|
+
return (
|
|
130
|
+
node.parent.type === "IfStatement" &&
|
|
131
|
+
node.parent.alternate === node
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
120
135
|
//--------------------------------------------------------------------------
|
|
121
136
|
// Public API
|
|
122
137
|
//--------------------------------------------------------------------------
|
|
@@ -129,7 +144,7 @@ module.exports = {
|
|
|
129
144
|
StaticBlock: startFunction,
|
|
130
145
|
|
|
131
146
|
IfStatement(node) {
|
|
132
|
-
if (node
|
|
147
|
+
if (!isElseIf(node)) {
|
|
133
148
|
pushBlock(node);
|
|
134
149
|
}
|
|
135
150
|
},
|
|
@@ -142,7 +157,11 @@ module.exports = {
|
|
|
142
157
|
ForInStatement: pushBlock,
|
|
143
158
|
ForOfStatement: pushBlock,
|
|
144
159
|
|
|
145
|
-
"IfStatement:exit"
|
|
160
|
+
"IfStatement:exit"(node) {
|
|
161
|
+
if (!isElseIf(node)) {
|
|
162
|
+
popBlock();
|
|
163
|
+
}
|
|
164
|
+
},
|
|
146
165
|
"SwitchStatement:exit": popBlock,
|
|
147
166
|
"TryStatement:exit": popBlock,
|
|
148
167
|
"DoWhileStatement:exit": popBlock,
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const astUtils = require("./utils/ast-utils");
|
|
13
|
+
|
|
8
14
|
//------------------------------------------------------------------------------
|
|
9
15
|
// Rule Definition
|
|
10
16
|
//------------------------------------------------------------------------------
|
|
@@ -53,6 +59,8 @@ module.exports = {
|
|
|
53
59
|
},
|
|
54
60
|
|
|
55
61
|
create(context) {
|
|
62
|
+
const sourceCode = context.sourceCode;
|
|
63
|
+
|
|
56
64
|
//--------------------------------------------------------------------------
|
|
57
65
|
// Constants
|
|
58
66
|
//--------------------------------------------------------------------------
|
|
@@ -90,17 +98,25 @@ module.exports = {
|
|
|
90
98
|
if (callbackStack.length > THRESHOLD) {
|
|
91
99
|
const opts = { num: callbackStack.length, max: THRESHOLD };
|
|
92
100
|
|
|
93
|
-
context.report({
|
|
101
|
+
context.report({
|
|
102
|
+
node,
|
|
103
|
+
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
|
104
|
+
messageId: "exceed",
|
|
105
|
+
data: opts,
|
|
106
|
+
});
|
|
94
107
|
}
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
/**
|
|
98
111
|
* Pops the call stack.
|
|
112
|
+
* @param {ASTNode} node The node to check.
|
|
99
113
|
* @returns {void}
|
|
100
114
|
* @private
|
|
101
115
|
*/
|
|
102
|
-
function popStack() {
|
|
103
|
-
callbackStack.
|
|
116
|
+
function popStack(node) {
|
|
117
|
+
if (callbackStack.at(-1) === node) {
|
|
118
|
+
callbackStack.pop();
|
|
119
|
+
}
|
|
104
120
|
}
|
|
105
121
|
|
|
106
122
|
//--------------------------------------------------------------------------
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
//------------------------------------------------------------------------------
|
|
10
10
|
|
|
11
11
|
const { directivesPattern } = require("../shared/directives");
|
|
12
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
12
13
|
|
|
13
14
|
//------------------------------------------------------------------------------
|
|
14
15
|
// Helpers
|
|
@@ -16,21 +17,6 @@ const { directivesPattern } = require("../shared/directives");
|
|
|
16
17
|
|
|
17
18
|
const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu;
|
|
18
19
|
|
|
19
|
-
/**
|
|
20
|
-
* Checks all segments in a set and returns true if any are reachable.
|
|
21
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
22
|
-
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
23
|
-
*/
|
|
24
|
-
function isAnySegmentReachable(segments) {
|
|
25
|
-
for (const segment of segments) {
|
|
26
|
-
if (segment.reachable) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
20
|
/**
|
|
35
21
|
* Checks whether or not a given comment string is really a fallthrough comment and not an ESLint directive.
|
|
36
22
|
* @param {string} comment The comment string to check.
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
9
|
+
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
// Helpers
|
|
10
12
|
//------------------------------------------------------------------------------
|
|
@@ -17,21 +19,6 @@ const allLoopTypes = [
|
|
|
17
19
|
"ForOfStatement",
|
|
18
20
|
];
|
|
19
21
|
|
|
20
|
-
/**
|
|
21
|
-
* Checks all segments in a set and returns true if any are reachable.
|
|
22
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
23
|
-
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
24
|
-
*/
|
|
25
|
-
function isAnySegmentReachable(segments) {
|
|
26
|
-
for (const segment of segments) {
|
|
27
|
-
if (segment.reachable) {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
22
|
/**
|
|
36
23
|
* Determines whether the given node is the first node in the code path to which a loop statement
|
|
37
24
|
* 'loops' for the next iteration.
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
"use strict";
|
|
6
6
|
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
12
|
+
|
|
7
13
|
//------------------------------------------------------------------------------
|
|
8
14
|
// Helpers
|
|
9
15
|
//------------------------------------------------------------------------------
|
|
@@ -23,21 +29,6 @@ function isInitialized(node) {
|
|
|
23
29
|
return Boolean(node.init);
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
/**
|
|
27
|
-
* Checks all segments in a set and returns true if all are unreachable.
|
|
28
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
29
|
-
* @returns {boolean} True if all segments are unreachable; false otherwise.
|
|
30
|
-
*/
|
|
31
|
-
function areAllSegmentsUnreachable(segments) {
|
|
32
|
-
for (const segment of segments) {
|
|
33
|
-
if (segment.reachable) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
32
|
/**
|
|
42
33
|
* The class to distinguish consecutive unreachable statements.
|
|
43
34
|
*/
|
|
@@ -154,7 +145,7 @@ module.exports = {
|
|
|
154
145
|
if (
|
|
155
146
|
node &&
|
|
156
147
|
(node.type === "PropertyDefinition" ||
|
|
157
|
-
|
|
148
|
+
!isAnySegmentReachable(currentCodePathSegments))
|
|
158
149
|
) {
|
|
159
150
|
// Store this statement to distinguish consecutive statements.
|
|
160
151
|
if (range.isEmpty) {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const astUtils = require("./utils/ast-utils"),
|
|
12
12
|
FixTracker = require("./utils/fix-tracker");
|
|
13
|
+
const { isAnySegmentReachable } = require("./utils/code-path-utils");
|
|
13
14
|
|
|
14
15
|
//------------------------------------------------------------------------------
|
|
15
16
|
// Helpers
|
|
@@ -60,21 +61,6 @@ function isInFinally(node) {
|
|
|
60
61
|
return false;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
/**
|
|
64
|
-
* Checks all segments in a set and returns true if any are reachable.
|
|
65
|
-
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
66
|
-
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
67
|
-
*/
|
|
68
|
-
function isAnySegmentReachable(segments) {
|
|
69
|
-
for (const segment of segments) {
|
|
70
|
-
if (segment.reachable) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
64
|
//------------------------------------------------------------------------------
|
|
79
65
|
// Rule Definition
|
|
80
66
|
//------------------------------------------------------------------------------
|
package/lib/rules/no-with.js
CHANGED
|
@@ -28,9 +28,15 @@ module.exports = {
|
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
create(context) {
|
|
31
|
+
const sourceCode = context.sourceCode;
|
|
32
|
+
|
|
31
33
|
return {
|
|
32
34
|
WithStatement(node) {
|
|
33
|
-
context.report({
|
|
35
|
+
context.report({
|
|
36
|
+
node,
|
|
37
|
+
loc: sourceCode.getFirstToken(node).loc,
|
|
38
|
+
messageId: "unexpectedWith",
|
|
39
|
+
});
|
|
34
40
|
},
|
|
35
41
|
};
|
|
36
42
|
},
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Code path related utilities.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checks all segments in a set and returns true if any are reachable.
|
|
9
|
+
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
10
|
+
* @returns {boolean} `true` if any segment is reachable; `false` otherwise.
|
|
11
|
+
*/
|
|
12
|
+
function isAnySegmentReachable(segments) {
|
|
13
|
+
for (const segment of segments) {
|
|
14
|
+
if (segment.reachable) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = { isAnySegmentReachable };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -78,8 +78,15 @@
|
|
|
78
78
|
"test:fuzz": "node Makefile.js fuzz",
|
|
79
79
|
"test:performance": "node Makefile.js perf",
|
|
80
80
|
"test:pnpm": "cd tests/pnpm && node check.js && pnpm install && pnpm exec tsc",
|
|
81
|
-
"test:types": "tsc -p tests/lib/types/tsconfig.json"
|
|
81
|
+
"test:types": "tsc -p tests/lib/types/tsconfig.json && npm run test:types --workspaces --if-present",
|
|
82
|
+
"test:types:5.3": "npx -p typescript@5.3 -y -- tsc -p tsconfig.types-legacy.json",
|
|
83
|
+
"test:types:5.x": "npx -p typescript@5.x -y -- tsc -p tsconfig.types.json",
|
|
84
|
+
"test:types:7.x": "npx -p @typescript/native-preview@latest -y -- tsgo -p tsconfig.types.json",
|
|
85
|
+
"test:types:all": "npm run test:types && npm run test:types:5.3 && npm run test:types:5.x && npm run test:types:7.x"
|
|
82
86
|
},
|
|
87
|
+
"workspaces": [
|
|
88
|
+
"packages/*"
|
|
89
|
+
],
|
|
83
90
|
"gitHooks": {
|
|
84
91
|
"pre-commit": "lint-staged"
|
|
85
92
|
},
|
|
@@ -151,12 +158,12 @@
|
|
|
151
158
|
"optionator": "^0.9.3"
|
|
152
159
|
},
|
|
153
160
|
"devDependencies": {
|
|
154
|
-
"@arethetypeswrong/cli": "^0.18.
|
|
161
|
+
"@arethetypeswrong/cli": "^0.18.3",
|
|
155
162
|
"@babel/core": "^7.4.3",
|
|
156
163
|
"@babel/preset-env": "^7.4.3",
|
|
157
164
|
"@cypress/webpack-preprocessor": "^6.0.2",
|
|
158
165
|
"@eslint/eslintrc": "^3.3.5",
|
|
159
|
-
"@eslint/json": "^
|
|
166
|
+
"@eslint/json": "^2.0.0",
|
|
160
167
|
"@types/esquery": "^1.5.4",
|
|
161
168
|
"@types/node": "^22.13.14",
|
|
162
169
|
"@typescript-eslint/parser": "^8.58.2",
|
|
@@ -228,10 +235,5 @@
|
|
|
228
235
|
"license": "MIT",
|
|
229
236
|
"engines": {
|
|
230
237
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
|
231
|
-
},
|
|
232
|
-
"overrides": {
|
|
233
|
-
"@arethetypeswrong/core": {
|
|
234
|
-
"fflate": "0.8.2"
|
|
235
|
-
}
|
|
236
238
|
}
|
|
237
239
|
}
|