eslint 8.56.0 → 9.0.0-alpha.1

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 (121) hide show
  1. package/README.md +7 -2
  2. package/conf/ecma-version.js +16 -0
  3. package/conf/rule-type-list.json +3 -1
  4. package/lib/api.js +1 -1
  5. package/lib/cli-engine/cli-engine.js +14 -3
  6. package/lib/cli-engine/formatters/formatters-meta.json +1 -29
  7. package/lib/cli-engine/lint-result-cache.js +2 -2
  8. package/lib/cli.js +46 -25
  9. package/lib/config/default-config.js +3 -0
  10. package/lib/config/flat-config-array.js +0 -20
  11. package/lib/config/flat-config-helpers.js +41 -20
  12. package/lib/config/flat-config-schema.js +35 -25
  13. package/lib/config/rule-validator.js +27 -4
  14. package/lib/eslint/eslint-helpers.js +32 -12
  15. package/lib/eslint/eslint.js +856 -373
  16. package/lib/eslint/index.js +2 -2
  17. package/lib/eslint/legacy-eslint.js +722 -0
  18. package/lib/linter/apply-disable-directives.js +35 -7
  19. package/lib/linter/code-path-analysis/code-path.js +5 -19
  20. package/lib/linter/code-path-analysis/fork-context.js +1 -1
  21. package/lib/linter/config-comment-parser.js +8 -11
  22. package/lib/linter/linter.js +196 -100
  23. package/lib/linter/report-translator.js +2 -2
  24. package/lib/linter/rules.js +6 -15
  25. package/lib/linter/source-code-fixer.js +1 -1
  26. package/lib/options.js +9 -1
  27. package/lib/rule-tester/rule-tester.js +234 -291
  28. package/lib/rules/array-bracket-newline.js +1 -1
  29. package/lib/rules/array-bracket-spacing.js +1 -1
  30. package/lib/rules/block-scoped-var.js +1 -1
  31. package/lib/rules/callback-return.js +2 -2
  32. package/lib/rules/comma-dangle.js +1 -1
  33. package/lib/rules/comma-style.js +2 -2
  34. package/lib/rules/complexity.js +1 -1
  35. package/lib/rules/constructor-super.js +1 -1
  36. package/lib/rules/default-case.js +1 -1
  37. package/lib/rules/eol-last.js +2 -2
  38. package/lib/rules/function-paren-newline.js +2 -2
  39. package/lib/rules/indent-legacy.js +5 -5
  40. package/lib/rules/indent.js +5 -5
  41. package/lib/rules/index.js +1 -2
  42. package/lib/rules/key-spacing.js +2 -2
  43. package/lib/rules/line-comment-position.js +1 -1
  44. package/lib/rules/lines-around-directive.js +2 -2
  45. package/lib/rules/max-depth.js +1 -1
  46. package/lib/rules/max-len.js +3 -3
  47. package/lib/rules/max-lines.js +3 -3
  48. package/lib/rules/max-nested-callbacks.js +1 -1
  49. package/lib/rules/max-params.js +1 -1
  50. package/lib/rules/max-statements.js +1 -1
  51. package/lib/rules/multiline-comment-style.js +7 -7
  52. package/lib/rules/new-cap.js +1 -1
  53. package/lib/rules/newline-after-var.js +1 -1
  54. package/lib/rules/newline-before-return.js +1 -1
  55. package/lib/rules/no-constant-binary-expression.js +6 -6
  56. package/lib/rules/no-constructor-return.js +2 -2
  57. package/lib/rules/no-dupe-class-members.js +2 -2
  58. package/lib/rules/no-else-return.js +1 -1
  59. package/lib/rules/no-empty-function.js +2 -2
  60. package/lib/rules/no-empty-static-block.js +1 -1
  61. package/lib/rules/no-extra-semi.js +1 -1
  62. package/lib/rules/no-fallthrough.js +1 -1
  63. package/lib/rules/no-implicit-coercion.js +17 -1
  64. package/lib/rules/no-inner-declarations.js +23 -2
  65. package/lib/rules/no-invalid-regexp.js +1 -1
  66. package/lib/rules/no-invalid-this.js +1 -1
  67. package/lib/rules/no-lone-blocks.js +2 -2
  68. package/lib/rules/no-loss-of-precision.js +1 -1
  69. package/lib/rules/no-misleading-character-class.js +174 -65
  70. package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
  71. package/lib/rules/no-multiple-empty-lines.js +1 -1
  72. package/lib/rules/no-new-native-nonconstructor.js +1 -1
  73. package/lib/rules/no-new-symbol.js +8 -1
  74. package/lib/rules/no-restricted-globals.js +1 -1
  75. package/lib/rules/no-restricted-imports.js +2 -2
  76. package/lib/rules/no-restricted-modules.js +2 -2
  77. package/lib/rules/no-return-await.js +1 -1
  78. package/lib/rules/no-sequences.js +1 -0
  79. package/lib/rules/no-trailing-spaces.js +2 -3
  80. package/lib/rules/no-unneeded-ternary.js +1 -1
  81. package/lib/rules/no-unsafe-optional-chaining.js +1 -1
  82. package/lib/rules/no-unused-private-class-members.js +1 -1
  83. package/lib/rules/no-unused-vars.js +6 -8
  84. package/lib/rules/no-useless-assignment.js +566 -0
  85. package/lib/rules/no-useless-backreference.js +1 -1
  86. package/lib/rules/object-curly-spacing.js +3 -3
  87. package/lib/rules/object-property-newline.js +1 -1
  88. package/lib/rules/one-var.js +5 -5
  89. package/lib/rules/padded-blocks.js +7 -7
  90. package/lib/rules/prefer-arrow-callback.js +3 -3
  91. package/lib/rules/prefer-reflect.js +1 -1
  92. package/lib/rules/prefer-regex-literals.js +1 -1
  93. package/lib/rules/prefer-template.js +1 -1
  94. package/lib/rules/radix.js +2 -2
  95. package/lib/rules/semi-style.js +1 -1
  96. package/lib/rules/sort-imports.js +1 -1
  97. package/lib/rules/sort-keys.js +1 -1
  98. package/lib/rules/sort-vars.js +1 -1
  99. package/lib/rules/space-unary-ops.js +1 -1
  100. package/lib/rules/strict.js +1 -1
  101. package/lib/rules/utils/ast-utils.js +7 -7
  102. package/lib/rules/yield-star-spacing.js +1 -1
  103. package/lib/shared/types.js +1 -1
  104. package/lib/source-code/source-code.js +5 -83
  105. package/lib/source-code/token-store/index.js +2 -2
  106. package/lib/unsupported-api.js +3 -5
  107. package/package.json +12 -14
  108. package/conf/config-schema.js +0 -93
  109. package/lib/cli-engine/formatters/checkstyle.js +0 -60
  110. package/lib/cli-engine/formatters/compact.js +0 -60
  111. package/lib/cli-engine/formatters/jslint-xml.js +0 -41
  112. package/lib/cli-engine/formatters/junit.js +0 -82
  113. package/lib/cli-engine/formatters/tap.js +0 -95
  114. package/lib/cli-engine/formatters/unix.js +0 -58
  115. package/lib/cli-engine/formatters/visualstudio.js +0 -63
  116. package/lib/eslint/flat-eslint.js +0 -1142
  117. package/lib/rule-tester/flat-rule-tester.js +0 -1122
  118. package/lib/rules/require-jsdoc.js +0 -122
  119. package/lib/rules/valid-jsdoc.js +0 -516
  120. package/lib/shared/config-validator.js +0 -347
  121. package/lib/shared/relative-module-resolver.js +0 -50
@@ -16,6 +16,11 @@
16
16
  //------------------------------------------------------------------------------
17
17
 
18
18
  const escapeRegExp = require("escape-string-regexp");
19
+ const {
20
+ Legacy: {
21
+ ConfigOps
22
+ }
23
+ } = require("@eslint/eslintrc/universal");
19
24
 
20
25
  /**
21
26
  * Compares the locations of two objects in a source file
@@ -166,7 +171,7 @@ function createCommentRemoval(directives, commentToken) {
166
171
  return {
167
172
  description: ruleIds.length <= 2
168
173
  ? ruleIds.join(" or ")
169
- : `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds[ruleIds.length - 1]}`,
174
+ : `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds.at(-1)}`,
170
175
  fix: {
171
176
  range,
172
177
  text: " "
@@ -337,7 +342,7 @@ function applyDirectives(options) {
337
342
  problem.suppressions = problem.suppressions.concat(suppressions);
338
343
  } else {
339
344
  problem.suppressions = suppressions;
340
- usedDisableDirectives.add(disableDirectivesForProblem[disableDirectivesForProblem.length - 1]);
345
+ usedDisableDirectives.add(disableDirectivesForProblem.at(-1));
341
346
  }
342
347
  }
343
348
 
@@ -345,11 +350,11 @@ function applyDirectives(options) {
345
350
  }
346
351
 
347
352
  const unusedDisableDirectivesToReport = options.directives
348
- .filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive));
353
+ .filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive) && !options.rulesToIgnore.has(directive.ruleId));
349
354
 
350
355
 
351
356
  const unusedEnableDirectivesToReport = new Set(
352
- options.directives.filter(directive => directive.unprocessedDirective.type === "enable")
357
+ options.directives.filter(directive => directive.unprocessedDirective.type === "enable" && !options.rulesToIgnore.has(directive.ruleId))
353
358
  );
354
359
 
355
360
  /*
@@ -410,11 +415,13 @@ function applyDirectives(options) {
410
415
  * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
411
416
  * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
412
417
  * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
418
+ * @param {Object} options.configuredRules The rules configuration.
419
+ * @param {Function} options.ruleFilter A predicate function to filter which rules should be executed.
413
420
  * @param {boolean} options.disableFixes If true, it doesn't make `fix` properties.
414
421
  * @returns {{ruleId: (string|null), line: number, column: number, suppressions?: {kind: string, justification: string}}[]}
415
422
  * An object with a list of reported problems, the suppressed of which contain the suppression information.
416
423
  */
417
- module.exports = ({ directives, disableFixes, problems, reportUnusedDisableDirectives = "off" }) => {
424
+ module.exports = ({ directives, disableFixes, problems, configuredRules, ruleFilter, reportUnusedDisableDirectives = "off" }) => {
418
425
  const blockDirectives = directives
419
426
  .filter(directive => directive.type === "disable" || directive.type === "enable")
420
427
  .map(directive => Object.assign({}, directive, { unprocessedDirective: directive }))
@@ -443,17 +450,38 @@ module.exports = ({ directives, disableFixes, problems, reportUnusedDisableDirec
443
450
  }
444
451
  }).sort(compareLocations);
445
452
 
453
+ // This determines a list of rules that are not being run by the given ruleFilter, if present.
454
+ const rulesToIgnore = configuredRules && ruleFilter
455
+ ? new Set(Object.keys(configuredRules).filter(ruleId => {
456
+ const severity = ConfigOps.getRuleSeverity(configuredRules[ruleId]);
457
+
458
+ // Ignore for disabled rules.
459
+ if (severity === 0) {
460
+ return false;
461
+ }
462
+
463
+ return !ruleFilter({ severity, ruleId });
464
+ }))
465
+ : new Set();
466
+
467
+ // If no ruleId is supplied that means this directive is applied to all rules, so we can't determine if it's unused if any rules are filtered out.
468
+ if (rulesToIgnore.size > 0) {
469
+ rulesToIgnore.add(null);
470
+ }
471
+
446
472
  const blockDirectivesResult = applyDirectives({
447
473
  problems,
448
474
  directives: blockDirectives,
449
475
  disableFixes,
450
- reportUnusedDisableDirectives
476
+ reportUnusedDisableDirectives,
477
+ rulesToIgnore
451
478
  });
452
479
  const lineDirectivesResult = applyDirectives({
453
480
  problems: blockDirectivesResult.problems,
454
481
  directives: lineDirectives,
455
482
  disableFixes,
456
- reportUnusedDisableDirectives
483
+ reportUnusedDisableDirectives,
484
+ rulesToIgnore
457
485
  });
458
486
 
459
487
  return reportUnusedDisableDirectives !== "off"
@@ -125,20 +125,6 @@ class CodePath {
125
125
  return this.internal.thrownForkContext;
126
126
  }
127
127
 
128
- /**
129
- * Tracks the traversal of the code path through each segment. This array
130
- * starts empty and segments are added or removed as the code path is
131
- * traversed. This array always ends up empty at the end of a code path
132
- * traversal. The `CodePathState` uses this to track its progress through
133
- * the code path.
134
- * This is a passthrough to the underlying `CodePathState`.
135
- * @type {CodePathSegment[]}
136
- * @deprecated
137
- */
138
- get currentSegments() {
139
- return this.internal.currentSegments;
140
- }
141
-
142
128
  /**
143
129
  * Traverses all segments in this code path.
144
130
  *
@@ -180,9 +166,9 @@ class CodePath {
180
166
  const lastSegment = resolvedOptions.last;
181
167
 
182
168
  // set up initial location information
183
- let record = null;
184
- let index = 0;
185
- let end = 0;
169
+ let record;
170
+ let index;
171
+ let end;
186
172
  let segment = null;
187
173
 
188
174
  // segments that have already been visited during traversal
@@ -210,7 +196,7 @@ class CodePath {
210
196
  if (stack.length <= 1) {
211
197
  broken = true;
212
198
  } else {
213
- skippedSegment = stack[stack.length - 2][0];
199
+ skippedSegment = stack.at(-2)[0];
214
200
  }
215
201
  },
216
202
 
@@ -251,7 +237,7 @@ class CodePath {
251
237
  * Otherwise, we just read the value and sometimes modify the
252
238
  * record as we traverse.
253
239
  */
254
- record = stack[stack.length - 1];
240
+ record = stack.at(-1);
255
241
  segment = record[0];
256
242
  index = record[1];
257
243
 
@@ -207,7 +207,7 @@ class ForkContext {
207
207
  get head() {
208
208
  const list = this.segmentsList;
209
209
 
210
- return list.length === 0 ? [] : list[list.length - 1];
210
+ return list.length === 0 ? [] : list.at(-1);
211
211
  }
212
212
 
213
213
  /**
@@ -40,7 +40,7 @@ module.exports = class ConfigCommentParser {
40
40
 
41
41
  /**
42
42
  * Parses a list of "name:string_value" or/and "name" options divided by comma or
43
- * whitespace. Used for "global" and "exported" comments.
43
+ * whitespace. Used for "global" comments.
44
44
  * @param {string} string The string to parse.
45
45
  * @param {Comment} comment The comment node which has the string.
46
46
  * @returns {Object} Result map object of names and string values, or null values if no value was provided
@@ -75,11 +75,9 @@ module.exports = class ConfigCommentParser {
75
75
  parseJsonConfig(string, location) {
76
76
  debug("Parsing JSON config");
77
77
 
78
- let items = {};
79
-
80
78
  // Parses a JSON-like comment by the same way as parsing CLI option.
81
79
  try {
82
- items = levn.parse("Object", string) || {};
80
+ const items = levn.parse("Object", string) || {};
83
81
 
84
82
  // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
85
83
  // Also, commaless notations have invalid severity:
@@ -102,11 +100,15 @@ module.exports = class ConfigCommentParser {
102
100
  * Optionator cannot parse commaless notations.
103
101
  * But we are supporting that. So this is a fallback for that.
104
102
  */
105
- items = {};
106
103
  const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
107
104
 
108
105
  try {
109
- items = JSON.parse(`{${normalizedString}}`);
106
+ const items = JSON.parse(`{${normalizedString}}`);
107
+
108
+ return {
109
+ success: true,
110
+ config: items
111
+ };
110
112
  } catch (ex) {
111
113
  debug("Manual parsing failed.");
112
114
 
@@ -124,11 +126,6 @@ module.exports = class ConfigCommentParser {
124
126
  };
125
127
 
126
128
  }
127
-
128
- return {
129
- success: true,
130
- config: items
131
- };
132
129
  }
133
130
 
134
131
  /**