eslint 9.39.0 → 10.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 +3 -3
- package/bin/eslint.js +1 -2
- package/lib/api.js +4 -15
- package/lib/cli.js +14 -56
- package/lib/config/config-loader.js +6 -154
- package/lib/eslint/eslint-helpers.js +5 -8
- package/lib/eslint/eslint.js +1 -1
- package/lib/eslint/index.js +0 -2
- package/lib/languages/js/source-code/source-code.js +41 -89
- package/lib/languages/js/source-code/token-store/utils.js +29 -8
- package/lib/linter/apply-disable-directives.js +0 -1
- package/lib/linter/file-context.js +0 -56
- package/lib/linter/file-report.js +0 -4
- package/lib/linter/linter.js +45 -1086
- package/lib/linter/rule-fixer.js +30 -0
- package/lib/options.js +62 -182
- package/lib/rule-tester/rule-tester.js +255 -194
- package/lib/rules/dot-notation.js +2 -2
- package/lib/rules/func-names.js +2 -0
- package/lib/rules/no-eval.js +1 -1
- package/lib/rules/no-invalid-regexp.js +1 -0
- package/lib/rules/no-shadow-restricted-names.js +1 -1
- package/lib/rules/no-unassigned-vars.js +1 -1
- package/lib/rules/no-useless-assignment.js +1 -1
- package/lib/rules/preserve-caught-error.js +1 -1
- package/lib/rules/radix.js +25 -48
- package/lib/services/parser-service.js +0 -1
- package/lib/services/processor-service.js +0 -1
- package/lib/services/warning-service.js +0 -11
- package/lib/shared/flags.js +0 -19
- package/lib/shared/translate-cli-options.js +106 -164
- package/lib/types/index.d.ts +7 -60
- package/lib/types/rules.d.ts +11 -2
- package/lib/types/use-at-your-own-risk.d.ts +1 -54
- package/lib/unsupported-api.js +3 -6
- package/package.json +14 -19
- package/conf/default-cli-options.js +0 -32
- package/lib/cli-engine/cli-engine.js +0 -1109
- package/lib/cli-engine/file-enumerator.js +0 -541
- package/lib/cli-engine/index.js +0 -7
- package/lib/cli-engine/load-rules.js +0 -46
- package/lib/eslint/legacy-eslint.js +0 -786
|
@@ -20,8 +20,7 @@ const { isCommentToken } = require("@eslint-community/eslint-utils"),
|
|
|
20
20
|
VisitNodeStep,
|
|
21
21
|
CallMethodStep,
|
|
22
22
|
Directive,
|
|
23
|
-
} = require("@eslint/plugin-kit")
|
|
24
|
-
eslintScope = require("eslint-scope");
|
|
23
|
+
} = require("@eslint/plugin-kit");
|
|
25
24
|
|
|
26
25
|
//------------------------------------------------------------------------------
|
|
27
26
|
// Type Definitions
|
|
@@ -29,6 +28,7 @@ const { isCommentToken } = require("@eslint-community/eslint-utils"),
|
|
|
29
28
|
|
|
30
29
|
/** @typedef {import("eslint-scope").Variable} Variable */
|
|
31
30
|
/** @typedef {import("eslint-scope").Scope} Scope */
|
|
31
|
+
/** @typedef {import("eslint-scope").ScopeManager} ScopeManager */
|
|
32
32
|
/** @typedef {import("@eslint/core").SourceCode} ISourceCode */
|
|
33
33
|
/** @typedef {import("@eslint/core").Directive} IDirective */
|
|
34
34
|
/** @typedef {import("@eslint/core").TraversalStep} ITraversalStep */
|
|
@@ -264,103 +264,37 @@ function findLineNumberBinarySearch(lineStartIndices, target) {
|
|
|
264
264
|
* Ensures that variables representing built-in properties of the Global Object,
|
|
265
265
|
* and any globals declared by special block comments, are present in the global
|
|
266
266
|
* scope.
|
|
267
|
-
* @param {
|
|
267
|
+
* @param {ScopeManager} scopeManager Scope manager.
|
|
268
268
|
* @param {Object|undefined} configGlobals The globals declared in configuration
|
|
269
269
|
* @param {Object|undefined} inlineGlobals The globals declared in the source code
|
|
270
270
|
* @returns {void}
|
|
271
271
|
*/
|
|
272
272
|
function addDeclaredGlobals(
|
|
273
|
-
|
|
274
|
-
configGlobals =
|
|
275
|
-
inlineGlobals =
|
|
273
|
+
scopeManager,
|
|
274
|
+
configGlobals = Object.create(null),
|
|
275
|
+
inlineGlobals = Object.create(null),
|
|
276
276
|
) {
|
|
277
|
-
|
|
278
|
-
for (const id of new Set([
|
|
279
|
-
...Object.keys(configGlobals),
|
|
280
|
-
...Object.keys(inlineGlobals),
|
|
281
|
-
])) {
|
|
282
|
-
/*
|
|
283
|
-
* `normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would
|
|
284
|
-
* typically be caught when validating a config anyway (validity for inline global comments is checked separately).
|
|
285
|
-
*/
|
|
286
|
-
const configValue =
|
|
287
|
-
configGlobals[id] === void 0
|
|
288
|
-
? void 0
|
|
289
|
-
: normalizeConfigGlobal(configGlobals[id]);
|
|
290
|
-
const commentValue = inlineGlobals[id] && inlineGlobals[id].value;
|
|
291
|
-
const value = commentValue || configValue;
|
|
292
|
-
const sourceComments = inlineGlobals[id] && inlineGlobals[id].comments;
|
|
293
|
-
|
|
294
|
-
if (value === "off") {
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
let variable = globalScope.set.get(id);
|
|
299
|
-
|
|
300
|
-
if (!variable) {
|
|
301
|
-
variable = new eslintScope.Variable(id, globalScope);
|
|
302
|
-
|
|
303
|
-
globalScope.variables.push(variable);
|
|
304
|
-
globalScope.set.set(id, variable);
|
|
305
|
-
}
|
|
277
|
+
const finalGlobals = { __proto__: null, ...configGlobals };
|
|
306
278
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
variable.eslintExplicitGlobalComments = sourceComments;
|
|
310
|
-
variable.writeable = value === "writable";
|
|
279
|
+
for (const [name, data] of Object.entries(inlineGlobals)) {
|
|
280
|
+
finalGlobals[name] = data.value;
|
|
311
281
|
}
|
|
312
282
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
* references and remove the ones that were added by configuration.
|
|
317
|
-
*/
|
|
318
|
-
globalScope.through = globalScope.through.filter(reference => {
|
|
319
|
-
const name = reference.identifier.name;
|
|
320
|
-
const variable = globalScope.set.get(name);
|
|
321
|
-
|
|
322
|
-
if (variable) {
|
|
323
|
-
/*
|
|
324
|
-
* Links the variable and the reference.
|
|
325
|
-
* And this reference is removed from `Scope#through`.
|
|
326
|
-
*/
|
|
327
|
-
reference.resolved = variable;
|
|
328
|
-
variable.references.push(reference);
|
|
283
|
+
const names = Object.keys(finalGlobals).filter(
|
|
284
|
+
name => finalGlobals[name] !== "off",
|
|
285
|
+
);
|
|
329
286
|
|
|
330
|
-
|
|
331
|
-
}
|
|
287
|
+
scopeManager.addGlobals(names);
|
|
332
288
|
|
|
333
|
-
|
|
334
|
-
});
|
|
289
|
+
const globalScope = scopeManager.scopes[0];
|
|
335
290
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
* implicitly by assigning values to undeclared variables in non-strict code).
|
|
339
|
-
* Since we augment the global scope using configuration, we need to remove
|
|
340
|
-
* the ones that were added by configuration, as they are either built-in
|
|
341
|
-
* or declared elsewhere, therefore not implicit.
|
|
342
|
-
* Since the "implicit" property was not documented, first we'll check if it exists
|
|
343
|
-
* because it's possible that not all custom scope managers create this property.
|
|
344
|
-
* If it exists, we assume it has properties `variables` and `set`. Property
|
|
345
|
-
* `left` is considered optional (for example, typescript-eslint's scope manage
|
|
346
|
-
* has this property named `leftToBeResolved`).
|
|
347
|
-
*/
|
|
348
|
-
const { implicit } = globalScope;
|
|
349
|
-
if (typeof implicit === "object" && implicit !== null) {
|
|
350
|
-
implicit.variables = implicit.variables.filter(variable => {
|
|
351
|
-
const name = variable.name;
|
|
352
|
-
if (globalScope.set.has(name)) {
|
|
353
|
-
implicit.set.delete(name);
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
return true;
|
|
357
|
-
});
|
|
291
|
+
for (const name of names) {
|
|
292
|
+
const variable = globalScope.set.get(name);
|
|
358
293
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
294
|
+
variable.eslintImplicitGlobalSetting = configGlobals[name];
|
|
295
|
+
variable.eslintExplicitGlobal = !!inlineGlobals[name];
|
|
296
|
+
variable.eslintExplicitGlobalComments = inlineGlobals[name]?.comments;
|
|
297
|
+
variable.writeable = finalGlobals[name] === "writable";
|
|
364
298
|
}
|
|
365
299
|
}
|
|
366
300
|
|
|
@@ -1162,6 +1096,15 @@ class SourceCode extends TokenStore {
|
|
|
1162
1096
|
: void 0,
|
|
1163
1097
|
languageOptions.globals,
|
|
1164
1098
|
);
|
|
1099
|
+
|
|
1100
|
+
/*
|
|
1101
|
+
* `normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would
|
|
1102
|
+
* typically be caught when validating a config anyway (validity for inline global comments is checked separately).
|
|
1103
|
+
*/
|
|
1104
|
+
for (const [name, value] of Object.entries(configGlobals)) {
|
|
1105
|
+
configGlobals[name] = normalizeConfigGlobal(value);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1165
1108
|
const varsCache = this[caches].get("vars");
|
|
1166
1109
|
|
|
1167
1110
|
varsCache.set("configGlobals", configGlobals);
|
|
@@ -1243,6 +1186,15 @@ class SourceCode extends TokenStore {
|
|
|
1243
1186
|
|
|
1244
1187
|
break;
|
|
1245
1188
|
}
|
|
1189
|
+
case "eslint-env": {
|
|
1190
|
+
problems.push({
|
|
1191
|
+
ruleId: null,
|
|
1192
|
+
loc: comment.loc,
|
|
1193
|
+
message:
|
|
1194
|
+
"/* eslint-env */ comments are no longer supported.",
|
|
1195
|
+
});
|
|
1196
|
+
break;
|
|
1197
|
+
}
|
|
1246
1198
|
|
|
1247
1199
|
// no default
|
|
1248
1200
|
}
|
|
@@ -1273,7 +1225,7 @@ class SourceCode extends TokenStore {
|
|
|
1273
1225
|
const exportedVariables = varsCache.get("exportedVariables");
|
|
1274
1226
|
const globalScope = this.scopeManager.scopes[0];
|
|
1275
1227
|
|
|
1276
|
-
addDeclaredGlobals(
|
|
1228
|
+
addDeclaredGlobals(this.scopeManager, configGlobals, inlineGlobals);
|
|
1277
1229
|
|
|
1278
1230
|
if (exportedVariables) {
|
|
1279
1231
|
markExportedVariables(globalScope, exportedVariables);
|
|
@@ -1303,7 +1255,7 @@ class SourceCode extends TokenStore {
|
|
|
1303
1255
|
new VisitNodeStep({
|
|
1304
1256
|
target: node,
|
|
1305
1257
|
phase: 1,
|
|
1306
|
-
args: [node
|
|
1258
|
+
args: [node],
|
|
1307
1259
|
}),
|
|
1308
1260
|
);
|
|
1309
1261
|
},
|
|
@@ -1312,7 +1264,7 @@ class SourceCode extends TokenStore {
|
|
|
1312
1264
|
new VisitNodeStep({
|
|
1313
1265
|
target: node,
|
|
1314
1266
|
phase: 2,
|
|
1315
|
-
args: [node
|
|
1267
|
+
args: [node],
|
|
1316
1268
|
}),
|
|
1317
1269
|
);
|
|
1318
1270
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"use strict";
|
|
6
6
|
|
|
7
7
|
//------------------------------------------------------------------------------
|
|
8
|
-
//
|
|
8
|
+
// Helpers
|
|
9
9
|
//------------------------------------------------------------------------------
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @param {number} location The location to search.
|
|
16
16
|
* @returns {number} The found index or `tokens.length`.
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
function search(tokens, location) {
|
|
19
19
|
for (
|
|
20
20
|
let minIndex = 0, maxIndex = tokens.length - 1;
|
|
21
21
|
minIndex <= maxIndex;
|
|
@@ -41,7 +41,7 @@ exports.search = function search(tokens, location) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
return tokens.length;
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Gets the index of the `startLoc` in `tokens`.
|
|
@@ -51,7 +51,10 @@ exports.search = function search(tokens, location) {
|
|
|
51
51
|
* @param {number} startLoc The location to get an index.
|
|
52
52
|
* @returns {number} The index.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
function getFirstIndex(tokens, indexMap, startLoc) {
|
|
55
|
+
if (startLoc === -1) {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
55
58
|
if (startLoc in indexMap) {
|
|
56
59
|
return indexMap[startLoc];
|
|
57
60
|
}
|
|
@@ -73,9 +76,13 @@ exports.getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) {
|
|
|
73
76
|
}
|
|
74
77
|
return index + 1;
|
|
75
78
|
}
|
|
76
|
-
return 0;
|
|
77
|
-
};
|
|
78
79
|
|
|
80
|
+
// Program node that doesn't start/end with a token or comment
|
|
81
|
+
if (startLoc === 0) {
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
return tokens.length;
|
|
85
|
+
}
|
|
79
86
|
/**
|
|
80
87
|
* Gets the index of the `endLoc` in `tokens`.
|
|
81
88
|
* The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well.
|
|
@@ -84,7 +91,10 @@ exports.getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) {
|
|
|
84
91
|
* @param {number} endLoc The location to get an index.
|
|
85
92
|
* @returns {number} The index.
|
|
86
93
|
*/
|
|
87
|
-
|
|
94
|
+
function getLastIndex(tokens, indexMap, endLoc) {
|
|
95
|
+
if (endLoc === -1) {
|
|
96
|
+
return tokens.length - 1;
|
|
97
|
+
}
|
|
88
98
|
if (endLoc in indexMap) {
|
|
89
99
|
return indexMap[endLoc] - 1;
|
|
90
100
|
}
|
|
@@ -106,5 +116,16 @@ exports.getLastIndex = function getLastIndex(tokens, indexMap, endLoc) {
|
|
|
106
116
|
}
|
|
107
117
|
return index;
|
|
108
118
|
}
|
|
119
|
+
|
|
120
|
+
// Program node that doesn't start/end with a token or comment
|
|
121
|
+
if (endLoc === 0) {
|
|
122
|
+
return -1;
|
|
123
|
+
}
|
|
109
124
|
return tokens.length - 1;
|
|
110
|
-
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//------------------------------------------------------------------------------
|
|
128
|
+
// Exports
|
|
129
|
+
//------------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
module.exports = { search, getFirstIndex, getLastIndex };
|
|
@@ -33,20 +33,6 @@ class FileContext {
|
|
|
33
33
|
*/
|
|
34
34
|
sourceCode;
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
* The parser options for the file being linted.
|
|
38
|
-
* @type {Record<string, unknown>}
|
|
39
|
-
* @deprecated Use `languageOptions` instead.
|
|
40
|
-
*/
|
|
41
|
-
parserOptions;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* The path to the parser used to parse this file.
|
|
45
|
-
* @type {string}
|
|
46
|
-
* @deprecated No longer supported.
|
|
47
|
-
*/
|
|
48
|
-
parserPath;
|
|
49
|
-
|
|
50
36
|
/**
|
|
51
37
|
* The language options used when parsing this file.
|
|
52
38
|
* @type {Record<string, unknown>}
|
|
@@ -66,8 +52,6 @@ class FileContext {
|
|
|
66
52
|
* @param {string} config.filename The filename of the file being linted.
|
|
67
53
|
* @param {string} config.physicalFilename The physical filename of the file being linted.
|
|
68
54
|
* @param {SourceCode} config.sourceCode The source code of the file being linted.
|
|
69
|
-
* @param {Record<string, unknown>} config.parserOptions The parser options for the file being linted.
|
|
70
|
-
* @param {string} config.parserPath The path to the parser used to parse this file.
|
|
71
55
|
* @param {Record<string, unknown>} config.languageOptions The language options used when parsing this file.
|
|
72
56
|
* @param {Record<string, unknown>} config.settings The settings for the file being linted.
|
|
73
57
|
*/
|
|
@@ -76,8 +60,6 @@ class FileContext {
|
|
|
76
60
|
filename,
|
|
77
61
|
physicalFilename,
|
|
78
62
|
sourceCode,
|
|
79
|
-
parserOptions,
|
|
80
|
-
parserPath,
|
|
81
63
|
languageOptions,
|
|
82
64
|
settings,
|
|
83
65
|
}) {
|
|
@@ -85,50 +67,12 @@ class FileContext {
|
|
|
85
67
|
this.filename = filename;
|
|
86
68
|
this.physicalFilename = physicalFilename;
|
|
87
69
|
this.sourceCode = sourceCode;
|
|
88
|
-
this.parserOptions = parserOptions;
|
|
89
|
-
this.parserPath = parserPath;
|
|
90
70
|
this.languageOptions = languageOptions;
|
|
91
71
|
this.settings = settings;
|
|
92
72
|
|
|
93
73
|
Object.freeze(this);
|
|
94
74
|
}
|
|
95
75
|
|
|
96
|
-
/**
|
|
97
|
-
* Gets the current working directory.
|
|
98
|
-
* @returns {string} The current working directory.
|
|
99
|
-
* @deprecated Use `cwd` instead.
|
|
100
|
-
*/
|
|
101
|
-
getCwd() {
|
|
102
|
-
return this.cwd;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Gets the filename of the file being linted.
|
|
107
|
-
* @returns {string} The filename of the file being linted.
|
|
108
|
-
* @deprecated Use `filename` instead.
|
|
109
|
-
*/
|
|
110
|
-
getFilename() {
|
|
111
|
-
return this.filename;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Gets the physical filename of the file being linted.
|
|
116
|
-
* @returns {string} The physical filename of the file being linted.
|
|
117
|
-
* @deprecated Use `physicalFilename` instead.
|
|
118
|
-
*/
|
|
119
|
-
getPhysicalFilename() {
|
|
120
|
-
return this.physicalFilename;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Gets the source code of the file being linted.
|
|
125
|
-
* @returns {SourceCode} The source code of the file being linted.
|
|
126
|
-
* @deprecated Use `sourceCode` instead.
|
|
127
|
-
*/
|
|
128
|
-
getSourceCode() {
|
|
129
|
-
return this.sourceCode;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
76
|
/**
|
|
133
77
|
* Creates a new object with the current object as the prototype and
|
|
134
78
|
* the specified properties as its own properties.
|
|
@@ -124,7 +124,6 @@ function createLintingProblem(options, severity, language) {
|
|
|
124
124
|
language,
|
|
125
125
|
),
|
|
126
126
|
severity,
|
|
127
|
-
nodeType: null,
|
|
128
127
|
};
|
|
129
128
|
}
|
|
130
129
|
|
|
@@ -340,7 +339,6 @@ function mapSuggestions(descriptor, sourceCode, messages) {
|
|
|
340
339
|
* @param {Object} options Information about the problem
|
|
341
340
|
* @param {string} options.ruleId Rule ID
|
|
342
341
|
* @param {(0|1|2)} options.severity Rule severity
|
|
343
|
-
* @param {(ASTNode|null)} options.node Node
|
|
344
342
|
* @param {string} options.message Error message
|
|
345
343
|
* @param {string} [options.messageId] The error message ID.
|
|
346
344
|
* @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
|
|
@@ -362,7 +360,6 @@ function createProblem(options) {
|
|
|
362
360
|
message: options.message,
|
|
363
361
|
line: options.loc.start.line + lineOffset,
|
|
364
362
|
column: options.loc.start.column + columnOffset,
|
|
365
|
-
nodeType: (options.node && options.node.type) || null,
|
|
366
363
|
};
|
|
367
364
|
|
|
368
365
|
/*
|
|
@@ -548,7 +545,6 @@ class FileReport {
|
|
|
548
545
|
createProblem({
|
|
549
546
|
ruleId,
|
|
550
547
|
severity,
|
|
551
|
-
node: descriptor.node,
|
|
552
548
|
message: interpolate(computedMessage, descriptor.data),
|
|
553
549
|
messageId: descriptor.messageId,
|
|
554
550
|
loc: descriptor.loc
|