eslint 9.26.0 → 9.27.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 +7 -2
- package/bin/eslint.js +7 -11
- package/conf/rule-type-list.json +2 -1
- package/lib/cli-engine/cli-engine.js +7 -7
- package/lib/cli.js +5 -4
- package/lib/config/config-loader.js +10 -18
- package/lib/config/config.js +328 -5
- package/lib/eslint/eslint-helpers.js +3 -1
- package/lib/eslint/eslint.js +26 -9
- package/lib/eslint/legacy-eslint.js +6 -6
- package/lib/languages/js/source-code/source-code.js +10 -6
- package/lib/linter/apply-disable-directives.js +1 -1
- package/lib/linter/file-context.js +11 -0
- package/lib/linter/linter.js +75 -82
- package/lib/linter/report-translator.js +2 -1
- package/lib/rule-tester/rule-tester.js +3 -3
- package/lib/rules/index.js +1 -0
- package/lib/rules/max-params.js +32 -7
- package/lib/rules/no-array-constructor.js +51 -1
- package/lib/rules/no-unassigned-vars.js +72 -0
- package/lib/rules/no-useless-escape.js +24 -2
- package/lib/rules/prefer-named-capture-group.js +7 -1
- package/lib/services/processor-service.js +1 -1
- package/lib/services/suppressions-service.js +5 -3
- package/lib/shared/flags.js +1 -0
- package/lib/types/index.d.ts +122 -4
- package/lib/types/rules.d.ts +19 -1
- package/package.json +6 -8
- package/lib/config/flat-config-helpers.js +0 -128
- package/lib/config/rule-validator.js +0 -199
- package/lib/mcp/mcp-server.js +0 -66
- package/lib/shared/types.js +0 -229
package/lib/eslint/eslint.js
CHANGED
@@ -14,7 +14,6 @@ const { existsSync } = require("node:fs");
|
|
14
14
|
const path = require("node:path");
|
15
15
|
const { version } = require("../../package.json");
|
16
16
|
const { Linter } = require("../linter");
|
17
|
-
const { getRuleFromConfig } = require("../config/flat-config-helpers");
|
18
17
|
const { defaultConfig } = require("../config/default-config");
|
19
18
|
const {
|
20
19
|
Legacy: {
|
@@ -57,17 +56,21 @@ const { ConfigLoader, LegacyConfigLoader } = require("../config/config-loader");
|
|
57
56
|
* @import { CLIEngineLintReport } from "./legacy-eslint.js";
|
58
57
|
* @import { FlatConfigArray } from "../config/flat-config-array.js";
|
59
58
|
* @import { RuleDefinition } from "@eslint/core";
|
60
|
-
* @import { ConfigData, DeprecatedRuleInfo, LintMessage, LintResult, ResultsMeta } from "../shared/types.js";
|
61
59
|
*/
|
62
60
|
|
63
61
|
/** @typedef {ReturnType<ConfigArray.extractConfig>} ExtractedConfig */
|
62
|
+
/** @typedef {import("../types").Linter.Config} Config */
|
63
|
+
/** @typedef {import("../types").ESLint.DeprecatedRuleUse} DeprecatedRuleInfo */
|
64
|
+
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
65
|
+
/** @typedef {import("../types").ESLint.LintResult} LintResult */
|
64
66
|
/** @typedef {import("../types").ESLint.Plugin} Plugin */
|
67
|
+
/** @typedef {import("../types").ESLint.ResultsMeta} ResultsMeta */
|
65
68
|
|
66
69
|
/**
|
67
70
|
* The options with which to configure the ESLint instance.
|
68
71
|
* @typedef {Object} ESLintOptions
|
69
72
|
* @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments.
|
70
|
-
* @property {
|
73
|
+
* @property {Config|Array<Config>} [baseConfig] Base config, extended by all configs used with this instance
|
71
74
|
* @property {boolean} [cache] Enable result caching.
|
72
75
|
* @property {string} [cacheLocation] The cache file to use instead of .eslintcache.
|
73
76
|
* @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files.
|
@@ -79,7 +82,7 @@ const { ConfigLoader, LegacyConfigLoader } = require("../config/config-loader");
|
|
79
82
|
* @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
|
80
83
|
* @property {boolean} [ignore] False disables all ignore patterns except for the default ones.
|
81
84
|
* @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to config ignores. These patterns are relative to `cwd`.
|
82
|
-
* @property {
|
85
|
+
* @property {Config|Array<Config>} [overrideConfig] Override config, overrides all configs used with this instance
|
83
86
|
* @property {boolean|string} [overrideConfigFile] Searches for default config file when falsy;
|
84
87
|
* doesn't do any config file lookup when `true`; considered to be a config filename
|
85
88
|
* when a string.
|
@@ -159,7 +162,7 @@ function getOrFindUsedDeprecatedRules(eslint, maybeFilePath) {
|
|
159
162
|
if (getRuleSeverity(ruleConf) === 0) {
|
160
163
|
continue;
|
161
164
|
}
|
162
|
-
const rule =
|
165
|
+
const rule = config.getRuleDefinition(ruleId);
|
163
166
|
const meta = rule && rule.meta;
|
164
167
|
|
165
168
|
if (meta && meta.deprecated) {
|
@@ -353,7 +356,7 @@ function shouldMessageBeFixed(message, config, fixTypes) {
|
|
353
356
|
return fixTypes.has("directive");
|
354
357
|
}
|
355
358
|
|
356
|
-
const rule = message.ruleId &&
|
359
|
+
const rule = message.ruleId && config.getRuleDefinition(message.ruleId);
|
357
360
|
|
358
361
|
return Boolean(rule && rule.meta && fixTypes.has(rule.meta.type));
|
359
362
|
}
|
@@ -387,6 +390,20 @@ function getFixerForFixTypes(fix, fixTypesSet, config) {
|
|
387
390
|
originalFix(message);
|
388
391
|
}
|
389
392
|
|
393
|
+
/**
|
394
|
+
* Retrieves flags from the environment variable ESLINT_FLAGS.
|
395
|
+
* @param {string[]} flags The flags defined via the API.
|
396
|
+
* @returns {string[]} The merged flags to use.
|
397
|
+
*/
|
398
|
+
function mergeEnvironmentFlags(flags) {
|
399
|
+
if (!process.env.ESLINT_FLAGS) {
|
400
|
+
return flags;
|
401
|
+
}
|
402
|
+
|
403
|
+
const envFlags = process.env.ESLINT_FLAGS.trim().split(/\s*,\s*/gu);
|
404
|
+
return Array.from(new Set([...envFlags, ...flags]));
|
405
|
+
}
|
406
|
+
|
390
407
|
//-----------------------------------------------------------------------------
|
391
408
|
// Main API
|
392
409
|
//-----------------------------------------------------------------------------
|
@@ -417,7 +434,7 @@ class ESLint {
|
|
417
434
|
const linter = new Linter({
|
418
435
|
cwd: processedOptions.cwd,
|
419
436
|
configType: "flat",
|
420
|
-
flags: processedOptions.flags,
|
437
|
+
flags: mergeEnvironmentFlags(processedOptions.flags),
|
421
438
|
});
|
422
439
|
|
423
440
|
const cacheFilePath = getCacheFile(
|
@@ -611,7 +628,7 @@ class ESLint {
|
|
611
628
|
if (!config) {
|
612
629
|
throw createExtraneousResultsError();
|
613
630
|
}
|
614
|
-
const rule =
|
631
|
+
const rule = config.getRuleDefinition(ruleId);
|
615
632
|
|
616
633
|
// ignore unknown rules
|
617
634
|
if (rule) {
|
@@ -1068,7 +1085,7 @@ class ESLint {
|
|
1068
1085
|
* This is the same logic used by the ESLint CLI executable to determine
|
1069
1086
|
* configuration for each file it processes.
|
1070
1087
|
* @param {string} filePath The path of the file to retrieve a config object for.
|
1071
|
-
* @returns {Promise<
|
1088
|
+
* @returns {Promise<Config|undefined>} A configuration object for the file
|
1072
1089
|
* or `undefined` if there is no configuration data for the object.
|
1073
1090
|
*/
|
1074
1091
|
async calculateConfigForFile(filePath) {
|
@@ -30,14 +30,14 @@ const { version } = require("../../package.json");
|
|
30
30
|
//------------------------------------------------------------------------------
|
31
31
|
|
32
32
|
/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */
|
33
|
-
/** @typedef {import("../
|
34
|
-
/** @typedef {import("../
|
35
|
-
/** @typedef {import("../
|
36
|
-
/** @typedef {import("../
|
37
|
-
/** @typedef {import("../shared/types").LintResult} LintResult */
|
38
|
-
/** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
|
33
|
+
/** @typedef {import("../types").ESLint.ConfigData} ConfigData */
|
34
|
+
/** @typedef {import("../types").ESLint.DeprecatedRuleUse} DeprecatedRuleInfo */
|
35
|
+
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
36
|
+
/** @typedef {import("../types").ESLint.LintResult} LintResult */
|
39
37
|
/** @typedef {import("../types").ESLint.Plugin} Plugin */
|
38
|
+
/** @typedef {import("../types").ESLint.ResultsMeta} ResultsMeta */
|
40
39
|
/** @typedef {import("../types").Rule.RuleModule} Rule */
|
40
|
+
/** @typedef {import("../types").Linter.SuppressedLintMessage} SuppressedLintMessage */
|
41
41
|
|
42
42
|
/**
|
43
43
|
* The main formatter object.
|
@@ -53,7 +53,7 @@ const CODE_PATH_EVENTS = [
|
|
53
53
|
/**
|
54
54
|
* Validates that the given AST has the required information.
|
55
55
|
* @param {ASTNode} ast The Program node of the AST to check.
|
56
|
-
* @throws {
|
56
|
+
* @throws {TypeError} If the AST doesn't contain the correct information.
|
57
57
|
* @returns {void}
|
58
58
|
* @private
|
59
59
|
*/
|
@@ -147,8 +147,8 @@ function sortedMerge(tokens, comments) {
|
|
147
147
|
* Normalizes a value for a global in a config
|
148
148
|
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
|
149
149
|
* a global directive comment
|
150
|
-
* @returns {("
|
151
|
-
* @throws Error if global value is invalid
|
150
|
+
* @returns {("readonly"|"writable"|"off")} The value normalized as a string
|
151
|
+
* @throws {Error} if global value is invalid
|
152
152
|
*/
|
153
153
|
function normalizeConfigGlobal(configuredValue) {
|
154
154
|
switch (configuredValue) {
|
@@ -471,6 +471,10 @@ class SourceCode extends TokenStore {
|
|
471
471
|
* @type {string[]}
|
472
472
|
*/
|
473
473
|
this.lines = [];
|
474
|
+
|
475
|
+
/**
|
476
|
+
* @type {number[]}
|
477
|
+
*/
|
474
478
|
this.lineStartIndices = [0];
|
475
479
|
|
476
480
|
const lineEndingPattern = astUtils.createGlobalLinebreakMatcher();
|
@@ -528,7 +532,7 @@ class SourceCode extends TokenStore {
|
|
528
532
|
|
529
533
|
/**
|
530
534
|
* Gets the entire source text split into an array of lines.
|
531
|
-
* @returns {
|
535
|
+
* @returns {string[]} The source text as an array of lines.
|
532
536
|
* @public
|
533
537
|
*/
|
534
538
|
getLines() {
|
@@ -687,8 +691,8 @@ class SourceCode extends TokenStore {
|
|
687
691
|
/**
|
688
692
|
* Converts a source text index into a (line, column) pair.
|
689
693
|
* @param {number} index The index of a character in a file
|
690
|
-
* @throws {TypeError} If non-numeric index or index out of range.
|
691
|
-
* @returns {
|
694
|
+
* @throws {TypeError|RangeError} If non-numeric index or index out of range.
|
695
|
+
* @returns {{line: number, column: number}} A {line, column} location object with a 0-indexed column
|
692
696
|
* @public
|
693
697
|
*/
|
694
698
|
getLocFromIndex(index) {
|
@@ -9,7 +9,7 @@
|
|
9
9
|
// Typedefs
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
/** @typedef {import("../
|
12
|
+
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
13
13
|
/** @typedef {import("@eslint/core").Language} Language */
|
14
14
|
/** @typedef {import("@eslint/core").Position} Position */
|
15
15
|
/** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
|
@@ -128,6 +128,17 @@ class FileContext {
|
|
128
128
|
getSourceCode() {
|
129
129
|
return this.sourceCode;
|
130
130
|
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* Creates a new object with the current object as the prototype and
|
134
|
+
* the specified properties as its own properties.
|
135
|
+
* @param {Object} extension The properties to add to the new object.
|
136
|
+
* @returns {FileContext} A new object with the current object as the prototype
|
137
|
+
* and the specified properties as its own properties.
|
138
|
+
*/
|
139
|
+
extend(extension) {
|
140
|
+
return Object.freeze(Object.assign(Object.create(this), extension));
|
141
|
+
}
|
131
142
|
}
|
132
143
|
|
133
144
|
exports.FileContext = FileContext;
|
package/lib/linter/linter.js
CHANGED
@@ -34,10 +34,8 @@ const path = require("node:path"),
|
|
34
34
|
SourceCodeFixer = require("./source-code-fixer"),
|
35
35
|
timing = require("./timing"),
|
36
36
|
ruleReplacements = require("../../conf/replacements.json");
|
37
|
-
const { getRuleFromConfig } = require("../config/flat-config-helpers");
|
38
37
|
const { FlatConfigArray } = require("../config/flat-config-array");
|
39
38
|
const { startTime, endTime } = require("../shared/stats");
|
40
|
-
const { RuleValidator } = require("../config/rule-validator");
|
41
39
|
const { assertIsRuleSeverity } = require("../config/flat-config-schema");
|
42
40
|
const {
|
43
41
|
normalizeSeverityToString,
|
@@ -66,6 +64,7 @@ const { ParserService } = require("../services/parser-service");
|
|
66
64
|
const { FileContext } = require("./file-context");
|
67
65
|
const { ProcessorService } = require("../services/processor-service");
|
68
66
|
const { containsDifferentProperty } = require("../shared/option-utils");
|
67
|
+
const { Config } = require("../config/config");
|
69
68
|
const STEP_KIND_VISIT = 1;
|
70
69
|
const STEP_KIND_CALL = 2;
|
71
70
|
|
@@ -75,17 +74,19 @@ const STEP_KIND_CALL = 2;
|
|
75
74
|
|
76
75
|
/** @import { Language, LanguageOptions, RuleConfig, RuleDefinition, RuleSeverity } from "@eslint/core" */
|
77
76
|
|
78
|
-
/** @typedef {import("../
|
79
|
-
/** @typedef {import("../
|
80
|
-
/** @typedef {import("../
|
81
|
-
/** @typedef {import("../
|
82
|
-
/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */
|
83
|
-
/** @typedef {import("../shared/types").ParserOptions} ParserOptions */
|
84
|
-
/** @typedef {import("../shared/types").Processor} Processor */
|
85
|
-
/** @typedef {import("../shared/types").Times} Times */
|
77
|
+
/** @typedef {import("../types").Linter.Config} Config */
|
78
|
+
/** @typedef {import("../types").ESLint.ConfigData} ConfigData */
|
79
|
+
/** @typedef {import("../types").ESLint.Environment} Environment */
|
80
|
+
/** @typedef {import("../types").Linter.GlobalConf} GlobalConf */
|
86
81
|
/** @typedef {import("../types").Linter.LanguageOptions} JSLanguageOptions */
|
87
|
-
/** @typedef {import("../types").Linter.
|
82
|
+
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
83
|
+
/** @typedef {import("../types").Linter.Parser} Parser */
|
84
|
+
/** @typedef {import("../types").Linter.ParserOptions} ParserOptions */
|
85
|
+
/** @typedef {import("../types").Linter.Processor} Processor */
|
88
86
|
/** @typedef {import("../types").Rule.RuleModule} Rule */
|
87
|
+
/** @typedef {import("../types").Linter.StringSeverity} StringSeverity */
|
88
|
+
/** @typedef {import("../types").Linter.SuppressedLintMessage} SuppressedLintMessage */
|
89
|
+
/** @typedef {import("../types").Linter.TimePass} TimePass */
|
89
90
|
|
90
91
|
/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
|
91
92
|
/**
|
@@ -110,7 +111,7 @@ const STEP_KIND_CALL = 2;
|
|
110
111
|
* @property {SourceCode|null} lastSourceCode The `SourceCode` instance that the last `verify()` call used.
|
111
112
|
* @property {SuppressedLintMessage[]} lastSuppressedMessages The `SuppressedLintMessage[]` instance that the last `verify()` call produced.
|
112
113
|
* @property {Map<string, Parser>} parserMap The loaded parsers.
|
113
|
-
* @property {
|
114
|
+
* @property {{ passes: TimePass[]; }} times The times spent on applying a rule to a file (see `stats` option).
|
114
115
|
* @property {Rules} ruleMap The loaded rules.
|
115
116
|
*/
|
116
117
|
|
@@ -350,7 +351,7 @@ function asArray(value) {
|
|
350
351
|
|
351
352
|
/**
|
352
353
|
* Pushes a problem to inlineConfigProblems if ruleOptions are redundant.
|
353
|
-
* @param {
|
354
|
+
* @param {Config} config Provided config.
|
354
355
|
* @param {Object} loc A line/column location
|
355
356
|
* @param {Array} problems Problems that may be added to.
|
356
357
|
* @param {string} ruleId The rule ID.
|
@@ -901,7 +902,7 @@ function normalizeFilename(filename) {
|
|
901
902
|
* Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a
|
902
903
|
* consistent shape.
|
903
904
|
* @param {VerifyOptions} providedOptions Options
|
904
|
-
* @param {ConfigData} config Config.
|
905
|
+
* @param {Config|ConfigData} config Config.
|
905
906
|
* @returns {Required<VerifyOptions> & InternalOptions} Normalized options
|
906
907
|
*/
|
907
908
|
function normalizeVerifyOptions(providedOptions, config) {
|
@@ -1184,7 +1185,7 @@ function runRules(
|
|
1184
1185
|
* All rule contexts will inherit from this object. This avoids the performance penalty of copying all the
|
1185
1186
|
* properties once for each rule.
|
1186
1187
|
*/
|
1187
|
-
const
|
1188
|
+
const fileContext = new FileContext({
|
1188
1189
|
cwd,
|
1189
1190
|
filename,
|
1190
1191
|
physicalFilename: physicalFilename || filename,
|
@@ -1200,7 +1201,7 @@ function runRules(
|
|
1200
1201
|
const lintingProblems = [];
|
1201
1202
|
|
1202
1203
|
Object.keys(configuredRules).forEach(ruleId => {
|
1203
|
-
const severity =
|
1204
|
+
const severity = Config.getRuleNumericSeverity(configuredRules[ruleId]);
|
1204
1205
|
|
1205
1206
|
// not load disabled rules
|
1206
1207
|
if (severity === 0) {
|
@@ -1220,63 +1221,61 @@ function runRules(
|
|
1220
1221
|
|
1221
1222
|
const messageIds = rule.meta && rule.meta.messages;
|
1222
1223
|
let reportTranslator = null;
|
1223
|
-
const ruleContext =
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
const problem = reportTranslator(...args);
|
1224
|
+
const ruleContext = fileContext.extend({
|
1225
|
+
id: ruleId,
|
1226
|
+
options: getRuleOptions(
|
1227
|
+
configuredRules[ruleId],
|
1228
|
+
applyDefaultOptions ? rule.meta?.defaultOptions : void 0,
|
1229
|
+
),
|
1230
|
+
report(...args) {
|
1231
|
+
/*
|
1232
|
+
* Create a report translator lazily.
|
1233
|
+
* In a vast majority of cases, any given rule reports zero errors on a given
|
1234
|
+
* piece of code. Creating a translator lazily avoids the performance cost of
|
1235
|
+
* creating a new translator function for each rule that usually doesn't get
|
1236
|
+
* called.
|
1237
|
+
*
|
1238
|
+
* Using lazy report translators improves end-to-end performance by about 3%
|
1239
|
+
* with Node 8.4.0.
|
1240
|
+
*/
|
1241
|
+
if (reportTranslator === null) {
|
1242
|
+
reportTranslator = createReportTranslator({
|
1243
|
+
ruleId,
|
1244
|
+
severity,
|
1245
|
+
sourceCode,
|
1246
|
+
messageIds,
|
1247
|
+
disableFixes,
|
1248
|
+
language,
|
1249
|
+
});
|
1250
|
+
}
|
1251
|
+
const problem = reportTranslator(...args);
|
1252
1252
|
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1253
|
+
if (problem.fix && !(rule.meta && rule.meta.fixable)) {
|
1254
|
+
throw new Error(
|
1255
|
+
'Fixable rules must set the `meta.fixable` property to "code" or "whitespace".',
|
1256
|
+
);
|
1257
|
+
}
|
1258
|
+
if (
|
1259
|
+
problem.suggestions &&
|
1260
|
+
!(rule.meta && rule.meta.hasSuggestions === true)
|
1261
|
+
) {
|
1258
1262
|
if (
|
1259
|
-
|
1260
|
-
|
1263
|
+
rule.meta &&
|
1264
|
+
rule.meta.docs &&
|
1265
|
+
typeof rule.meta.docs.suggestion !== "undefined"
|
1261
1266
|
) {
|
1262
|
-
|
1263
|
-
rule.meta &&
|
1264
|
-
rule.meta.docs &&
|
1265
|
-
typeof rule.meta.docs.suggestion !== "undefined"
|
1266
|
-
) {
|
1267
|
-
// Encourage migration from the former property name.
|
1268
|
-
throw new Error(
|
1269
|
-
"Rules with suggestions must set the `meta.hasSuggestions` property to `true`. `meta.docs.suggestion` is ignored by ESLint.",
|
1270
|
-
);
|
1271
|
-
}
|
1267
|
+
// Encourage migration from the former property name.
|
1272
1268
|
throw new Error(
|
1273
|
-
"Rules with suggestions must set the `meta.hasSuggestions` property to `true`.",
|
1269
|
+
"Rules with suggestions must set the `meta.hasSuggestions` property to `true`. `meta.docs.suggestion` is ignored by ESLint.",
|
1274
1270
|
);
|
1275
1271
|
}
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1272
|
+
throw new Error(
|
1273
|
+
"Rules with suggestions must set the `meta.hasSuggestions` property to `true`.",
|
1274
|
+
);
|
1275
|
+
}
|
1276
|
+
lintingProblems.push(problem);
|
1277
|
+
},
|
1278
|
+
});
|
1280
1279
|
|
1281
1280
|
const ruleListenersReturn =
|
1282
1281
|
timing.enabled || stats
|
@@ -1885,7 +1884,7 @@ class Linter {
|
|
1885
1884
|
/**
|
1886
1885
|
* Verify with a processor.
|
1887
1886
|
* @param {string|SourceCode} textOrSourceCode The source code.
|
1888
|
-
* @param {
|
1887
|
+
* @param {Config} config The config array.
|
1889
1888
|
* @param {VerifyOptions&ProcessorOptions} options The options.
|
1890
1889
|
* @param {FlatConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively.
|
1891
1890
|
* @returns {(LintMessage|SuppressedLintMessage)[]} The found problems.
|
@@ -1986,7 +1985,7 @@ class Linter {
|
|
1986
1985
|
/**
|
1987
1986
|
* Verify using flat config and without any processors.
|
1988
1987
|
* @param {VFile} file The file to lint.
|
1989
|
-
* @param {
|
1988
|
+
* @param {Config} providedConfig An ESLintConfig instance to configure everything.
|
1990
1989
|
* @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
|
1991
1990
|
* @throws {Error} If during rule execution.
|
1992
1991
|
* @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
|
@@ -2100,15 +2099,12 @@ class Linter {
|
|
2100
2099
|
}),
|
2101
2100
|
);
|
2102
2101
|
|
2103
|
-
// next we need to verify information about the specified rules
|
2104
|
-
const ruleValidator = new RuleValidator();
|
2105
|
-
|
2106
2102
|
for (const {
|
2107
2103
|
config: inlineConfig,
|
2108
2104
|
loc,
|
2109
2105
|
} of inlineConfigResult.configs) {
|
2110
2106
|
Object.keys(inlineConfig.rules).forEach(ruleId => {
|
2111
|
-
const rule =
|
2107
|
+
const rule = config.getRuleDefinition(ruleId);
|
2112
2108
|
const ruleValue = inlineConfig.rules[ruleId];
|
2113
2109
|
|
2114
2110
|
if (!rule) {
|
@@ -2218,11 +2214,8 @@ class Linter {
|
|
2218
2214
|
}
|
2219
2215
|
|
2220
2216
|
if (shouldValidateOptions) {
|
2221
|
-
|
2222
|
-
|
2223
|
-
rules: {
|
2224
|
-
[ruleId]: ruleOptions,
|
2225
|
-
},
|
2217
|
+
config.validateRulesConfig({
|
2218
|
+
[ruleId]: ruleOptions,
|
2226
2219
|
});
|
2227
2220
|
}
|
2228
2221
|
|
@@ -2270,7 +2263,7 @@ class Linter {
|
|
2270
2263
|
options.allowInlineConfig && !options.warnInlineConfig
|
2271
2264
|
? getDirectiveCommentsForFlatConfig(
|
2272
2265
|
sourceCode,
|
2273
|
-
ruleId =>
|
2266
|
+
ruleId => config.getRuleDefinition(ruleId),
|
2274
2267
|
config.language,
|
2275
2268
|
)
|
2276
2269
|
: { problems: [], disableDirectives: [] };
|
@@ -2289,7 +2282,7 @@ class Linter {
|
|
2289
2282
|
lintingProblems = runRules(
|
2290
2283
|
sourceCode,
|
2291
2284
|
configuredRules,
|
2292
|
-
ruleId =>
|
2285
|
+
ruleId => config.getRuleDefinition(ruleId),
|
2293
2286
|
void 0,
|
2294
2287
|
config.language,
|
2295
2288
|
languageOptions,
|
@@ -2348,7 +2341,7 @@ class Linter {
|
|
2348
2341
|
/**
|
2349
2342
|
* Same as linter.verify, except without support for processors.
|
2350
2343
|
* @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
|
2351
|
-
* @param {
|
2344
|
+
* @param {Config} providedConfig An ESLintConfig instance to configure everything.
|
2352
2345
|
* @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
|
2353
2346
|
* @throws {Error} If during rule execution.
|
2354
2347
|
* @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
|
@@ -2619,7 +2612,7 @@ class Linter {
|
|
2619
2612
|
|
2620
2613
|
/**
|
2621
2614
|
* Gets the times spent on (parsing, fixing, linting) a file.
|
2622
|
-
* @returns {
|
2615
|
+
* @returns {{ passes: TimePass[]; }} The times.
|
2623
2616
|
*/
|
2624
2617
|
getTimes() {
|
2625
2618
|
return internalSlotsMap.get(this).times ?? { passes: [] };
|
@@ -17,7 +17,8 @@ const { interpolate } = require("./interpolate");
|
|
17
17
|
// Typedefs
|
18
18
|
//------------------------------------------------------------------------------
|
19
19
|
|
20
|
-
/** @typedef {import("../
|
20
|
+
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
21
|
+
/** @typedef {import("../types").Linter.LintSuggestion} SuggestionResult */
|
21
22
|
|
22
23
|
/**
|
23
24
|
* An error message description
|
@@ -15,7 +15,7 @@ const assert = require("node:assert"),
|
|
15
15
|
path = require("node:path"),
|
16
16
|
equal = require("fast-deep-equal"),
|
17
17
|
Traverser = require("../shared/traverser"),
|
18
|
-
{
|
18
|
+
{ Config } = require("../config/config"),
|
19
19
|
{ Linter, SourceCodeFixer } = require("../linter"),
|
20
20
|
{ interpolate, getPlaceholderMatcher } = require("../linter/interpolate"),
|
21
21
|
stringify = require("json-stable-stringify-without-jsonify");
|
@@ -41,7 +41,7 @@ const { SourceCode } = require("../languages/js/source-code");
|
|
41
41
|
|
42
42
|
/** @import { LanguageOptions, RuleDefinition } from "@eslint/core" */
|
43
43
|
|
44
|
-
/** @typedef {import("../
|
44
|
+
/** @typedef {import("../types").Linter.Parser} Parser */
|
45
45
|
|
46
46
|
/**
|
47
47
|
* A test case that is expected to pass lint.
|
@@ -767,7 +767,7 @@ class RuleTester {
|
|
767
767
|
let schema;
|
768
768
|
|
769
769
|
try {
|
770
|
-
schema = getRuleOptionsSchema(rule);
|
770
|
+
schema = Config.getRuleOptionsSchema(rule);
|
771
771
|
} catch (err) {
|
772
772
|
err.message += metaSchemaDescription;
|
773
773
|
throw err;
|
package/lib/rules/index.js
CHANGED
@@ -225,6 +225,7 @@ module.exports = new LazyLoadingRuleMap(
|
|
225
225
|
"no-this-before-super": () => require("./no-this-before-super"),
|
226
226
|
"no-throw-literal": () => require("./no-throw-literal"),
|
227
227
|
"no-trailing-spaces": () => require("./no-trailing-spaces"),
|
228
|
+
"no-unassigned-vars": () => require("./no-unassigned-vars"),
|
228
229
|
"no-undef": () => require("./no-undef"),
|
229
230
|
"no-undef-init": () => require("./no-undef-init"),
|
230
231
|
"no-undefined": () => require("./no-undefined"),
|
package/lib/rules/max-params.js
CHANGED
@@ -20,6 +20,8 @@ const { upperCaseFirst } = require("../shared/string-utils");
|
|
20
20
|
module.exports = {
|
21
21
|
meta: {
|
22
22
|
type: "suggestion",
|
23
|
+
dialects: ["typescript", "javascript"],
|
24
|
+
language: "javascript",
|
23
25
|
|
24
26
|
docs: {
|
25
27
|
description:
|
@@ -46,6 +48,11 @@ module.exports = {
|
|
46
48
|
type: "integer",
|
47
49
|
minimum: 0,
|
48
50
|
},
|
51
|
+
countVoidThis: {
|
52
|
+
type: "boolean",
|
53
|
+
description:
|
54
|
+
"Whether to count a `this` declaration when the type is `void`.",
|
55
|
+
},
|
49
56
|
},
|
50
57
|
additionalProperties: false,
|
51
58
|
},
|
@@ -61,12 +68,16 @@ module.exports = {
|
|
61
68
|
const sourceCode = context.sourceCode;
|
62
69
|
const option = context.options[0];
|
63
70
|
let numParams = 3;
|
71
|
+
let countVoidThis = false;
|
64
72
|
|
65
|
-
if (
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
73
|
+
if (typeof option === "object") {
|
74
|
+
if (
|
75
|
+
Object.hasOwn(option, "maximum") ||
|
76
|
+
Object.hasOwn(option, "max")
|
77
|
+
) {
|
78
|
+
numParams = option.maximum || option.max;
|
79
|
+
}
|
80
|
+
countVoidThis = option.countVoidThis;
|
70
81
|
}
|
71
82
|
if (typeof option === "number") {
|
72
83
|
numParams = option;
|
@@ -79,7 +90,19 @@ module.exports = {
|
|
79
90
|
* @private
|
80
91
|
*/
|
81
92
|
function checkFunction(node) {
|
82
|
-
|
93
|
+
const hasVoidThisParam =
|
94
|
+
node.params.length > 0 &&
|
95
|
+
node.params[0].type === "Identifier" &&
|
96
|
+
node.params[0].name === "this" &&
|
97
|
+
node.params[0].typeAnnotation?.typeAnnotation.type ===
|
98
|
+
"TSVoidKeyword";
|
99
|
+
|
100
|
+
const effectiveParamCount =
|
101
|
+
hasVoidThisParam && !countVoidThis
|
102
|
+
? node.params.length - 1
|
103
|
+
: node.params.length;
|
104
|
+
|
105
|
+
if (effectiveParamCount > numParams) {
|
83
106
|
context.report({
|
84
107
|
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
85
108
|
node,
|
@@ -88,7 +111,7 @@ module.exports = {
|
|
88
111
|
name: upperCaseFirst(
|
89
112
|
astUtils.getFunctionNameWithKind(node),
|
90
113
|
),
|
91
|
-
count:
|
114
|
+
count: effectiveParamCount,
|
92
115
|
max: numParams,
|
93
116
|
},
|
94
117
|
});
|
@@ -99,6 +122,8 @@ module.exports = {
|
|
99
122
|
FunctionDeclaration: checkFunction,
|
100
123
|
ArrowFunctionExpression: checkFunction,
|
101
124
|
FunctionExpression: checkFunction,
|
125
|
+
TSDeclareFunction: checkFunction,
|
126
|
+
TSFunctionType: checkFunction,
|
102
127
|
};
|
103
128
|
},
|
104
129
|
};
|