eslint 8.56.0 → 9.0.0-alpha.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 +2 -2
- package/conf/rule-type-list.json +3 -1
- package/lib/api.js +1 -1
- package/lib/cli-engine/cli-engine.js +13 -2
- package/lib/cli-engine/formatters/formatters-meta.json +1 -29
- package/lib/cli.js +32 -9
- package/lib/config/default-config.js +3 -0
- package/lib/config/flat-config-array.js +0 -20
- package/lib/config/flat-config-helpers.js +41 -20
- package/lib/config/flat-config-schema.js +35 -25
- package/lib/config/rule-validator.js +27 -4
- package/lib/eslint/eslint-helpers.js +32 -12
- package/lib/eslint/eslint.js +856 -373
- package/lib/eslint/index.js +2 -2
- package/lib/eslint/legacy-eslint.js +722 -0
- package/lib/linter/apply-disable-directives.js +33 -5
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +91 -96
- package/lib/linter/rules.js +6 -15
- package/lib/options.js +9 -1
- package/lib/rule-tester/rule-tester.js +240 -272
- package/lib/rules/index.js +0 -2
- package/lib/rules/no-constant-binary-expression.js +1 -1
- package/lib/rules/no-constructor-return.js +1 -1
- package/lib/rules/no-empty-static-block.js +1 -1
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-implicit-coercion.js +17 -1
- package/lib/rules/no-inner-declarations.js +1 -1
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
- package/lib/rules/no-new-native-nonconstructor.js +1 -1
- package/lib/rules/no-new-symbol.js +8 -1
- package/lib/rules/no-sequences.js +1 -0
- package/lib/rules/no-unused-private-class-members.js +1 -1
- package/lib/shared/config-validator.js +44 -11
- package/lib/shared/types.js +1 -1
- package/lib/source-code/source-code.js +1 -79
- package/lib/unsupported-api.js +3 -5
- package/package.json +9 -11
- package/lib/cli-engine/formatters/checkstyle.js +0 -60
- package/lib/cli-engine/formatters/compact.js +0 -60
- package/lib/cli-engine/formatters/jslint-xml.js +0 -41
- package/lib/cli-engine/formatters/junit.js +0 -82
- package/lib/cli-engine/formatters/tap.js +0 -95
- package/lib/cli-engine/formatters/unix.js +0 -58
- package/lib/cli-engine/formatters/visualstudio.js +0 -63
- package/lib/eslint/flat-eslint.js +0 -1142
- package/lib/rule-tester/flat-rule-tester.js +0 -1122
- package/lib/rules/require-jsdoc.js +0 -122
- package/lib/rules/valid-jsdoc.js +0 -516
@@ -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
|
@@ -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"
|
@@ -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"
|
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
|
package/lib/linter/linter.js
CHANGED
@@ -105,6 +105,7 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser");
|
|
105
105
|
* @property {string} [filename] the filename of the source code.
|
106
106
|
* @property {boolean | "off" | "warn" | "error"} [reportUnusedDisableDirectives] Adds reported errors for
|
107
107
|
* unused `eslint-disable` directives.
|
108
|
+
* @property {Function} [ruleFilter] A predicate function that determines whether a given rule should run.
|
108
109
|
*/
|
109
110
|
|
110
111
|
/**
|
@@ -392,7 +393,7 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig) {
|
|
392
393
|
}
|
393
394
|
|
394
395
|
case "exported":
|
395
|
-
Object.assign(exportedVariables, commentParser.
|
396
|
+
Object.assign(exportedVariables, commentParser.parseListConfig(directiveValue, comment));
|
396
397
|
break;
|
397
398
|
|
398
399
|
case "globals":
|
@@ -439,6 +440,15 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig) {
|
|
439
440
|
try {
|
440
441
|
validator.validateRuleOptions(rule, name, ruleValue);
|
441
442
|
} catch (err) {
|
443
|
+
|
444
|
+
/*
|
445
|
+
* If the rule has invalid `meta.schema`, throw the error because
|
446
|
+
* this is not an invalid inline configuration but an invalid rule.
|
447
|
+
*/
|
448
|
+
if (err.code === "ESLINT_INVALID_RULE_OPTIONS_SCHEMA") {
|
449
|
+
throw err;
|
450
|
+
}
|
451
|
+
|
442
452
|
problems.push(createLintingProblem({
|
443
453
|
ruleId: name,
|
444
454
|
message: err.message,
|
@@ -661,6 +671,12 @@ function normalizeVerifyOptions(providedOptions, config) {
|
|
661
671
|
}
|
662
672
|
}
|
663
673
|
|
674
|
+
let ruleFilter = providedOptions.ruleFilter;
|
675
|
+
|
676
|
+
if (typeof ruleFilter !== "function") {
|
677
|
+
ruleFilter = () => true;
|
678
|
+
}
|
679
|
+
|
664
680
|
return {
|
665
681
|
filename: normalizeFilename(providedOptions.filename || "<input>"),
|
666
682
|
allowInlineConfig: !ignoreInlineConfig,
|
@@ -668,7 +684,8 @@ function normalizeVerifyOptions(providedOptions, config) {
|
|
668
684
|
? `your config${configNameOfNoInlineConfig}`
|
669
685
|
: null,
|
670
686
|
reportUnusedDisableDirectives,
|
671
|
-
disableFixes: Boolean(providedOptions.disableFixes)
|
687
|
+
disableFixes: Boolean(providedOptions.disableFixes),
|
688
|
+
ruleFilter
|
672
689
|
};
|
673
690
|
}
|
674
691
|
|
@@ -885,12 +902,18 @@ function parse(text, languageOptions, filePath) {
|
|
885
902
|
|
886
903
|
/**
|
887
904
|
* Runs a rule, and gets its listeners
|
888
|
-
* @param {Rule} rule A
|
905
|
+
* @param {Rule} rule A rule object
|
889
906
|
* @param {Context} ruleContext The context that should be passed to the rule
|
907
|
+
* @throws {TypeError} If `rule` is not an object with a `create` method
|
890
908
|
* @throws {any} Any error during the rule's `create`
|
891
909
|
* @returns {Object} A map of selector listeners provided by the rule
|
892
910
|
*/
|
893
911
|
function createRuleListeners(rule, ruleContext) {
|
912
|
+
|
913
|
+
if (!rule || typeof rule !== "object" || typeof rule.create !== "function") {
|
914
|
+
throw new TypeError(`Error while loading rule '${ruleContext.id}': Rule must be an object with a \`create\` method`);
|
915
|
+
}
|
916
|
+
|
894
917
|
try {
|
895
918
|
return rule.create(ruleContext);
|
896
919
|
} catch (ex) {
|
@@ -899,43 +922,6 @@ function createRuleListeners(rule, ruleContext) {
|
|
899
922
|
}
|
900
923
|
}
|
901
924
|
|
902
|
-
// methods that exist on SourceCode object
|
903
|
-
const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
|
904
|
-
getSource: "getText",
|
905
|
-
getSourceLines: "getLines",
|
906
|
-
getAllComments: "getAllComments",
|
907
|
-
getNodeByRangeIndex: "getNodeByRangeIndex",
|
908
|
-
getComments: "getComments",
|
909
|
-
getCommentsBefore: "getCommentsBefore",
|
910
|
-
getCommentsAfter: "getCommentsAfter",
|
911
|
-
getCommentsInside: "getCommentsInside",
|
912
|
-
getJSDocComment: "getJSDocComment",
|
913
|
-
getFirstToken: "getFirstToken",
|
914
|
-
getFirstTokens: "getFirstTokens",
|
915
|
-
getLastToken: "getLastToken",
|
916
|
-
getLastTokens: "getLastTokens",
|
917
|
-
getTokenAfter: "getTokenAfter",
|
918
|
-
getTokenBefore: "getTokenBefore",
|
919
|
-
getTokenByRangeStart: "getTokenByRangeStart",
|
920
|
-
getTokens: "getTokens",
|
921
|
-
getTokensAfter: "getTokensAfter",
|
922
|
-
getTokensBefore: "getTokensBefore",
|
923
|
-
getTokensBetween: "getTokensBetween"
|
924
|
-
};
|
925
|
-
|
926
|
-
|
927
|
-
const BASE_TRAVERSAL_CONTEXT = Object.freeze(
|
928
|
-
Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce(
|
929
|
-
(contextInfo, methodName) =>
|
930
|
-
Object.assign(contextInfo, {
|
931
|
-
[methodName](...args) {
|
932
|
-
return this.sourceCode[DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]](...args);
|
933
|
-
}
|
934
|
-
}),
|
935
|
-
{}
|
936
|
-
)
|
937
|
-
);
|
938
|
-
|
939
925
|
/**
|
940
926
|
* Runs the given rules on the given SourceCode object
|
941
927
|
* @param {SourceCode} sourceCode A SourceCode object for the given text
|
@@ -948,9 +934,10 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(
|
|
948
934
|
* @param {boolean} disableFixes If true, it doesn't make `fix` properties.
|
949
935
|
* @param {string | undefined} cwd cwd of the cli
|
950
936
|
* @param {string} physicalFilename The full path of the file on disk without any code block information
|
937
|
+
* @param {Function} ruleFilter A predicate function to filter which rules should be executed.
|
951
938
|
* @returns {LintMessage[]} An array of reported problems
|
952
939
|
*/
|
953
|
-
function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageOptions, settings, filename, disableFixes, cwd, physicalFilename) {
|
940
|
+
function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageOptions, settings, filename, disableFixes, cwd, physicalFilename, ruleFilter) {
|
954
941
|
const emitter = createEmitter();
|
955
942
|
const nodeQueue = [];
|
956
943
|
let currentNode = sourceCode.ast;
|
@@ -972,30 +959,22 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
|
|
972
959
|
* properties once for each rule.
|
973
960
|
*/
|
974
961
|
const sharedTraversalContext = Object.freeze(
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
...languageOptions.parserOptions
|
992
|
-
},
|
993
|
-
parserPath: parserName,
|
994
|
-
languageOptions,
|
995
|
-
parserServices: sourceCode.parserServices,
|
996
|
-
settings
|
997
|
-
}
|
998
|
-
)
|
962
|
+
{
|
963
|
+
getCwd: () => cwd,
|
964
|
+
cwd,
|
965
|
+
getFilename: () => filename,
|
966
|
+
filename,
|
967
|
+
getPhysicalFilename: () => physicalFilename || filename,
|
968
|
+
physicalFilename: physicalFilename || filename,
|
969
|
+
getSourceCode: () => sourceCode,
|
970
|
+
sourceCode,
|
971
|
+
parserOptions: {
|
972
|
+
...languageOptions.parserOptions
|
973
|
+
},
|
974
|
+
parserPath: parserName,
|
975
|
+
languageOptions,
|
976
|
+
settings
|
977
|
+
}
|
999
978
|
);
|
1000
979
|
|
1001
980
|
const lintingProblems = [];
|
@@ -1008,6 +987,10 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
|
|
1008
987
|
return;
|
1009
988
|
}
|
1010
989
|
|
990
|
+
if (ruleFilter && !ruleFilter({ ruleId, severity })) {
|
991
|
+
return;
|
992
|
+
}
|
993
|
+
|
1011
994
|
const rule = ruleMapper(ruleId);
|
1012
995
|
|
1013
996
|
if (!rule) {
|
@@ -1217,9 +1200,9 @@ class Linter {
|
|
1217
1200
|
* Initialize the Linter.
|
1218
1201
|
* @param {Object} [config] the config object
|
1219
1202
|
* @param {string} [config.cwd] path to a directory that should be considered as the current working directory, can be undefined.
|
1220
|
-
* @param {"flat"|"eslintrc"} [config.configType="
|
1203
|
+
* @param {"flat"|"eslintrc"} [config.configType="flat"] the type of config used.
|
1221
1204
|
*/
|
1222
|
-
constructor({ cwd, configType } = {}) {
|
1205
|
+
constructor({ cwd, configType = "flat" } = {}) {
|
1223
1206
|
internalSlotsMap.set(this, {
|
1224
1207
|
cwd: normalizeCwd(cwd),
|
1225
1208
|
lastConfigArray: null,
|
@@ -1362,7 +1345,8 @@ class Linter {
|
|
1362
1345
|
options.filename,
|
1363
1346
|
options.disableFixes,
|
1364
1347
|
slots.cwd,
|
1365
|
-
providedOptions.physicalFilename
|
1348
|
+
providedOptions.physicalFilename,
|
1349
|
+
null
|
1366
1350
|
);
|
1367
1351
|
} catch (err) {
|
1368
1352
|
err.message += `\nOccurred while linting ${options.filename}`;
|
@@ -1413,29 +1397,29 @@ class Linter {
|
|
1413
1397
|
? { filename: filenameOrOptions }
|
1414
1398
|
: filenameOrOptions || {};
|
1415
1399
|
|
1416
|
-
|
1417
|
-
if (configType === "flat") {
|
1418
|
-
|
1419
|
-
/*
|
1420
|
-
* Because of how Webpack packages up the files, we can't
|
1421
|
-
* compare directly to `FlatConfigArray` using `instanceof`
|
1422
|
-
* because it's not the same `FlatConfigArray` as in the tests.
|
1423
|
-
* So, we work around it by assuming an array is, in fact, a
|
1424
|
-
* `FlatConfigArray` if it has a `getConfig()` method.
|
1425
|
-
*/
|
1426
|
-
let configArray = config;
|
1427
|
-
|
1428
|
-
if (!Array.isArray(config) || typeof config.getConfig !== "function") {
|
1429
|
-
configArray = new FlatConfigArray(config, { basePath: cwd });
|
1430
|
-
configArray.normalizeSync();
|
1431
|
-
}
|
1400
|
+
const configToUse = config ?? {};
|
1432
1401
|
|
1433
|
-
|
1434
|
-
|
1402
|
+
if (configType !== "eslintrc") {
|
1403
|
+
|
1404
|
+
/*
|
1405
|
+
* Because of how Webpack packages up the files, we can't
|
1406
|
+
* compare directly to `FlatConfigArray` using `instanceof`
|
1407
|
+
* because it's not the same `FlatConfigArray` as in the tests.
|
1408
|
+
* So, we work around it by assuming an array is, in fact, a
|
1409
|
+
* `FlatConfigArray` if it has a `getConfig()` method.
|
1410
|
+
*/
|
1411
|
+
let configArray = configToUse;
|
1435
1412
|
|
1436
|
-
if (typeof
|
1437
|
-
|
1413
|
+
if (!Array.isArray(configToUse) || typeof configToUse.getConfig !== "function") {
|
1414
|
+
configArray = new FlatConfigArray(configToUse, { basePath: cwd });
|
1415
|
+
configArray.normalizeSync();
|
1438
1416
|
}
|
1417
|
+
|
1418
|
+
return this._distinguishSuppressedMessages(this._verifyWithFlatConfigArray(textOrSourceCode, configArray, options, true));
|
1419
|
+
}
|
1420
|
+
|
1421
|
+
if (typeof configToUse.extractConfig === "function") {
|
1422
|
+
return this._distinguishSuppressedMessages(this._verifyWithConfigArray(textOrSourceCode, configToUse, options));
|
1439
1423
|
}
|
1440
1424
|
|
1441
1425
|
/*
|
@@ -1448,9 +1432,9 @@ class Linter {
|
|
1448
1432
|
* So we cannot apply multiple processors.
|
1449
1433
|
*/
|
1450
1434
|
if (options.preprocess || options.postprocess) {
|
1451
|
-
return this._distinguishSuppressedMessages(this._verifyWithProcessor(textOrSourceCode,
|
1435
|
+
return this._distinguishSuppressedMessages(this._verifyWithProcessor(textOrSourceCode, configToUse, options));
|
1452
1436
|
}
|
1453
|
-
return this._distinguishSuppressedMessages(this._verifyWithoutProcessors(textOrSourceCode,
|
1437
|
+
return this._distinguishSuppressedMessages(this._verifyWithoutProcessors(textOrSourceCode, configToUse, options));
|
1454
1438
|
}
|
1455
1439
|
|
1456
1440
|
/**
|
@@ -1693,6 +1677,14 @@ class Linter {
|
|
1693
1677
|
mergedInlineConfig.rules[ruleId] = ruleValue;
|
1694
1678
|
} catch (err) {
|
1695
1679
|
|
1680
|
+
/*
|
1681
|
+
* If the rule has invalid `meta.schema`, throw the error because
|
1682
|
+
* this is not an invalid inline configuration but an invalid rule.
|
1683
|
+
*/
|
1684
|
+
if (err.code === "ESLINT_INVALID_RULE_OPTIONS_SCHEMA") {
|
1685
|
+
throw err;
|
1686
|
+
}
|
1687
|
+
|
1696
1688
|
let baseMessage = err.message.slice(
|
1697
1689
|
err.message.startsWith("Key \"rules\":")
|
1698
1690
|
? err.message.indexOf(":", 12) + 1
|
@@ -1737,7 +1729,8 @@ class Linter {
|
|
1737
1729
|
options.filename,
|
1738
1730
|
options.disableFixes,
|
1739
1731
|
slots.cwd,
|
1740
|
-
providedOptions.physicalFilename
|
1732
|
+
providedOptions.physicalFilename,
|
1733
|
+
options.ruleFilter
|
1741
1734
|
);
|
1742
1735
|
} catch (err) {
|
1743
1736
|
err.message += `\nOccurred while linting ${options.filename}`;
|
@@ -1768,7 +1761,9 @@ class Linter {
|
|
1768
1761
|
.concat(commentDirectives.problems)
|
1769
1762
|
.concat(inlineConfigProblems)
|
1770
1763
|
.sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
|
1771
|
-
reportUnusedDisableDirectives: options.reportUnusedDisableDirectives
|
1764
|
+
reportUnusedDisableDirectives: options.reportUnusedDisableDirectives,
|
1765
|
+
ruleFilter: options.ruleFilter,
|
1766
|
+
configuredRules
|
1772
1767
|
});
|
1773
1768
|
}
|
1774
1769
|
|
@@ -1986,17 +1981,17 @@ class Linter {
|
|
1986
1981
|
/**
|
1987
1982
|
* Defines a new linting rule.
|
1988
1983
|
* @param {string} ruleId A unique rule identifier
|
1989
|
-
* @param {
|
1984
|
+
* @param {Rule} rule A rule object
|
1990
1985
|
* @returns {void}
|
1991
1986
|
*/
|
1992
|
-
defineRule(ruleId,
|
1987
|
+
defineRule(ruleId, rule) {
|
1993
1988
|
assertEslintrcConfig(this);
|
1994
|
-
internalSlotsMap.get(this).ruleMap.define(ruleId,
|
1989
|
+
internalSlotsMap.get(this).ruleMap.define(ruleId, rule);
|
1995
1990
|
}
|
1996
1991
|
|
1997
1992
|
/**
|
1998
1993
|
* Defines many new linting rules.
|
1999
|
-
* @param {Record<string,
|
1994
|
+
* @param {Record<string, Rule>} rulesToDefine map from unique rule identifier to rule
|
2000
1995
|
* @returns {void}
|
2001
1996
|
*/
|
2002
1997
|
defineRules(rulesToDefine) {
|
package/lib/linter/rules.js
CHANGED
@@ -13,18 +13,10 @@
|
|
13
13
|
const builtInRules = require("../rules");
|
14
14
|
|
15
15
|
//------------------------------------------------------------------------------
|
16
|
-
//
|
16
|
+
// Typedefs
|
17
17
|
//------------------------------------------------------------------------------
|
18
18
|
|
19
|
-
/**
|
20
|
-
* Normalizes a rule module to the new-style API
|
21
|
-
* @param {(Function|{create: Function})} rule A rule object, which can either be a function
|
22
|
-
* ("old-style") or an object with a `create` method ("new-style")
|
23
|
-
* @returns {{create: Function}} A new-style rule.
|
24
|
-
*/
|
25
|
-
function normalizeRule(rule) {
|
26
|
-
return typeof rule === "function" ? Object.assign({ create: rule }, rule) : rule;
|
27
|
-
}
|
19
|
+
/** @typedef {import("../shared/types").Rule} Rule */
|
28
20
|
|
29
21
|
//------------------------------------------------------------------------------
|
30
22
|
// Public Interface
|
@@ -41,18 +33,17 @@ class Rules {
|
|
41
33
|
/**
|
42
34
|
* Registers a rule module for rule id in storage.
|
43
35
|
* @param {string} ruleId Rule id (file name).
|
44
|
-
* @param {
|
36
|
+
* @param {Rule} rule Rule object.
|
45
37
|
* @returns {void}
|
46
38
|
*/
|
47
|
-
define(ruleId,
|
48
|
-
this._rules[ruleId] =
|
39
|
+
define(ruleId, rule) {
|
40
|
+
this._rules[ruleId] = rule;
|
49
41
|
}
|
50
42
|
|
51
43
|
/**
|
52
44
|
* Access rule handler by id (file name).
|
53
45
|
* @param {string} ruleId Rule id (file name).
|
54
|
-
* @returns {
|
55
|
-
* A rule. This is normalized to always have the new-style shape with a `create` method.
|
46
|
+
* @returns {Rule} Rule object.
|
56
47
|
*/
|
57
48
|
get(ruleId) {
|
58
49
|
if (typeof this._rules[ruleId] === "string") {
|
package/lib/options.js
CHANGED
@@ -57,6 +57,8 @@ const optionator = require("optionator");
|
|
57
57
|
* @property {boolean} quiet Report errors only
|
58
58
|
* @property {boolean} [version] Output the version number
|
59
59
|
* @property {boolean} warnIgnored Show warnings when the file list includes ignored files
|
60
|
+
* @property {boolean} [passOnNoPatterns=false] When set to true, missing patterns cause
|
61
|
+
* the linting operation to short circuit and not report any failures.
|
60
62
|
* @property {string[]} _ Positional filenames or patterns
|
61
63
|
*/
|
62
64
|
|
@@ -168,7 +170,7 @@ module.exports = function(usingFlatConfig) {
|
|
168
170
|
alias: "c",
|
169
171
|
type: "path::String",
|
170
172
|
description: usingFlatConfig
|
171
|
-
? "Use this configuration instead of eslint.config.js"
|
173
|
+
? "Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs"
|
172
174
|
: "Use this configuration, overriding .eslintrc.* config options if present"
|
173
175
|
},
|
174
176
|
envFlag,
|
@@ -370,6 +372,12 @@ module.exports = function(usingFlatConfig) {
|
|
370
372
|
description: "Exit with exit code 2 in case of fatal error"
|
371
373
|
},
|
372
374
|
warnIgnoredFlag,
|
375
|
+
{
|
376
|
+
option: "pass-on-no-patterns",
|
377
|
+
type: "Boolean",
|
378
|
+
default: false,
|
379
|
+
description: "Exit with exit code 0 in case no file patterns are passed"
|
380
|
+
},
|
373
381
|
{
|
374
382
|
option: "debug",
|
375
383
|
type: "Boolean",
|