eslint 8.47.0 → 8.57.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.
Files changed (118) hide show
  1. package/README.md +18 -13
  2. package/bin/eslint.js +38 -5
  3. package/conf/rule-type-list.json +25 -33
  4. package/lib/api.js +29 -1
  5. package/lib/cli-engine/cli-engine.js +2 -2
  6. package/lib/cli-engine/lint-result-cache.js +18 -6
  7. package/lib/cli.js +36 -6
  8. package/lib/config/flat-config-schema.js +124 -61
  9. package/lib/config/rule-validator.js +2 -1
  10. package/lib/eslint/eslint-helpers.js +9 -11
  11. package/lib/eslint/eslint.js +7 -0
  12. package/lib/eslint/flat-eslint.js +33 -18
  13. package/lib/linter/apply-disable-directives.js +127 -13
  14. package/lib/linter/code-path-analysis/code-path-analyzer.js +32 -24
  15. package/lib/linter/code-path-analysis/code-path-segment.js +52 -24
  16. package/lib/linter/code-path-analysis/code-path-state.js +1108 -243
  17. package/lib/linter/code-path-analysis/code-path.js +128 -33
  18. package/lib/linter/code-path-analysis/fork-context.js +173 -72
  19. package/lib/linter/config-comment-parser.js +36 -2
  20. package/lib/linter/linter.js +183 -82
  21. package/lib/options.js +24 -3
  22. package/lib/rule-tester/flat-rule-tester.js +113 -25
  23. package/lib/rule-tester/rule-tester.js +176 -23
  24. package/lib/rules/array-bracket-newline.js +3 -0
  25. package/lib/rules/array-bracket-spacing.js +3 -0
  26. package/lib/rules/array-callback-return.js +175 -25
  27. package/lib/rules/array-element-newline.js +3 -0
  28. package/lib/rules/arrow-parens.js +3 -0
  29. package/lib/rules/arrow-spacing.js +3 -0
  30. package/lib/rules/block-spacing.js +3 -0
  31. package/lib/rules/brace-style.js +3 -0
  32. package/lib/rules/comma-dangle.js +3 -0
  33. package/lib/rules/comma-spacing.js +3 -0
  34. package/lib/rules/comma-style.js +3 -0
  35. package/lib/rules/computed-property-spacing.js +3 -0
  36. package/lib/rules/consistent-return.js +32 -7
  37. package/lib/rules/constructor-super.js +37 -14
  38. package/lib/rules/dot-location.js +3 -0
  39. package/lib/rules/eol-last.js +3 -0
  40. package/lib/rules/for-direction.js +38 -24
  41. package/lib/rules/func-call-spacing.js +3 -0
  42. package/lib/rules/function-call-argument-newline.js +3 -0
  43. package/lib/rules/function-paren-newline.js +3 -0
  44. package/lib/rules/generator-star-spacing.js +3 -0
  45. package/lib/rules/getter-return.js +33 -8
  46. package/lib/rules/implicit-arrow-linebreak.js +3 -0
  47. package/lib/rules/indent.js +3 -0
  48. package/lib/rules/index.js +1 -0
  49. package/lib/rules/jsx-quotes.js +3 -0
  50. package/lib/rules/key-spacing.js +3 -0
  51. package/lib/rules/keyword-spacing.js +3 -0
  52. package/lib/rules/linebreak-style.js +3 -0
  53. package/lib/rules/lines-around-comment.js +3 -0
  54. package/lib/rules/lines-between-class-members.js +95 -7
  55. package/lib/rules/logical-assignment-operators.js +31 -3
  56. package/lib/rules/max-len.js +3 -0
  57. package/lib/rules/max-statements-per-line.js +3 -0
  58. package/lib/rules/multiline-ternary.js +3 -0
  59. package/lib/rules/new-parens.js +3 -0
  60. package/lib/rules/newline-per-chained-call.js +3 -0
  61. package/lib/rules/no-array-constructor.js +85 -6
  62. package/lib/rules/no-confusing-arrow.js +3 -0
  63. package/lib/rules/no-console.js +74 -2
  64. package/lib/rules/no-extra-parens.js +3 -0
  65. package/lib/rules/no-extra-semi.js +3 -0
  66. package/lib/rules/no-fallthrough.js +42 -14
  67. package/lib/rules/no-floating-decimal.js +3 -0
  68. package/lib/rules/no-invalid-this.js +1 -1
  69. package/lib/rules/no-misleading-character-class.js +65 -15
  70. package/lib/rules/no-mixed-operators.js +3 -0
  71. package/lib/rules/no-mixed-spaces-and-tabs.js +3 -0
  72. package/lib/rules/no-multi-spaces.js +3 -0
  73. package/lib/rules/no-multiple-empty-lines.js +3 -0
  74. package/lib/rules/no-new-object.js +7 -0
  75. package/lib/rules/no-object-constructor.js +117 -0
  76. package/lib/rules/no-promise-executor-return.js +157 -16
  77. package/lib/rules/no-prototype-builtins.js +90 -2
  78. package/lib/rules/no-restricted-imports.js +54 -31
  79. package/lib/rules/no-restricted-properties.js +15 -28
  80. package/lib/rules/no-tabs.js +3 -0
  81. package/lib/rules/no-this-before-super.js +38 -11
  82. package/lib/rules/no-trailing-spaces.js +3 -0
  83. package/lib/rules/no-unreachable-loop.js +47 -12
  84. package/lib/rules/no-unreachable.js +39 -10
  85. package/lib/rules/no-useless-return.js +35 -4
  86. package/lib/rules/no-whitespace-before-property.js +3 -0
  87. package/lib/rules/nonblock-statement-body-position.js +3 -0
  88. package/lib/rules/object-curly-newline.js +3 -0
  89. package/lib/rules/object-curly-spacing.js +3 -0
  90. package/lib/rules/object-property-newline.js +3 -0
  91. package/lib/rules/one-var-declaration-per-line.js +3 -0
  92. package/lib/rules/operator-linebreak.js +3 -0
  93. package/lib/rules/padded-blocks.js +3 -0
  94. package/lib/rules/padding-line-between-statements.js +3 -0
  95. package/lib/rules/quote-props.js +3 -0
  96. package/lib/rules/quotes.js +3 -0
  97. package/lib/rules/require-atomic-updates.js +21 -7
  98. package/lib/rules/rest-spread-spacing.js +3 -0
  99. package/lib/rules/semi-spacing.js +3 -0
  100. package/lib/rules/semi-style.js +3 -0
  101. package/lib/rules/semi.js +3 -0
  102. package/lib/rules/space-before-blocks.js +3 -0
  103. package/lib/rules/space-before-function-paren.js +3 -0
  104. package/lib/rules/space-in-parens.js +3 -0
  105. package/lib/rules/space-infix-ops.js +3 -0
  106. package/lib/rules/space-unary-ops.js +3 -0
  107. package/lib/rules/spaced-comment.js +3 -0
  108. package/lib/rules/switch-colon-spacing.js +3 -0
  109. package/lib/rules/template-curly-spacing.js +3 -0
  110. package/lib/rules/template-tag-spacing.js +3 -0
  111. package/lib/rules/utils/ast-utils.js +111 -1
  112. package/lib/rules/wrap-iife.js +3 -0
  113. package/lib/rules/wrap-regex.js +3 -0
  114. package/lib/rules/yield-star-spacing.js +3 -0
  115. package/lib/shared/severity.js +49 -0
  116. package/lib/source-code/source-code.js +329 -3
  117. package/messages/eslintrc-incompat.js +1 -1
  118. package/package.json +24 -17
@@ -18,15 +18,6 @@ const astUtils = require("./utils/ast-utils");
18
18
  const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
19
19
  const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u;
20
20
 
21
- /**
22
- * Checks a given code path segment is reachable.
23
- * @param {CodePathSegment} segment A segment to check.
24
- * @returns {boolean} `true` if the segment is reachable.
25
- */
26
- function isReachable(segment) {
27
- return segment.reachable;
28
- }
29
-
30
21
  /**
31
22
  * Checks a given node is a member access which has the specified name's
32
23
  * property.
@@ -38,6 +29,22 @@ function isTargetMethod(node) {
38
29
  return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS);
39
30
  }
40
31
 
32
+ /**
33
+ * Checks all segments in a set and returns true if any are reachable.
34
+ * @param {Set<CodePathSegment>} segments The segments to check.
35
+ * @returns {boolean} True if any segment is reachable; false otherwise.
36
+ */
37
+ function isAnySegmentReachable(segments) {
38
+
39
+ for (const segment of segments) {
40
+ if (segment.reachable) {
41
+ return true;
42
+ }
43
+ }
44
+
45
+ return false;
46
+ }
47
+
41
48
  /**
42
49
  * Returns a human-legible description of an array method
43
50
  * @param {string} arrayMethodName A method name to fully qualify
@@ -129,6 +136,76 @@ function getArrayMethodName(node) {
129
136
  return null;
130
137
  }
131
138
 
139
+ /**
140
+ * Checks if the given node is a void expression.
141
+ * @param {ASTNode} node The node to check.
142
+ * @returns {boolean} - `true` if the node is a void expression
143
+ */
144
+ function isExpressionVoid(node) {
145
+ return node.type === "UnaryExpression" && node.operator === "void";
146
+ }
147
+
148
+ /**
149
+ * Fixes the linting error by prepending "void " to the given node
150
+ * @param {Object} sourceCode context given by context.sourceCode
151
+ * @param {ASTNode} node The node to fix.
152
+ * @param {Object} fixer The fixer object provided by ESLint.
153
+ * @returns {Array<Object>} - An array of fix objects to apply to the node.
154
+ */
155
+ function voidPrependFixer(sourceCode, node, fixer) {
156
+
157
+ const requiresParens =
158
+
159
+ // prepending `void ` will fail if the node has a lower precedence than void
160
+ astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression", operator: "void" }) &&
161
+
162
+ // check if there are parentheses around the node to avoid redundant parentheses
163
+ !astUtils.isParenthesised(sourceCode, node);
164
+
165
+ // avoid parentheses issues
166
+ const returnOrArrowToken = sourceCode.getTokenBefore(
167
+ node,
168
+ node.parent.type === "ArrowFunctionExpression"
169
+ ? astUtils.isArrowToken
170
+
171
+ // isReturnToken
172
+ : token => token.type === "Keyword" && token.value === "return"
173
+ );
174
+
175
+ const firstToken = sourceCode.getTokenAfter(returnOrArrowToken);
176
+
177
+ const prependSpace =
178
+
179
+ // is return token, as => allows void to be adjacent
180
+ returnOrArrowToken.value === "return" &&
181
+
182
+ // If two tokens (return and "(") are adjacent
183
+ returnOrArrowToken.range[1] === firstToken.range[0];
184
+
185
+ return [
186
+ fixer.insertTextBefore(firstToken, `${prependSpace ? " " : ""}void ${requiresParens ? "(" : ""}`),
187
+ fixer.insertTextAfter(node, requiresParens ? ")" : "")
188
+ ];
189
+ }
190
+
191
+ /**
192
+ * Fixes the linting error by `wrapping {}` around the given node's body.
193
+ * @param {Object} sourceCode context given by context.sourceCode
194
+ * @param {ASTNode} node The node to fix.
195
+ * @param {Object} fixer The fixer object provided by ESLint.
196
+ * @returns {Array<Object>} - An array of fix objects to apply to the node.
197
+ */
198
+ function curlyWrapFixer(sourceCode, node, fixer) {
199
+ const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
200
+ const firstToken = sourceCode.getTokenAfter(arrowToken);
201
+ const lastToken = sourceCode.getLastToken(node);
202
+
203
+ return [
204
+ fixer.insertTextBefore(firstToken, "{"),
205
+ fixer.insertTextAfter(lastToken, "}")
206
+ ];
207
+ }
208
+
132
209
  //------------------------------------------------------------------------------
133
210
  // Rule Definition
134
211
  //------------------------------------------------------------------------------
@@ -144,6 +221,9 @@ module.exports = {
144
221
  url: "https://eslint.org/docs/latest/rules/array-callback-return"
145
222
  },
146
223
 
224
+ // eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- false positive
225
+ hasSuggestions: true,
226
+
147
227
  schema: [
148
228
  {
149
229
  type: "object",
@@ -155,6 +235,10 @@ module.exports = {
155
235
  checkForEach: {
156
236
  type: "boolean",
157
237
  default: false
238
+ },
239
+ allowVoid: {
240
+ type: "boolean",
241
+ default: false
158
242
  }
159
243
  },
160
244
  additionalProperties: false
@@ -165,13 +249,15 @@ module.exports = {
165
249
  expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",
166
250
  expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.",
167
251
  expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.",
168
- expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}."
252
+ expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}.",
253
+ wrapBraces: "Wrap the expression in `{}`.",
254
+ prependVoid: "Prepend `void` to the expression."
169
255
  }
170
256
  },
171
257
 
172
258
  create(context) {
173
259
 
174
- const options = context.options[0] || { allowImplicit: false, checkForEach: false };
260
+ const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false };
175
261
  const sourceCode = context.sourceCode;
176
262
 
177
263
  let funcInfo = {
@@ -198,26 +284,56 @@ module.exports = {
198
284
  return;
199
285
  }
200
286
 
201
- let messageId = null;
287
+ const messageAndSuggestions = { messageId: "", suggest: [] };
202
288
 
203
289
  if (funcInfo.arrayMethodName === "forEach") {
204
290
  if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) {
205
- messageId = "expectedNoReturnValue";
291
+
292
+ if (options.allowVoid) {
293
+ if (isExpressionVoid(node.body)) {
294
+ return;
295
+ }
296
+
297
+ messageAndSuggestions.messageId = "expectedNoReturnValue";
298
+ messageAndSuggestions.suggest = [
299
+ {
300
+ messageId: "wrapBraces",
301
+ fix(fixer) {
302
+ return curlyWrapFixer(sourceCode, node, fixer);
303
+ }
304
+ },
305
+ {
306
+ messageId: "prependVoid",
307
+ fix(fixer) {
308
+ return voidPrependFixer(sourceCode, node.body, fixer);
309
+ }
310
+ }
311
+ ];
312
+ } else {
313
+ messageAndSuggestions.messageId = "expectedNoReturnValue";
314
+ messageAndSuggestions.suggest = [{
315
+ messageId: "wrapBraces",
316
+ fix(fixer) {
317
+ return curlyWrapFixer(sourceCode, node, fixer);
318
+ }
319
+ }];
320
+ }
206
321
  }
207
322
  } else {
208
- if (node.body.type === "BlockStatement" && funcInfo.codePath.currentSegments.some(isReachable)) {
209
- messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
323
+ if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) {
324
+ messageAndSuggestions.messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
210
325
  }
211
326
  }
212
327
 
213
- if (messageId) {
328
+ if (messageAndSuggestions.messageId) {
214
329
  const name = astUtils.getFunctionNameWithKind(node);
215
330
 
216
331
  context.report({
217
332
  node,
218
333
  loc: astUtils.getFunctionHeadLoc(node, sourceCode),
219
- messageId,
220
- data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) }
334
+ messageId: messageAndSuggestions.messageId,
335
+ data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) },
336
+ suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
221
337
  });
222
338
  }
223
339
  }
@@ -242,7 +358,8 @@ module.exports = {
242
358
  methodName &&
243
359
  !node.async &&
244
360
  !node.generator,
245
- node
361
+ node,
362
+ currentSegments: new Set()
246
363
  };
247
364
  },
248
365
 
@@ -251,6 +368,23 @@ module.exports = {
251
368
  funcInfo = funcInfo.upper;
252
369
  },
253
370
 
371
+ onUnreachableCodePathSegmentStart(segment) {
372
+ funcInfo.currentSegments.add(segment);
373
+ },
374
+
375
+ onUnreachableCodePathSegmentEnd(segment) {
376
+ funcInfo.currentSegments.delete(segment);
377
+ },
378
+
379
+ onCodePathSegmentStart(segment) {
380
+ funcInfo.currentSegments.add(segment);
381
+ },
382
+
383
+ onCodePathSegmentEnd(segment) {
384
+ funcInfo.currentSegments.delete(segment);
385
+ },
386
+
387
+
254
388
  // Checks the return statement is valid.
255
389
  ReturnStatement(node) {
256
390
 
@@ -260,30 +394,46 @@ module.exports = {
260
394
 
261
395
  funcInfo.hasReturn = true;
262
396
 
263
- let messageId = null;
397
+ const messageAndSuggestions = { messageId: "", suggest: [] };
264
398
 
265
399
  if (funcInfo.arrayMethodName === "forEach") {
266
400
 
267
401
  // if checkForEach: true, returning a value at any path inside a forEach is not allowed
268
402
  if (options.checkForEach && node.argument) {
269
- messageId = "expectedNoReturnValue";
403
+
404
+ if (options.allowVoid) {
405
+ if (isExpressionVoid(node.argument)) {
406
+ return;
407
+ }
408
+
409
+ messageAndSuggestions.messageId = "expectedNoReturnValue";
410
+ messageAndSuggestions.suggest = [{
411
+ messageId: "prependVoid",
412
+ fix(fixer) {
413
+ return voidPrependFixer(sourceCode, node.argument, fixer);
414
+ }
415
+ }];
416
+ } else {
417
+ messageAndSuggestions.messageId = "expectedNoReturnValue";
418
+ }
270
419
  }
271
420
  } else {
272
421
 
273
422
  // if allowImplicit: false, should also check node.argument
274
423
  if (!options.allowImplicit && !node.argument) {
275
- messageId = "expectedReturnValue";
424
+ messageAndSuggestions.messageId = "expectedReturnValue";
276
425
  }
277
426
  }
278
427
 
279
- if (messageId) {
428
+ if (messageAndSuggestions.messageId) {
280
429
  context.report({
281
430
  node,
282
- messageId,
431
+ messageId: messageAndSuggestions.messageId,
283
432
  data: {
284
433
  name: astUtils.getFunctionNameWithKind(funcInfo.node),
285
434
  arrayMethodName: fullMethodName(funcInfo.arrayMethodName)
286
- }
435
+ },
436
+ suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
287
437
  });
288
438
  }
289
439
  },
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to enforce line breaks after each array element
3
3
  * @author Jan Peer Stöcklmair <https://github.com/JPeer264>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to require parens in arrow function arguments.
3
3
  * @author Jxck
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -30,6 +31,8 @@ function hasBlockBody(node) {
30
31
  /** @type {import('../shared/types').Rule} */
31
32
  module.exports = {
32
33
  meta: {
34
+ deprecated: true,
35
+ replacedBy: [],
33
36
  type: "layout",
34
37
 
35
38
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to define spacing before/after arrow function's arrow.
3
3
  * @author Jxck
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -17,6 +18,8 @@ const astUtils = require("./utils/ast-utils");
17
18
  /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
21
+ deprecated: true,
22
+ replacedBy: [],
20
23
  type: "layout",
21
24
 
22
25
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
3
3
  * @author Toru Nagashima
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const util = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to flag block statements that do not use the one true brace style
3
3
  * @author Ian Christian Myers
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to forbid or enforce dangling commas.
3
3
  * @author Ian Christian Myers
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -73,6 +74,8 @@ function normalizeOptions(optionValue, ecmaVersion) {
73
74
  /** @type {import('../shared/types').Rule} */
74
75
  module.exports = {
75
76
  meta: {
77
+ deprecated: true,
78
+ replacedBy: [],
76
79
  type: "layout",
77
80
 
78
81
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Comma spacing - validates spacing before and after comma
3
3
  * @author Vignesh Anand aka vegetableman.
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -13,6 +14,8 @@ const astUtils = require("./utils/ast-utils");
13
14
  /** @type {import('../shared/types').Rule} */
14
15
  module.exports = {
15
16
  meta: {
17
+ deprecated: true,
18
+ replacedBy: [],
16
19
  type: "layout",
17
20
 
18
21
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Comma style - enforces comma styles of two types: last and first
3
3
  * @author Vignesh Anand aka vegetableman
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Disallows or enforces spaces inside computed properties.
3
3
  * @author Jamund Ferguson
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -13,6 +14,8 @@ const astUtils = require("./utils/ast-utils");
13
14
  /** @type {import('../shared/types').Rule} */
14
15
  module.exports = {
15
16
  meta: {
17
+ deprecated: true,
18
+ replacedBy: [],
16
19
  type: "layout",
17
20
 
18
21
  docs: {
@@ -16,12 +16,19 @@ const { upperCaseFirst } = require("../shared/string-utils");
16
16
  //------------------------------------------------------------------------------
17
17
 
18
18
  /**
19
- * Checks whether or not a given code path segment is unreachable.
20
- * @param {CodePathSegment} segment A CodePathSegment to check.
21
- * @returns {boolean} `true` if the segment is unreachable.
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
22
  */
23
- function isUnreachable(segment) {
24
- return !segment.reachable;
23
+ function areAllSegmentsUnreachable(segments) {
24
+
25
+ for (const segment of segments) {
26
+ if (segment.reachable) {
27
+ return false;
28
+ }
29
+ }
30
+
31
+ return true;
25
32
  }
26
33
 
27
34
  /**
@@ -88,7 +95,7 @@ module.exports = {
88
95
  * When unreachable, all paths are returned or thrown.
89
96
  */
90
97
  if (!funcInfo.hasReturnValue ||
91
- funcInfo.codePath.currentSegments.every(isUnreachable) ||
98
+ areAllSegmentsUnreachable(funcInfo.currentSegments) ||
92
99
  astUtils.isES5Constructor(node) ||
93
100
  isClassConstructor(node)
94
101
  ) {
@@ -141,13 +148,31 @@ module.exports = {
141
148
  hasReturn: false,
142
149
  hasReturnValue: false,
143
150
  messageId: "",
144
- node
151
+ node,
152
+ currentSegments: new Set()
145
153
  };
146
154
  },
147
155
  onCodePathEnd() {
148
156
  funcInfo = funcInfo.upper;
149
157
  },
150
158
 
159
+ onUnreachableCodePathSegmentStart(segment) {
160
+ funcInfo.currentSegments.add(segment);
161
+ },
162
+
163
+ onUnreachableCodePathSegmentEnd(segment) {
164
+ funcInfo.currentSegments.delete(segment);
165
+ },
166
+
167
+ onCodePathSegmentStart(segment) {
168
+ funcInfo.currentSegments.add(segment);
169
+ },
170
+
171
+ onCodePathSegmentEnd(segment) {
172
+ funcInfo.currentSegments.delete(segment);
173
+ },
174
+
175
+
151
176
  // Reports a given return statement if it's inconsistent.
152
177
  ReturnStatement(node) {
153
178
  const argument = node.argument;
@@ -10,12 +10,19 @@
10
10
  //------------------------------------------------------------------------------
11
11
 
12
12
  /**
13
- * Checks whether a given code path segment is reachable or not.
14
- * @param {CodePathSegment} segment A code path segment to check.
15
- * @returns {boolean} `true` if the segment is reachable.
13
+ * Checks all segments in a set and returns true if any are reachable.
14
+ * @param {Set<CodePathSegment>} segments The segments to check.
15
+ * @returns {boolean} True if any segment is reachable; false otherwise.
16
16
  */
17
- function isReachable(segment) {
18
- return segment.reachable;
17
+ function isAnySegmentReachable(segments) {
18
+
19
+ for (const segment of segments) {
20
+ if (segment.reachable) {
21
+ return true;
22
+ }
23
+ }
24
+
25
+ return false;
19
26
  }
20
27
 
21
28
  /**
@@ -210,7 +217,8 @@ module.exports = {
210
217
  isConstructor: true,
211
218
  hasExtends: Boolean(superClass),
212
219
  superIsConstructor: isPossibleConstructor(superClass),
213
- codePath
220
+ codePath,
221
+ currentSegments: new Set()
214
222
  };
215
223
  } else {
216
224
  funcInfo = {
@@ -218,7 +226,8 @@ module.exports = {
218
226
  isConstructor: false,
219
227
  hasExtends: false,
220
228
  superIsConstructor: false,
221
- codePath
229
+ codePath,
230
+ currentSegments: new Set()
222
231
  };
223
232
  }
224
233
  },
@@ -261,6 +270,9 @@ module.exports = {
261
270
  * @returns {void}
262
271
  */
263
272
  onCodePathSegmentStart(segment) {
273
+
274
+ funcInfo.currentSegments.add(segment);
275
+
264
276
  if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
265
277
  return;
266
278
  }
@@ -281,6 +293,19 @@ module.exports = {
281
293
  }
282
294
  },
283
295
 
296
+ onUnreachableCodePathSegmentStart(segment) {
297
+ funcInfo.currentSegments.add(segment);
298
+ },
299
+
300
+ onUnreachableCodePathSegmentEnd(segment) {
301
+ funcInfo.currentSegments.delete(segment);
302
+ },
303
+
304
+ onCodePathSegmentEnd(segment) {
305
+ funcInfo.currentSegments.delete(segment);
306
+ },
307
+
308
+
284
309
  /**
285
310
  * Update information of the code path segment when a code path was
286
311
  * looped.
@@ -344,12 +369,11 @@ module.exports = {
344
369
 
345
370
  // Reports if needed.
346
371
  if (funcInfo.hasExtends) {
347
- const segments = funcInfo.codePath.currentSegments;
372
+ const segments = funcInfo.currentSegments;
348
373
  let duplicate = false;
349
374
  let info = null;
350
375
 
351
- for (let i = 0; i < segments.length; ++i) {
352
- const segment = segments[i];
376
+ for (const segment of segments) {
353
377
 
354
378
  if (segment.reachable) {
355
379
  info = segInfoMap[segment.id];
@@ -374,7 +398,7 @@ module.exports = {
374
398
  info.validNodes.push(node);
375
399
  }
376
400
  }
377
- } else if (funcInfo.codePath.currentSegments.some(isReachable)) {
401
+ } else if (isAnySegmentReachable(funcInfo.currentSegments)) {
378
402
  context.report({
379
403
  messageId: "unexpected",
380
404
  node
@@ -398,10 +422,9 @@ module.exports = {
398
422
  }
399
423
 
400
424
  // Returning argument is a substitute of 'super()'.
401
- const segments = funcInfo.codePath.currentSegments;
425
+ const segments = funcInfo.currentSegments;
402
426
 
403
- for (let i = 0; i < segments.length; ++i) {
404
- const segment = segments[i];
427
+ for (const segment of segments) {
405
428
 
406
429
  if (segment.reachable) {
407
430
  const info = segInfoMap[segment.id];
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Validates newlines before and after dots
3
3
  * @author Greg Cochard
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Require or disallow newline at the end of files
3
3
  * @author Nodeca Team <https://github.com/nodeca>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -11,6 +12,8 @@
11
12
  /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
15
+ deprecated: true,
16
+ replacedBy: [],
14
17
  type: "layout",
15
18
 
16
19
  docs: {