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
@@ -13,10 +13,13 @@
13
13
  const
14
14
  assert = require("assert"),
15
15
  util = require("util"),
16
+ path = require("path"),
16
17
  equal = require("fast-deep-equal"),
17
18
  Traverser = require("../shared/traverser"),
18
19
  { getRuleOptionsSchema } = require("../config/flat-config-helpers"),
19
- { Linter, SourceCodeFixer, interpolate } = require("../linter");
20
+ { Linter, SourceCodeFixer, interpolate } = require("../linter"),
21
+ CodePath = require("../linter/code-path-analysis/code-path");
22
+
20
23
  const { FlatConfigArray } = require("../config/flat-config-array");
21
24
  const { defaultConfig } = require("../config/default-config");
22
25
 
@@ -32,6 +35,7 @@ const { ConfigArraySymbol } = require("@humanwhocodes/config-array");
32
35
 
33
36
  /** @typedef {import("../shared/types").Parser} Parser */
34
37
  /** @typedef {import("../shared/types").LanguageOptions} LanguageOptions */
38
+ /** @typedef {import("../shared/types").Rule} Rule */
35
39
 
36
40
 
37
41
  /**
@@ -130,6 +134,15 @@ const suggestionObjectParameters = new Set([
130
134
  ]);
131
135
  const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`;
132
136
 
137
+ const forbiddenMethods = [
138
+ "applyInlineConfig",
139
+ "applyLanguageOptions",
140
+ "finalize"
141
+ ];
142
+
143
+ /** @type {Map<string,WeakSet>} */
144
+ const forbiddenMethodCalls = new Map(forbiddenMethods.map(methodName => ([methodName, new WeakSet()])));
145
+
133
146
  const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
134
147
 
135
148
  /**
@@ -273,6 +286,49 @@ function getCommentsDeprecation() {
273
286
  );
274
287
  }
275
288
 
289
+ /**
290
+ * Emit a deprecation warning if rule uses CodePath#currentSegments.
291
+ * @param {string} ruleName Name of the rule.
292
+ * @returns {void}
293
+ */
294
+ function emitCodePathCurrentSegmentsWarning(ruleName) {
295
+ if (!emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`]) {
296
+ emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`] = true;
297
+ process.emitWarning(
298
+ `"${ruleName}" rule uses CodePath#currentSegments and will stop working in ESLint v9. Please read the documentation for how to update your code: https://eslint.org/docs/latest/extend/code-path-analysis#usage-examples`,
299
+ "DeprecationWarning"
300
+ );
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Function to replace forbidden `SourceCode` methods. Allows just one call per method.
306
+ * @param {string} methodName The name of the method to forbid.
307
+ * @param {Function} prototype The prototype with the original method to call.
308
+ * @returns {Function} The function that throws the error.
309
+ */
310
+ function throwForbiddenMethodError(methodName, prototype) {
311
+
312
+ const original = prototype[methodName];
313
+
314
+ return function(...args) {
315
+
316
+ const called = forbiddenMethodCalls.get(methodName);
317
+
318
+ /* eslint-disable no-invalid-this -- needed to operate as a method. */
319
+ if (!called.has(this)) {
320
+ called.add(this);
321
+
322
+ return original.apply(this, args);
323
+ }
324
+ /* eslint-enable no-invalid-this -- not needed past this point */
325
+
326
+ throw new Error(
327
+ `\`SourceCode#${methodName}()\` cannot be called inside a rule.`
328
+ );
329
+ };
330
+ }
331
+
276
332
  //------------------------------------------------------------------------------
277
333
  // Public Interface
278
334
  //------------------------------------------------------------------------------
@@ -446,7 +502,7 @@ class FlatRuleTester {
446
502
  /**
447
503
  * Adds a new rule test to execute.
448
504
  * @param {string} ruleName The name of the rule to run.
449
- * @param {Function} rule The rule to test.
505
+ * @param {Function | Rule} rule The rule to test.
450
506
  * @param {{
451
507
  * valid: (ValidTestCase | string)[],
452
508
  * invalid: InvalidTestCase[]
@@ -480,6 +536,7 @@ class FlatRuleTester {
480
536
  }
481
537
 
482
538
  const baseConfig = [
539
+ { files: ["**"] }, // Make sure the default config matches for all files
483
540
  {
484
541
  plugins: {
485
542
 
@@ -536,7 +593,15 @@ class FlatRuleTester {
536
593
  * @private
537
594
  */
538
595
  function runRuleForItem(item) {
539
- const configs = new FlatConfigArray(testerConfig, { baseConfig });
596
+ const flatConfigArrayOptions = {
597
+ baseConfig
598
+ };
599
+
600
+ if (item.filename) {
601
+ flatConfigArrayOptions.basePath = path.parse(item.filename).root;
602
+ }
603
+
604
+ const configs = new FlatConfigArray(testerConfig, flatConfigArrayOptions);
540
605
 
541
606
  /*
542
607
  * Modify the returned config so that the parser is wrapped to catch
@@ -661,10 +726,6 @@ class FlatRuleTester {
661
726
  }
662
727
  }
663
728
 
664
- // Verify the code.
665
- const { getComments } = SourceCode.prototype;
666
- let messages;
667
-
668
729
  // check for validation errors
669
730
  try {
670
731
  configs.normalizeSync();
@@ -674,13 +735,34 @@ class FlatRuleTester {
674
735
  throw error;
675
736
  }
676
737
 
738
+ // Verify the code.
739
+ const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype;
740
+ const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
741
+ let messages;
742
+
677
743
  try {
678
744
  SourceCode.prototype.getComments = getCommentsDeprecation;
745
+ Object.defineProperty(CodePath.prototype, "currentSegments", {
746
+ get() {
747
+ emitCodePathCurrentSegmentsWarning(ruleName);
748
+ return originalCurrentSegments.get.call(this);
749
+ }
750
+ });
751
+
752
+ forbiddenMethods.forEach(methodName => {
753
+ SourceCode.prototype[methodName] = throwForbiddenMethodError(methodName, SourceCode.prototype);
754
+ });
755
+
679
756
  messages = linter.verify(code, configs, filename);
680
757
  } finally {
681
758
  SourceCode.prototype.getComments = getComments;
759
+ Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
760
+ SourceCode.prototype.applyInlineConfig = applyInlineConfig;
761
+ SourceCode.prototype.applyLanguageOptions = applyLanguageOptions;
762
+ SourceCode.prototype.finalize = finalize;
682
763
  }
683
764
 
765
+
684
766
  const fatalErrorMessage = messages.find(m => m.fatal);
685
767
 
686
768
  assert(!fatalErrorMessage, `A fatal parsing error occurred: ${fatalErrorMessage && fatalErrorMessage.message}`);
@@ -1011,29 +1093,35 @@ class FlatRuleTester {
1011
1093
  /*
1012
1094
  * This creates a mocha test suite and pipes all supplied info through
1013
1095
  * one of the templates above.
1096
+ * The test suites for valid/invalid are created conditionally as
1097
+ * test runners (eg. vitest) fail for empty test suites.
1014
1098
  */
1015
1099
  this.constructor.describe(ruleName, () => {
1016
- this.constructor.describe("valid", () => {
1017
- test.valid.forEach(valid => {
1018
- this.constructor[valid.only ? "itOnly" : "it"](
1019
- sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
1020
- () => {
1021
- testValidTemplate(valid);
1022
- }
1023
- );
1100
+ if (test.valid.length > 0) {
1101
+ this.constructor.describe("valid", () => {
1102
+ test.valid.forEach(valid => {
1103
+ this.constructor[valid.only ? "itOnly" : "it"](
1104
+ sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
1105
+ () => {
1106
+ testValidTemplate(valid);
1107
+ }
1108
+ );
1109
+ });
1024
1110
  });
1025
- });
1111
+ }
1026
1112
 
1027
- this.constructor.describe("invalid", () => {
1028
- test.invalid.forEach(invalid => {
1029
- this.constructor[invalid.only ? "itOnly" : "it"](
1030
- sanitize(invalid.name || invalid.code),
1031
- () => {
1032
- testInvalidTemplate(invalid);
1033
- }
1034
- );
1113
+ if (test.invalid.length > 0) {
1114
+ this.constructor.describe("invalid", () => {
1115
+ test.invalid.forEach(invalid => {
1116
+ this.constructor[invalid.only ? "itOnly" : "it"](
1117
+ sanitize(invalid.name || invalid.code),
1118
+ () => {
1119
+ testInvalidTemplate(invalid);
1120
+ }
1121
+ );
1122
+ });
1035
1123
  });
1036
- });
1124
+ }
1037
1125
  });
1038
1126
  }
1039
1127
  }
@@ -48,7 +48,8 @@ const
48
48
  equal = require("fast-deep-equal"),
49
49
  Traverser = require("../../lib/shared/traverser"),
50
50
  { getRuleOptionsSchema, validate } = require("../shared/config-validator"),
51
- { Linter, SourceCodeFixer, interpolate } = require("../linter");
51
+ { Linter, SourceCodeFixer, interpolate } = require("../linter"),
52
+ CodePath = require("../linter/code-path-analysis/code-path");
52
53
 
53
54
  const ajv = require("../shared/ajv")({ strictDefaults: true });
54
55
 
@@ -62,6 +63,7 @@ const { SourceCode } = require("../source-code");
62
63
  //------------------------------------------------------------------------------
63
64
 
64
65
  /** @typedef {import("../shared/types").Parser} Parser */
66
+ /** @typedef {import("../shared/types").Rule} Rule */
65
67
 
66
68
 
67
69
  /**
@@ -161,8 +163,43 @@ const suggestionObjectParameters = new Set([
161
163
  ]);
162
164
  const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`;
163
165
 
166
+ const forbiddenMethods = [
167
+ "applyInlineConfig",
168
+ "applyLanguageOptions",
169
+ "finalize"
170
+ ];
171
+
164
172
  const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
165
173
 
174
+ const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
175
+ getSource: "getText",
176
+ getSourceLines: "getLines",
177
+ getAllComments: "getAllComments",
178
+ getNodeByRangeIndex: "getNodeByRangeIndex",
179
+
180
+ // getComments: "getComments", -- already handled by a separate error
181
+ getCommentsBefore: "getCommentsBefore",
182
+ getCommentsAfter: "getCommentsAfter",
183
+ getCommentsInside: "getCommentsInside",
184
+ getJSDocComment: "getJSDocComment",
185
+ getFirstToken: "getFirstToken",
186
+ getFirstTokens: "getFirstTokens",
187
+ getLastToken: "getLastToken",
188
+ getLastTokens: "getLastTokens",
189
+ getTokenAfter: "getTokenAfter",
190
+ getTokenBefore: "getTokenBefore",
191
+ getTokenByRangeStart: "getTokenByRangeStart",
192
+ getTokens: "getTokens",
193
+ getTokensAfter: "getTokensAfter",
194
+ getTokensBefore: "getTokensBefore",
195
+ getTokensBetween: "getTokensBetween",
196
+
197
+ getScope: "getScope",
198
+ getAncestors: "getAncestors",
199
+ getDeclaredVariables: "getDeclaredVariables",
200
+ markVariableAsUsed: "markVariableAsUsed"
201
+ };
202
+
166
203
  /**
167
204
  * Clones a given value deeply.
168
205
  * Note: This ignores `parent` property.
@@ -304,6 +341,19 @@ function getCommentsDeprecation() {
304
341
  );
305
342
  }
306
343
 
344
+ /**
345
+ * Function to replace forbidden `SourceCode` methods.
346
+ * @param {string} methodName The name of the method to forbid.
347
+ * @returns {Function} The function that throws the error.
348
+ */
349
+ function throwForbiddenMethodError(methodName) {
350
+ return () => {
351
+ throw new Error(
352
+ `\`SourceCode#${methodName}()\` cannot be called inside a rule.`
353
+ );
354
+ };
355
+ }
356
+
307
357
  /**
308
358
  * Emit a deprecation warning if function-style format is being used.
309
359
  * @param {string} ruleName Name of the rule.
@@ -334,6 +384,53 @@ function emitMissingSchemaWarning(ruleName) {
334
384
  }
335
385
  }
336
386
 
387
+ /**
388
+ * Emit a deprecation warning if a rule uses a deprecated `context` method.
389
+ * @param {string} ruleName Name of the rule.
390
+ * @param {string} methodName The name of the method on `context` that was used.
391
+ * @returns {void}
392
+ */
393
+ function emitDeprecatedContextMethodWarning(ruleName, methodName) {
394
+ if (!emitDeprecatedContextMethodWarning[`warned-${ruleName}-${methodName}`]) {
395
+ emitDeprecatedContextMethodWarning[`warned-${ruleName}-${methodName}`] = true;
396
+ process.emitWarning(
397
+ `"${ruleName}" rule is using \`context.${methodName}()\`, which is deprecated and will be removed in ESLint v9. Please use \`sourceCode.${DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]}()\` instead.`,
398
+ "DeprecationWarning"
399
+ );
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Emit a deprecation warning if rule uses CodePath#currentSegments.
405
+ * @param {string} ruleName Name of the rule.
406
+ * @returns {void}
407
+ */
408
+ function emitCodePathCurrentSegmentsWarning(ruleName) {
409
+ if (!emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`]) {
410
+ emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`] = true;
411
+ process.emitWarning(
412
+ `"${ruleName}" rule uses CodePath#currentSegments and will stop working in ESLint v9. Please read the documentation for how to update your code: https://eslint.org/docs/latest/extend/code-path-analysis#usage-examples`,
413
+ "DeprecationWarning"
414
+ );
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Emit a deprecation warning if `context.parserServices` is used.
420
+ * @param {string} ruleName Name of the rule.
421
+ * @returns {void}
422
+ */
423
+ function emitParserServicesWarning(ruleName) {
424
+ if (!emitParserServicesWarning[`warned-${ruleName}`]) {
425
+ emitParserServicesWarning[`warned-${ruleName}`] = true;
426
+ process.emitWarning(
427
+ `"${ruleName}" rule is using \`context.parserServices\`, which is deprecated and will be removed in ESLint v9. Please use \`sourceCode.parserServices\` instead.`,
428
+ "DeprecationWarning"
429
+ );
430
+ }
431
+ }
432
+
433
+
337
434
  //------------------------------------------------------------------------------
338
435
  // Public Interface
339
436
  //------------------------------------------------------------------------------
@@ -508,17 +605,20 @@ class RuleTester {
508
605
  /**
509
606
  * Define a rule for one particular run of tests.
510
607
  * @param {string} name The name of the rule to define.
511
- * @param {Function} rule The rule definition.
608
+ * @param {Function | Rule} rule The rule definition.
512
609
  * @returns {void}
513
610
  */
514
611
  defineRule(name, rule) {
612
+ if (typeof rule === "function") {
613
+ emitLegacyRuleAPIWarning(name);
614
+ }
515
615
  this.rules[name] = rule;
516
616
  }
517
617
 
518
618
  /**
519
619
  * Adds a new rule test to execute.
520
620
  * @param {string} ruleName The name of the rule to run.
521
- * @param {Function} rule The rule to test.
621
+ * @param {Function | Rule} rule The rule to test.
522
622
  * @param {{
523
623
  * valid: (ValidTestCase | string)[],
524
624
  * invalid: InvalidTestCase[]
@@ -562,7 +662,38 @@ class RuleTester {
562
662
  freezeDeeply(context.settings);
563
663
  freezeDeeply(context.parserOptions);
564
664
 
565
- return (typeof rule === "function" ? rule : rule.create)(context);
665
+ // wrap all deprecated methods
666
+ const newContext = Object.create(
667
+ context,
668
+ Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
669
+ methodName,
670
+ {
671
+ value(...args) {
672
+
673
+ // emit deprecation warning
674
+ emitDeprecatedContextMethodWarning(ruleName, methodName);
675
+
676
+ // call the original method
677
+ return context[methodName].call(this, ...args);
678
+ },
679
+ enumerable: true
680
+ }
681
+ ]))
682
+ );
683
+
684
+ // emit warning about context.parserServices
685
+ const parserServices = context.parserServices;
686
+
687
+ Object.defineProperty(newContext, "parserServices", {
688
+ get() {
689
+ emitParserServicesWarning(ruleName);
690
+ return parserServices;
691
+ }
692
+ });
693
+
694
+ Object.freeze(newContext);
695
+
696
+ return (typeof rule === "function" ? rule : rule.create)(newContext);
566
697
  }
567
698
  }));
568
699
 
@@ -681,14 +812,30 @@ class RuleTester {
681
812
  validate(config, "rule-tester", id => (id === ruleName ? rule : null));
682
813
 
683
814
  // Verify the code.
684
- const { getComments } = SourceCode.prototype;
815
+ const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype;
816
+ const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
685
817
  let messages;
686
818
 
687
819
  try {
688
820
  SourceCode.prototype.getComments = getCommentsDeprecation;
821
+ Object.defineProperty(CodePath.prototype, "currentSegments", {
822
+ get() {
823
+ emitCodePathCurrentSegmentsWarning(ruleName);
824
+ return originalCurrentSegments.get.call(this);
825
+ }
826
+ });
827
+
828
+ forbiddenMethods.forEach(methodName => {
829
+ SourceCode.prototype[methodName] = throwForbiddenMethodError(methodName);
830
+ });
831
+
689
832
  messages = linter.verify(code, config, filename);
690
833
  } finally {
691
834
  SourceCode.prototype.getComments = getComments;
835
+ Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
836
+ SourceCode.prototype.applyInlineConfig = applyInlineConfig;
837
+ SourceCode.prototype.applyLanguageOptions = applyLanguageOptions;
838
+ SourceCode.prototype.finalize = finalize;
692
839
  }
693
840
 
694
841
  const fatalErrorMessage = messages.find(m => m.fatal);
@@ -1021,29 +1168,35 @@ class RuleTester {
1021
1168
  /*
1022
1169
  * This creates a mocha test suite and pipes all supplied info through
1023
1170
  * one of the templates above.
1171
+ * The test suites for valid/invalid are created conditionally as
1172
+ * test runners (eg. vitest) fail for empty test suites.
1024
1173
  */
1025
1174
  this.constructor.describe(ruleName, () => {
1026
- this.constructor.describe("valid", () => {
1027
- test.valid.forEach(valid => {
1028
- this.constructor[valid.only ? "itOnly" : "it"](
1029
- sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
1030
- () => {
1031
- testValidTemplate(valid);
1032
- }
1033
- );
1175
+ if (test.valid.length > 0) {
1176
+ this.constructor.describe("valid", () => {
1177
+ test.valid.forEach(valid => {
1178
+ this.constructor[valid.only ? "itOnly" : "it"](
1179
+ sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
1180
+ () => {
1181
+ testValidTemplate(valid);
1182
+ }
1183
+ );
1184
+ });
1034
1185
  });
1035
- });
1186
+ }
1036
1187
 
1037
- this.constructor.describe("invalid", () => {
1038
- test.invalid.forEach(invalid => {
1039
- this.constructor[invalid.only ? "itOnly" : "it"](
1040
- sanitize(invalid.name || invalid.code),
1041
- () => {
1042
- testInvalidTemplate(invalid);
1043
- }
1044
- );
1188
+ if (test.invalid.length > 0) {
1189
+ this.constructor.describe("invalid", () => {
1190
+ test.invalid.forEach(invalid => {
1191
+ this.constructor[invalid.only ? "itOnly" : "it"](
1192
+ sanitize(invalid.name || invalid.code),
1193
+ () => {
1194
+ testInvalidTemplate(invalid);
1195
+ }
1196
+ );
1197
+ });
1045
1198
  });
1046
- });
1199
+ }
1047
1200
  });
1048
1201
  }
1049
1202
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to enforce linebreaks after open and before close array brackets
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 Disallows or enforces spaces inside of array brackets.
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: {