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
@@ -15,7 +15,10 @@ const levn = require("levn"),
15
15
  Legacy: {
16
16
  ConfigOps
17
17
  }
18
- } = require("@eslint/eslintrc/universal");
18
+ } = require("@eslint/eslintrc/universal"),
19
+ {
20
+ directivesPattern
21
+ } = require("../shared/directives");
19
22
 
20
23
  const debug = require("debug")("eslint:config-comment-parser");
21
24
 
@@ -139,7 +142,7 @@ module.exports = class ConfigCommentParser {
139
142
  const items = {};
140
143
 
141
144
  string.split(",").forEach(name => {
142
- const trimmedName = name.trim();
145
+ const trimmedName = name.trim().replace(/^(?<quote>['"]?)(?<ruleId>.*)\k<quote>$/us, "$<ruleId>");
143
146
 
144
147
  if (trimmedName) {
145
148
  items[trimmedName] = true;
@@ -148,4 +151,35 @@ module.exports = class ConfigCommentParser {
148
151
  return items;
149
152
  }
150
153
 
154
+ /**
155
+ * Extract the directive and the justification from a given directive comment and trim them.
156
+ * @param {string} value The comment text to extract.
157
+ * @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
158
+ */
159
+ extractDirectiveComment(value) {
160
+ const match = /\s-{2,}\s/u.exec(value);
161
+
162
+ if (!match) {
163
+ return { directivePart: value.trim(), justificationPart: "" };
164
+ }
165
+
166
+ const directive = value.slice(0, match.index).trim();
167
+ const justification = value.slice(match.index + match[0].length).trim();
168
+
169
+ return { directivePart: directive, justificationPart: justification };
170
+ }
171
+
172
+ /**
173
+ * Parses a directive comment into directive text and value.
174
+ * @param {Comment} comment The comment node with the directive to be parsed.
175
+ * @returns {{directiveText: string, directiveValue: string}} The directive text and value.
176
+ */
177
+ parseDirective(comment) {
178
+ const { directivePart } = this.extractDirectiveComment(comment.value);
179
+ const match = directivesPattern.exec(directivePart);
180
+ const directiveText = match[1];
181
+ const directiveValue = directivePart.slice(match.index + directiveText.length);
182
+
183
+ return { directiveText, directiveValue };
184
+ }
151
185
  };
@@ -42,7 +42,9 @@ const
42
42
  ruleReplacements = require("../../conf/replacements.json");
43
43
  const { getRuleFromConfig } = require("../config/flat-config-helpers");
44
44
  const { FlatConfigArray } = require("../config/flat-config-array");
45
-
45
+ const { RuleValidator } = require("../config/rule-validator");
46
+ const { assertIsRuleOptions, assertIsRuleSeverity } = require("../config/flat-config-schema");
47
+ const { normalizeSeverityToString } = require("../shared/severity");
46
48
  const debug = require("debug")("eslint:linter");
47
49
  const MAX_AUTOFIX_PASSES = 10;
48
50
  const DEFAULT_PARSER_NAME = "espree";
@@ -50,7 +52,6 @@ const DEFAULT_ECMA_VERSION = 5;
50
52
  const commentParser = new ConfigCommentParser();
51
53
  const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } };
52
54
  const parserSymbol = Symbol.for("eslint.RuleTester.parser");
53
- const globals = require("../../conf/globals");
54
55
 
55
56
  //------------------------------------------------------------------------------
56
57
  // Typedefs
@@ -145,29 +146,6 @@ function isEspree(parser) {
145
146
  return !!(parser === espree || parser[parserSymbol] === espree);
146
147
  }
147
148
 
148
- /**
149
- * Retrieves globals for the given ecmaVersion.
150
- * @param {number} ecmaVersion The version to retrieve globals for.
151
- * @returns {Object} The globals for the given ecmaVersion.
152
- */
153
- function getGlobalsForEcmaVersion(ecmaVersion) {
154
-
155
- switch (ecmaVersion) {
156
- case 3:
157
- return globals.es3;
158
-
159
- case 5:
160
- return globals.es5;
161
-
162
- default:
163
- if (ecmaVersion < 2015) {
164
- return globals[`es${ecmaVersion + 2009}`];
165
- }
166
-
167
- return globals[`es${ecmaVersion}`];
168
- }
169
- }
170
-
171
149
  /**
172
150
  * Ensures that variables representing built-in properties of the Global Object,
173
151
  * and any globals declared by special block comments, are present in the global
@@ -339,35 +317,17 @@ function createDisableDirectives(options) {
339
317
  return result;
340
318
  }
341
319
 
342
- /**
343
- * Extract the directive and the justification from a given directive comment and trim them.
344
- * @param {string} value The comment text to extract.
345
- * @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
346
- */
347
- function extractDirectiveComment(value) {
348
- const match = /\s-{2,}\s/u.exec(value);
349
-
350
- if (!match) {
351
- return { directivePart: value.trim(), justificationPart: "" };
352
- }
353
-
354
- const directive = value.slice(0, match.index).trim();
355
- const justification = value.slice(match.index + match[0].length).trim();
356
-
357
- return { directivePart: directive, justificationPart: justification };
358
- }
359
-
360
320
  /**
361
321
  * Parses comments in file to extract file-specific config of rules, globals
362
322
  * and environments and merges them with global config; also code blocks
363
323
  * where reporting is disabled or enabled and merges them with reporting config.
364
- * @param {ASTNode} ast The top node of the AST.
324
+ * @param {SourceCode} sourceCode The SourceCode object to get comments from.
365
325
  * @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
366
326
  * @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from.
367
327
  * @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: LintMessage[], disableDirectives: DisableDirective[]}}
368
328
  * A collection of the directive comments that were found, along with any problems that occurred when parsing
369
329
  */
370
- function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
330
+ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig) {
371
331
  const configuredRules = {};
372
332
  const enabledGlobals = Object.create(null);
373
333
  const exportedVariables = {};
@@ -377,8 +337,8 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
377
337
  builtInRules: Rules
378
338
  });
379
339
 
380
- ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
381
- const { directivePart, justificationPart } = extractDirectiveComment(comment.value);
340
+ sourceCode.getInlineConfigNodes().filter(token => token.type !== "Shebang").forEach(comment => {
341
+ const { directivePart, justificationPart } = commentParser.extractDirectiveComment(comment.value);
382
342
 
383
343
  const match = directivesPattern.exec(directivePart);
384
344
 
@@ -511,6 +471,69 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
511
471
  };
512
472
  }
513
473
 
474
+ /**
475
+ * Parses comments in file to extract disable directives.
476
+ * @param {SourceCode} sourceCode The SourceCode object to get comments from.
477
+ * @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
478
+ * @returns {{problems: LintMessage[], disableDirectives: DisableDirective[]}}
479
+ * A collection of the directive comments that were found, along with any problems that occurred when parsing
480
+ */
481
+ function getDirectiveCommentsForFlatConfig(sourceCode, ruleMapper) {
482
+ const problems = [];
483
+ const disableDirectives = [];
484
+
485
+ sourceCode.getInlineConfigNodes().filter(token => token.type !== "Shebang").forEach(comment => {
486
+ const { directivePart, justificationPart } = commentParser.extractDirectiveComment(comment.value);
487
+
488
+ const match = directivesPattern.exec(directivePart);
489
+
490
+ if (!match) {
491
+ return;
492
+ }
493
+ const directiveText = match[1];
494
+ const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText);
495
+
496
+ if (comment.type === "Line" && !lineCommentSupported) {
497
+ return;
498
+ }
499
+
500
+ if (directiveText === "eslint-disable-line" && comment.loc.start.line !== comment.loc.end.line) {
501
+ const message = `${directiveText} comment should not span multiple lines.`;
502
+
503
+ problems.push(createLintingProblem({
504
+ ruleId: null,
505
+ message,
506
+ loc: comment.loc
507
+ }));
508
+ return;
509
+ }
510
+
511
+ const directiveValue = directivePart.slice(match.index + directiveText.length);
512
+
513
+ switch (directiveText) {
514
+ case "eslint-disable":
515
+ case "eslint-enable":
516
+ case "eslint-disable-next-line":
517
+ case "eslint-disable-line": {
518
+ const directiveType = directiveText.slice("eslint-".length);
519
+ const options = { commentToken: comment, type: directiveType, value: directiveValue, justification: justificationPart, ruleMapper };
520
+ const { directives, directiveProblems } = createDisableDirectives(options);
521
+
522
+ disableDirectives.push(...directives);
523
+ problems.push(...directiveProblems);
524
+ break;
525
+ }
526
+
527
+ // no default
528
+ }
529
+ });
530
+
531
+ return {
532
+ problems,
533
+ disableDirectives
534
+ };
535
+ }
536
+
514
537
  /**
515
538
  * Normalize ECMAScript version from the initial config
516
539
  * @param {Parser} parser The parser which uses this options.
@@ -580,7 +603,7 @@ function findEslintEnv(text) {
580
603
  if (match[0].endsWith("*/")) {
581
604
  retv = Object.assign(
582
605
  retv || {},
583
- commentParser.parseListConfig(extractDirectiveComment(match[1]).directivePart)
606
+ commentParser.parseListConfig(commentParser.extractDirectiveComment(match[1]).directivePart)
584
607
  );
585
608
  }
586
609
  }
@@ -631,9 +654,11 @@ function normalizeVerifyOptions(providedOptions, config) {
631
654
  reportUnusedDisableDirectives = reportUnusedDisableDirectives ? "error" : "off";
632
655
  }
633
656
  if (typeof reportUnusedDisableDirectives !== "string") {
634
- reportUnusedDisableDirectives =
635
- linterOptions.reportUnusedDisableDirectives
636
- ? "warn" : "off";
657
+ if (typeof linterOptions.reportUnusedDisableDirectives === "boolean") {
658
+ reportUnusedDisableDirectives = linterOptions.reportUnusedDisableDirectives ? "warn" : "off";
659
+ } else {
660
+ reportUnusedDisableDirectives = linterOptions.reportUnusedDisableDirectives === void 0 ? "off" : normalizeSeverityToString(linterOptions.reportUnusedDisableDirectives);
661
+ }
637
662
  }
638
663
 
639
664
  return {
@@ -898,6 +923,7 @@ const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
898
923
  getTokensBetween: "getTokensBetween"
899
924
  };
900
925
 
926
+
901
927
  const BASE_TRAVERSAL_CONTEXT = Object.freeze(
902
928
  Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce(
903
929
  (contextInfo, methodName) =>
@@ -1312,7 +1338,7 @@ class Linter {
1312
1338
 
1313
1339
  const sourceCode = slots.lastSourceCode;
1314
1340
  const commentDirectives = options.allowInlineConfig
1315
- ? getDirectiveComments(sourceCode.ast, ruleId => getRule(slots, ruleId), options.warnInlineConfig)
1341
+ ? getDirectiveComments(sourceCode, ruleId => getRule(slots, ruleId), options.warnInlineConfig)
1316
1342
  : { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
1317
1343
 
1318
1344
  // augment global scope with declared global variables
@@ -1323,7 +1349,6 @@ class Linter {
1323
1349
  );
1324
1350
 
1325
1351
  const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules);
1326
-
1327
1352
  let lintingProblems;
1328
1353
 
1329
1354
  try {
@@ -1382,7 +1407,7 @@ class Linter {
1382
1407
  verify(textOrSourceCode, config, filenameOrOptions) {
1383
1408
  debug("Verify");
1384
1409
 
1385
- const { configType } = internalSlotsMap.get(this);
1410
+ const { configType, cwd } = internalSlotsMap.get(this);
1386
1411
 
1387
1412
  const options = typeof filenameOrOptions === "string"
1388
1413
  ? { filename: filenameOrOptions }
@@ -1401,7 +1426,7 @@ class Linter {
1401
1426
  let configArray = config;
1402
1427
 
1403
1428
  if (!Array.isArray(config) || typeof config.getConfig !== "function") {
1404
- configArray = new FlatConfigArray(config);
1429
+ configArray = new FlatConfigArray(config, { basePath: cwd });
1405
1430
  configArray.normalizeSync();
1406
1431
  }
1407
1432
 
@@ -1539,19 +1564,6 @@ class Linter {
1539
1564
  languageOptions.ecmaVersion
1540
1565
  );
1541
1566
 
1542
- /*
1543
- * add configured globals and language globals
1544
- *
1545
- * using Object.assign instead of object spread for performance reasons
1546
- * https://github.com/eslint/eslint/issues/16302
1547
- */
1548
- const configuredGlobals = Object.assign(
1549
- {},
1550
- getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
1551
- languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
1552
- languageOptions.globals
1553
- );
1554
-
1555
1567
  // double check that there is a parser to avoid mysterious error messages
1556
1568
  if (!languageOptions.parser) {
1557
1569
  throw new TypeError(`No parser specified for ${options.filename}`);
@@ -1607,25 +1619,113 @@ class Linter {
1607
1619
  }
1608
1620
 
1609
1621
  const sourceCode = slots.lastSourceCode;
1610
- const commentDirectives = options.allowInlineConfig
1611
- ? getDirectiveComments(
1612
- sourceCode.ast,
1613
- ruleId => getRuleFromConfig(ruleId, config),
1614
- options.warnInlineConfig
1615
- )
1616
- : { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
1617
1622
 
1618
- // augment global scope with declared global variables
1619
- addDeclaredGlobals(
1620
- sourceCode.scopeManager.scopes[0],
1621
- configuredGlobals,
1622
- { exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals }
1623
- );
1623
+ /*
1624
+ * Make adjustments based on the language options. For JavaScript,
1625
+ * this is primarily about adding variables into the global scope
1626
+ * to account for ecmaVersion and configured globals.
1627
+ */
1628
+ sourceCode.applyLanguageOptions(languageOptions);
1624
1629
 
1625
- const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules);
1630
+ const mergedInlineConfig = {
1631
+ rules: {}
1632
+ };
1633
+ const inlineConfigProblems = [];
1626
1634
 
1635
+ /*
1636
+ * Inline config can be either enabled or disabled. If disabled, it's possible
1637
+ * to detect the inline config and emit a warning (though this is not required).
1638
+ * So we first check to see if inline config is allowed at all, and if so, we
1639
+ * need to check if it's a warning or not.
1640
+ */
1641
+ if (options.allowInlineConfig) {
1642
+
1643
+ // if inline config should warn then add the warnings
1644
+ if (options.warnInlineConfig) {
1645
+ sourceCode.getInlineConfigNodes().forEach(node => {
1646
+ inlineConfigProblems.push(createLintingProblem({
1647
+ ruleId: null,
1648
+ message: `'${sourceCode.text.slice(node.range[0], node.range[1])}' has no effect because you have 'noInlineConfig' setting in ${options.warnInlineConfig}.`,
1649
+ loc: node.loc,
1650
+ severity: 1
1651
+ }));
1652
+
1653
+ });
1654
+ } else {
1655
+ const inlineConfigResult = sourceCode.applyInlineConfig();
1656
+
1657
+ inlineConfigProblems.push(
1658
+ ...inlineConfigResult.problems
1659
+ .map(createLintingProblem)
1660
+ .map(problem => {
1661
+ problem.fatal = true;
1662
+ return problem;
1663
+ })
1664
+ );
1665
+
1666
+ // next we need to verify information about the specified rules
1667
+ const ruleValidator = new RuleValidator();
1668
+
1669
+ for (const { config: inlineConfig, node } of inlineConfigResult.configs) {
1670
+
1671
+ Object.keys(inlineConfig.rules).forEach(ruleId => {
1672
+ const rule = getRuleFromConfig(ruleId, config);
1673
+ const ruleValue = inlineConfig.rules[ruleId];
1674
+
1675
+ if (!rule) {
1676
+ inlineConfigProblems.push(createLintingProblem({ ruleId, loc: node.loc }));
1677
+ return;
1678
+ }
1679
+
1680
+ try {
1681
+
1682
+ const ruleOptions = Array.isArray(ruleValue) ? ruleValue : [ruleValue];
1683
+
1684
+ assertIsRuleOptions(ruleId, ruleValue);
1685
+ assertIsRuleSeverity(ruleId, ruleOptions[0]);
1686
+
1687
+ ruleValidator.validate({
1688
+ plugins: config.plugins,
1689
+ rules: {
1690
+ [ruleId]: ruleOptions
1691
+ }
1692
+ });
1693
+ mergedInlineConfig.rules[ruleId] = ruleValue;
1694
+ } catch (err) {
1695
+
1696
+ let baseMessage = err.message.slice(
1697
+ err.message.startsWith("Key \"rules\":")
1698
+ ? err.message.indexOf(":", 12) + 1
1699
+ : err.message.indexOf(":") + 1
1700
+ ).trim();
1701
+
1702
+ if (err.messageTemplate) {
1703
+ baseMessage += ` You passed "${ruleValue}".`;
1704
+ }
1705
+
1706
+ inlineConfigProblems.push(createLintingProblem({
1707
+ ruleId,
1708
+ message: `Inline configuration for rule "${ruleId}" is invalid:\n\t${baseMessage}\n`,
1709
+ loc: node.loc
1710
+ }));
1711
+ }
1712
+ });
1713
+ }
1714
+ }
1715
+ }
1716
+
1717
+ const commentDirectives = options.allowInlineConfig && !options.warnInlineConfig
1718
+ ? getDirectiveCommentsForFlatConfig(
1719
+ sourceCode,
1720
+ ruleId => getRuleFromConfig(ruleId, config)
1721
+ )
1722
+ : { problems: [], disableDirectives: [] };
1723
+
1724
+ const configuredRules = Object.assign({}, config.rules, mergedInlineConfig.rules);
1627
1725
  let lintingProblems;
1628
1726
 
1727
+ sourceCode.finalize();
1728
+
1629
1729
  try {
1630
1730
  lintingProblems = runRules(
1631
1731
  sourceCode,
@@ -1666,6 +1766,7 @@ class Linter {
1666
1766
  disableFixes: options.disableFixes,
1667
1767
  problems: lintingProblems
1668
1768
  .concat(commentDirectives.problems)
1769
+ .concat(inlineConfigProblems)
1669
1770
  .sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
1670
1771
  reportUnusedDisableDirectives: options.reportUnusedDisableDirectives
1671
1772
  });
package/lib/options.js CHANGED
@@ -47,7 +47,8 @@ const optionator = require("optionator");
47
47
  * @property {Object} [parserOptions] Specify parser options
48
48
  * @property {string[]} [plugin] Specify plugins
49
49
  * @property {string} [printConfig] Print the configuration for the given file
50
- * @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable directives
50
+ * @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable and eslint-enable directives
51
+ * @property {string | undefined} reportUnusedDisableDirectivesSeverity A severity string indicating if and how unused disable and enable directives should be tracked and reported.
51
52
  * @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default
52
53
  * @property {Object} [rule] Specify rules
53
54
  * @property {string[]} [rulesdir] Load additional rules from this directory. Deprecated: Use rules from plugins
@@ -55,6 +56,7 @@ const optionator = require("optionator");
55
56
  * @property {string} [stdinFilename] Specify filename to process STDIN as
56
57
  * @property {boolean} quiet Report errors only
57
58
  * @property {boolean} [version] Output the version number
59
+ * @property {boolean} warnIgnored Show warnings when the file list includes ignored files
58
60
  * @property {string[]} _ Positional filenames or patterns
59
61
  */
60
62
 
@@ -139,6 +141,17 @@ module.exports = function(usingFlatConfig) {
139
141
  };
140
142
  }
141
143
 
144
+ let warnIgnoredFlag;
145
+
146
+ if (usingFlatConfig) {
147
+ warnIgnoredFlag = {
148
+ option: "warn-ignored",
149
+ type: "Boolean",
150
+ default: "true",
151
+ description: "Suppress warnings when the file list includes ignored files"
152
+ };
153
+ }
154
+
142
155
  return optionator({
143
156
  prepend: "eslint [options] file.js [file.js] [dir]",
144
157
  defaults: {
@@ -155,7 +168,7 @@ module.exports = function(usingFlatConfig) {
155
168
  alias: "c",
156
169
  type: "path::String",
157
170
  description: usingFlatConfig
158
- ? "Use this configuration instead of eslint.config.js"
171
+ ? "Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs"
159
172
  : "Use this configuration, overriding .eslintrc.* config options if present"
160
173
  },
161
174
  envFlag,
@@ -292,7 +305,14 @@ module.exports = function(usingFlatConfig) {
292
305
  option: "report-unused-disable-directives",
293
306
  type: "Boolean",
294
307
  default: void 0,
295
- description: "Adds reported errors for unused eslint-disable directives"
308
+ description: "Adds reported errors for unused eslint-disable and eslint-enable directives"
309
+ },
310
+ {
311
+ option: "report-unused-disable-directives-severity",
312
+ type: "String",
313
+ default: void 0,
314
+ description: "Chooses severity level for reporting unused eslint-disable and eslint-enable directives",
315
+ enum: ["off", "warn", "error", "0", "1", "2"]
296
316
  },
297
317
  {
298
318
  heading: "Caching"
@@ -349,6 +369,7 @@ module.exports = function(usingFlatConfig) {
349
369
  default: "false",
350
370
  description: "Exit with exit code 2 in case of fatal error"
351
371
  },
372
+ warnIgnoredFlag,
352
373
  {
353
374
  option: "debug",
354
375
  type: "Boolean",