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.
- package/README.md +18 -13
- package/bin/eslint.js +38 -5
- package/conf/rule-type-list.json +25 -33
- package/lib/api.js +29 -1
- package/lib/cli-engine/cli-engine.js +2 -2
- package/lib/cli-engine/lint-result-cache.js +18 -6
- package/lib/cli.js +36 -6
- package/lib/config/flat-config-schema.js +124 -61
- package/lib/config/rule-validator.js +2 -1
- package/lib/eslint/eslint-helpers.js +9 -11
- package/lib/eslint/eslint.js +7 -0
- package/lib/eslint/flat-eslint.js +33 -18
- package/lib/linter/apply-disable-directives.js +127 -13
- package/lib/linter/code-path-analysis/code-path-analyzer.js +32 -24
- package/lib/linter/code-path-analysis/code-path-segment.js +52 -24
- package/lib/linter/code-path-analysis/code-path-state.js +1108 -243
- package/lib/linter/code-path-analysis/code-path.js +128 -33
- package/lib/linter/code-path-analysis/fork-context.js +173 -72
- package/lib/linter/config-comment-parser.js +36 -2
- package/lib/linter/linter.js +183 -82
- package/lib/options.js +24 -3
- package/lib/rule-tester/flat-rule-tester.js +113 -25
- package/lib/rule-tester/rule-tester.js +176 -23
- package/lib/rules/array-bracket-newline.js +3 -0
- package/lib/rules/array-bracket-spacing.js +3 -0
- package/lib/rules/array-callback-return.js +175 -25
- package/lib/rules/array-element-newline.js +3 -0
- package/lib/rules/arrow-parens.js +3 -0
- package/lib/rules/arrow-spacing.js +3 -0
- package/lib/rules/block-spacing.js +3 -0
- package/lib/rules/brace-style.js +3 -0
- package/lib/rules/comma-dangle.js +3 -0
- package/lib/rules/comma-spacing.js +3 -0
- package/lib/rules/comma-style.js +3 -0
- package/lib/rules/computed-property-spacing.js +3 -0
- package/lib/rules/consistent-return.js +32 -7
- package/lib/rules/constructor-super.js +37 -14
- package/lib/rules/dot-location.js +3 -0
- package/lib/rules/eol-last.js +3 -0
- package/lib/rules/for-direction.js +38 -24
- package/lib/rules/func-call-spacing.js +3 -0
- package/lib/rules/function-call-argument-newline.js +3 -0
- package/lib/rules/function-paren-newline.js +3 -0
- package/lib/rules/generator-star-spacing.js +3 -0
- package/lib/rules/getter-return.js +33 -8
- package/lib/rules/implicit-arrow-linebreak.js +3 -0
- package/lib/rules/indent.js +3 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/jsx-quotes.js +3 -0
- package/lib/rules/key-spacing.js +3 -0
- package/lib/rules/keyword-spacing.js +3 -0
- package/lib/rules/linebreak-style.js +3 -0
- package/lib/rules/lines-around-comment.js +3 -0
- package/lib/rules/lines-between-class-members.js +95 -7
- package/lib/rules/logical-assignment-operators.js +31 -3
- package/lib/rules/max-len.js +3 -0
- package/lib/rules/max-statements-per-line.js +3 -0
- package/lib/rules/multiline-ternary.js +3 -0
- package/lib/rules/new-parens.js +3 -0
- package/lib/rules/newline-per-chained-call.js +3 -0
- package/lib/rules/no-array-constructor.js +85 -6
- package/lib/rules/no-confusing-arrow.js +3 -0
- package/lib/rules/no-console.js +74 -2
- package/lib/rules/no-extra-parens.js +3 -0
- package/lib/rules/no-extra-semi.js +3 -0
- package/lib/rules/no-fallthrough.js +42 -14
- package/lib/rules/no-floating-decimal.js +3 -0
- package/lib/rules/no-invalid-this.js +1 -1
- package/lib/rules/no-misleading-character-class.js +65 -15
- package/lib/rules/no-mixed-operators.js +3 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +3 -0
- package/lib/rules/no-multi-spaces.js +3 -0
- package/lib/rules/no-multiple-empty-lines.js +3 -0
- package/lib/rules/no-new-object.js +7 -0
- package/lib/rules/no-object-constructor.js +117 -0
- package/lib/rules/no-promise-executor-return.js +157 -16
- package/lib/rules/no-prototype-builtins.js +90 -2
- package/lib/rules/no-restricted-imports.js +54 -31
- package/lib/rules/no-restricted-properties.js +15 -28
- package/lib/rules/no-tabs.js +3 -0
- package/lib/rules/no-this-before-super.js +38 -11
- package/lib/rules/no-trailing-spaces.js +3 -0
- package/lib/rules/no-unreachable-loop.js +47 -12
- package/lib/rules/no-unreachable.js +39 -10
- package/lib/rules/no-useless-return.js +35 -4
- package/lib/rules/no-whitespace-before-property.js +3 -0
- package/lib/rules/nonblock-statement-body-position.js +3 -0
- package/lib/rules/object-curly-newline.js +3 -0
- package/lib/rules/object-curly-spacing.js +3 -0
- package/lib/rules/object-property-newline.js +3 -0
- package/lib/rules/one-var-declaration-per-line.js +3 -0
- package/lib/rules/operator-linebreak.js +3 -0
- package/lib/rules/padded-blocks.js +3 -0
- package/lib/rules/padding-line-between-statements.js +3 -0
- package/lib/rules/quote-props.js +3 -0
- package/lib/rules/quotes.js +3 -0
- package/lib/rules/require-atomic-updates.js +21 -7
- package/lib/rules/rest-spread-spacing.js +3 -0
- package/lib/rules/semi-spacing.js +3 -0
- package/lib/rules/semi-style.js +3 -0
- package/lib/rules/semi.js +3 -0
- package/lib/rules/space-before-blocks.js +3 -0
- package/lib/rules/space-before-function-paren.js +3 -0
- package/lib/rules/space-in-parens.js +3 -0
- package/lib/rules/space-infix-ops.js +3 -0
- package/lib/rules/space-unary-ops.js +3 -0
- package/lib/rules/spaced-comment.js +3 -0
- package/lib/rules/switch-colon-spacing.js +3 -0
- package/lib/rules/template-curly-spacing.js +3 -0
- package/lib/rules/template-tag-spacing.js +3 -0
- package/lib/rules/utils/ast-utils.js +111 -1
- package/lib/rules/wrap-iife.js +3 -0
- package/lib/rules/wrap-regex.js +3 -0
- package/lib/rules/yield-star-spacing.js +3 -0
- package/lib/shared/severity.js +49 -0
- package/lib/source-code/source-code.js +329 -3
- package/messages/eslintrc-incompat.js +1 -1
- 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
|
};
|
package/lib/linter/linter.js
CHANGED
@@ -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 {
|
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(
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
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
|
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",
|