eslint 9.6.0 → 9.7.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 +6 -7
- package/lib/languages/js/index.js +10 -5
- package/lib/languages/js/source-code/source-code.js +8 -2
- package/lib/linter/apply-disable-directives.js +6 -3
- package/lib/linter/linter.js +7 -3
- package/lib/linter/node-event-generator.js +2 -4
- package/lib/linter/vfile.js +7 -0
- package/lib/rules/no-restricted-imports.js +12 -5
- package/lib/rules/no-unused-vars.js +1 -1
- package/lib/rules/no-useless-backreference.js +81 -31
- package/lib/rules/utils/regular-expressions.js +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
@@ -39,7 +39,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
|
|
39
39
|
10. [License](#license)
|
40
40
|
11. [Team](#team)
|
41
41
|
12. [Sponsors](#sponsors)
|
42
|
-
13. [Technology Sponsors](#technology-sponsors)
|
42
|
+
13. [Technology Sponsors](#technology-sponsors) <!-- markdownlint-disable-line MD051 -->
|
43
43
|
|
44
44
|
## Installation and Usage
|
45
45
|
|
@@ -294,14 +294,13 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
294
294
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
295
295
|
<!--sponsorsstart-->
|
296
296
|
<h3>Platinum Sponsors</h3>
|
297
|
-
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="
|
297
|
+
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
|
298
298
|
<p><a href="#"><img src="https://images.opencollective.com/guest-bf377e88/avatar.png" alt="Eli Schleifer" height="96"></a> <a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a></p><h3>Silver Sponsors</h3>
|
299
299
|
<p><a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a> <a href="https://www.workleap.com"><img src="https://avatars.githubusercontent.com/u/53535748?u=d1e55d7661d724bf2281c1bfd33cb8f99fe2465f&v=4" alt="Workleap" height="64"></a></p><h3>Bronze Sponsors</h3>
|
300
300
|
<p><a href="https://www.notion.so"><img src="https://images.opencollective.com/notion/bf3b117/logo.png" alt="notion" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://usenextbase.com"><img src="https://avatars.githubusercontent.com/u/145838380?v=4" alt="Nextbase Starter Kit" height="32"></a></p>
|
301
301
|
<!--sponsorsend-->
|
302
302
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
* Password management is sponsored by [1Password](https://www.1password.com)
|
303
|
+
<!--techsponsorsstart-->
|
304
|
+
<h2>Technology Sponsors</h2>
|
305
|
+
<p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
|
306
|
+
<!--techsponsorsend-->
|
@@ -20,7 +20,9 @@ const { validateLanguageOptions } = require("./validate-language-options");
|
|
20
20
|
// Type Definitions
|
21
21
|
//-----------------------------------------------------------------------------
|
22
22
|
|
23
|
-
/** @typedef {import("
|
23
|
+
/** @typedef {import("@eslint/core").File} File */
|
24
|
+
/** @typedef {import("@eslint/core").Language} Language */
|
25
|
+
/** @typedef {import("@eslint/core").OkParseResult} OkParseResult */
|
24
26
|
|
25
27
|
//-----------------------------------------------------------------------------
|
26
28
|
// Helpers
|
@@ -56,6 +58,9 @@ function analyzeScope(ast, languageOptions, visitorKeys) {
|
|
56
58
|
// Exports
|
57
59
|
//-----------------------------------------------------------------------------
|
58
60
|
|
61
|
+
/**
|
62
|
+
* @type {Language}
|
63
|
+
*/
|
59
64
|
module.exports = {
|
60
65
|
|
61
66
|
fileType: "text",
|
@@ -143,7 +148,7 @@ module.exports = {
|
|
143
148
|
|
144
149
|
/**
|
145
150
|
* Parses the given file into an AST.
|
146
|
-
* @param {
|
151
|
+
* @param {File} file The virtual file to parse.
|
147
152
|
* @param {Object} options Additional options passed from ESLint.
|
148
153
|
* @param {LanguageOptions} options.languageOptions The language options.
|
149
154
|
* @returns {Object} The result of parsing.
|
@@ -200,7 +205,7 @@ module.exports = {
|
|
200
205
|
} catch (ex) {
|
201
206
|
|
202
207
|
// If the message includes a leading line number, strip it:
|
203
|
-
const message =
|
208
|
+
const message = ex.message.replace(/^line \d+:/iu, "").trim();
|
204
209
|
|
205
210
|
debug("%s\n%s", message, ex.stack);
|
206
211
|
|
@@ -218,8 +223,8 @@ module.exports = {
|
|
218
223
|
|
219
224
|
/**
|
220
225
|
* Creates a new `SourceCode` object from the given information.
|
221
|
-
* @param {
|
222
|
-
* @param {
|
226
|
+
* @param {File} file The virtual file to create a `SourceCode` object from.
|
227
|
+
* @param {OkParseResult} parseResult The result returned from `parse()`.
|
223
228
|
* @param {Object} options Additional options passed from ESLint.
|
224
229
|
* @param {LanguageOptions} options.languageOptions The language options.
|
225
230
|
* @returns {SourceCode} The new `SourceCode` object.
|
@@ -29,6 +29,10 @@ const
|
|
29
29
|
//------------------------------------------------------------------------------
|
30
30
|
|
31
31
|
/** @typedef {import("eslint-scope").Variable} Variable */
|
32
|
+
/** @typedef {import("eslint-scope").Scope} Scope */
|
33
|
+
/** @typedef {import("@eslint/core").SourceCode} ISourceCode */
|
34
|
+
/** @typedef {import("@eslint/core").Directive} IDirective */
|
35
|
+
/** @typedef {import("@eslint/core").TraversalStep} ITraversalStep */
|
32
36
|
|
33
37
|
//------------------------------------------------------------------------------
|
34
38
|
// Private
|
@@ -373,6 +377,7 @@ class TraversalStep {
|
|
373
377
|
|
374
378
|
/**
|
375
379
|
* A class to represent a directive comment.
|
380
|
+
* @implements {IDirective}
|
376
381
|
*/
|
377
382
|
class Directive {
|
378
383
|
|
@@ -429,12 +434,13 @@ const caches = Symbol("caches");
|
|
429
434
|
|
430
435
|
/**
|
431
436
|
* Represents parsed source code.
|
437
|
+
* @implements {ISourceCode}
|
432
438
|
*/
|
433
439
|
class SourceCode extends TokenStore {
|
434
440
|
|
435
441
|
/**
|
436
442
|
* The cache of steps that were taken while traversing the source code.
|
437
|
-
* @type {Array<
|
443
|
+
* @type {Array<ITraversalStep>}
|
438
444
|
*/
|
439
445
|
#steps;
|
440
446
|
|
@@ -838,7 +844,7 @@ class SourceCode extends TokenStore {
|
|
838
844
|
/**
|
839
845
|
* Gets the scope for the given node
|
840
846
|
* @param {ASTNode} currentNode The node to get the scope of
|
841
|
-
* @returns {
|
847
|
+
* @returns {Scope} The scope information for this node
|
842
848
|
* @throws {TypeError} If the `currentNode` argument is missing.
|
843
849
|
*/
|
844
850
|
getScope(currentNode) {
|
@@ -10,6 +10,9 @@
|
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
12
|
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
13
|
+
/** @typedef {import("@eslint/core").Language} Language */
|
14
|
+
/** @typedef {import("@eslint/core").Position} Position */
|
15
|
+
/** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
|
13
16
|
|
14
17
|
//------------------------------------------------------------------------------
|
15
18
|
// Module Definition
|
@@ -24,8 +27,8 @@ const {
|
|
24
27
|
|
25
28
|
/**
|
26
29
|
* Compares the locations of two objects in a source file
|
27
|
-
* @param {
|
28
|
-
* @param {
|
30
|
+
* @param {Position} itemA The first object
|
31
|
+
* @param {Position} itemB The second object
|
29
32
|
* @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if
|
30
33
|
* itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location.
|
31
34
|
*/
|
@@ -418,7 +421,7 @@ function applyDirectives(options) {
|
|
418
421
|
* @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
|
419
422
|
* A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
|
420
423
|
* @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
|
421
|
-
* @param {
|
424
|
+
* @param {RulesConfig} options.configuredRules The rules configuration.
|
422
425
|
* @param {Function} options.ruleFilter A predicate function to filter which rules should be executed.
|
423
426
|
* @param {boolean} options.disableFixes If true, it doesn't make `fix` properties.
|
424
427
|
* @returns {{ruleId: (string|null), line: number, column: number, suppressions?: {kind: string, justification: string}}[]}
|
package/lib/linter/linter.js
CHANGED
@@ -72,6 +72,10 @@ const STEP_KIND_CALL = 2;
|
|
72
72
|
/** @typedef {import("../shared/types").Processor} Processor */
|
73
73
|
/** @typedef {import("../shared/types").Rule} Rule */
|
74
74
|
/** @typedef {import("../shared/types").Times} Times */
|
75
|
+
/** @typedef {import("@eslint/core").Language} Language */
|
76
|
+
/** @typedef {import("@eslint/core").RuleSeverity} RuleSeverity */
|
77
|
+
/** @typedef {import("@eslint/core").RuleConfig} RuleConfig */
|
78
|
+
|
75
79
|
|
76
80
|
/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
|
77
81
|
/**
|
@@ -276,7 +280,7 @@ function updateLocationInformation({ line, column, endLine, endColumn }, languag
|
|
276
280
|
* @param {string} [options.ruleId] the ruleId to report
|
277
281
|
* @param {Object} [options.loc] the loc to report
|
278
282
|
* @param {string} [options.message] the error message to report
|
279
|
-
* @param {
|
283
|
+
* @param {RuleSeverity} [options.severity] the error message to report
|
280
284
|
* @param {Language} [options.language] the language to use to adjust the location information
|
281
285
|
* @returns {LintMessage} created problem, returns a missing-rule problem if only provided ruleId.
|
282
286
|
* @private
|
@@ -877,7 +881,7 @@ function storeTime(time, timeOpts, slots) {
|
|
877
881
|
|
878
882
|
/**
|
879
883
|
* Get the options for a rule (not including severity), if any
|
880
|
-
* @param {
|
884
|
+
* @param {RuleConfig} ruleConfig rule configuration
|
881
885
|
* @returns {Array} of rule options, empty Array if none
|
882
886
|
*/
|
883
887
|
function getRuleOptions(ruleConfig) {
|
@@ -941,7 +945,7 @@ function parse(file, language, languageOptions) {
|
|
941
945
|
nodeType: null,
|
942
946
|
fatal: true,
|
943
947
|
severity: 2,
|
944
|
-
message: error.message
|
948
|
+
message: `Parsing error: ${error.message}`,
|
945
949
|
line: error.line,
|
946
950
|
column: error.column
|
947
951
|
}))
|
@@ -334,10 +334,8 @@ class NodeEventGenerator {
|
|
334
334
|
* @returns {void}
|
335
335
|
*/
|
336
336
|
enterNode(node) {
|
337
|
-
if (node.parent) {
|
338
|
-
this.currentAncestry.unshift(node.parent);
|
339
|
-
}
|
340
337
|
this.applySelectors(node, false);
|
338
|
+
this.currentAncestry.unshift(node);
|
341
339
|
}
|
342
340
|
|
343
341
|
/**
|
@@ -346,8 +344,8 @@ class NodeEventGenerator {
|
|
346
344
|
* @returns {void}
|
347
345
|
*/
|
348
346
|
leaveNode(node) {
|
349
|
-
this.applySelectors(node, true);
|
350
347
|
this.currentAncestry.shift();
|
348
|
+
this.applySelectors(node, true);
|
351
349
|
}
|
352
350
|
}
|
353
351
|
|
package/lib/linter/vfile.js
CHANGED
@@ -5,6 +5,12 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//-----------------------------------------------------------------------------
|
9
|
+
// Type Definitions
|
10
|
+
//-----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/** @typedef {import("@eslint/core").File} File */
|
13
|
+
|
8
14
|
//------------------------------------------------------------------------------
|
9
15
|
// Helpers
|
10
16
|
//------------------------------------------------------------------------------
|
@@ -54,6 +60,7 @@ function stripUnicodeBOM(value) {
|
|
54
60
|
|
55
61
|
/**
|
56
62
|
* Represents a virtual file inside of ESLint.
|
63
|
+
* @implements {File}
|
57
64
|
*/
|
58
65
|
class VFile {
|
59
66
|
|
@@ -89,6 +89,9 @@ const arrayOfStringsOrObjectPatterns = {
|
|
89
89
|
minItems: 1,
|
90
90
|
uniqueItems: true
|
91
91
|
},
|
92
|
+
regex: {
|
93
|
+
type: "string"
|
94
|
+
},
|
92
95
|
importNamePattern: {
|
93
96
|
type: "string"
|
94
97
|
},
|
@@ -104,7 +107,6 @@ const arrayOfStringsOrObjectPatterns = {
|
|
104
107
|
}
|
105
108
|
},
|
106
109
|
additionalProperties: false,
|
107
|
-
required: ["group"],
|
108
110
|
not: {
|
109
111
|
anyOf: [
|
110
112
|
{ required: ["importNames", "allowImportNames"] },
|
@@ -113,7 +115,11 @@ const arrayOfStringsOrObjectPatterns = {
|
|
113
115
|
{ required: ["importNamePattern", "allowImportNames"] },
|
114
116
|
{ required: ["allowImportNames", "allowImportNamePattern"] }
|
115
117
|
]
|
116
|
-
}
|
118
|
+
},
|
119
|
+
oneOf: [
|
120
|
+
{ required: ["group"] },
|
121
|
+
{ required: ["regex"] }
|
122
|
+
]
|
117
123
|
},
|
118
124
|
uniqueItems: true
|
119
125
|
}
|
@@ -235,9 +241,10 @@ module.exports = {
|
|
235
241
|
|
236
242
|
// relative paths are supported for this rule
|
237
243
|
const restrictedPatternGroups = restrictedPatterns.map(
|
238
|
-
({ group, message, caseSensitive, importNames, importNamePattern, allowImportNames, allowImportNamePattern }) => (
|
244
|
+
({ group, regex, message, caseSensitive, importNames, importNamePattern, allowImportNames, allowImportNamePattern }) => (
|
239
245
|
{
|
240
|
-
matcher: ignore({ allowRelativePaths: true, ignorecase: !caseSensitive }).add(group),
|
246
|
+
...(group ? { matcher: ignore({ allowRelativePaths: true, ignorecase: !caseSensitive }).add(group) } : {}),
|
247
|
+
...(typeof regex === "string" ? { regexMatcher: new RegExp(regex, caseSensitive ? "u" : "iu") } : {}),
|
241
248
|
customMessage: message,
|
242
249
|
importNames,
|
243
250
|
importNamePattern,
|
@@ -493,7 +500,7 @@ module.exports = {
|
|
493
500
|
* @private
|
494
501
|
*/
|
495
502
|
function isRestrictedPattern(importSource, group) {
|
496
|
-
return group.matcher.ignores(importSource);
|
503
|
+
return group.regexMatcher ? group.regexMatcher.test(importSource) : group.matcher.ignores(importSource);
|
497
504
|
}
|
498
505
|
|
499
506
|
/**
|
@@ -340,7 +340,7 @@ module.exports = {
|
|
340
340
|
/**
|
341
341
|
* Determines if a variable has a sibling rest property
|
342
342
|
* @param {Variable} variable eslint-scope variable object.
|
343
|
-
* @returns {boolean} True if the variable
|
343
|
+
* @returns {boolean} True if the variable has a sibling rest property, false if not.
|
344
344
|
* @private
|
345
345
|
*/
|
346
346
|
function hasRestSpreadSibling(variable) {
|
@@ -72,11 +72,11 @@ module.exports = {
|
|
72
72
|
schema: [],
|
73
73
|
|
74
74
|
messages: {
|
75
|
-
nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' from within that group.",
|
76
|
-
forward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears later in the pattern.",
|
77
|
-
backward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears before in the same lookbehind.",
|
78
|
-
disjunctive: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in another alternative.",
|
79
|
-
intoNegativeLookaround: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in a negative lookaround."
|
75
|
+
nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} from within that group.",
|
76
|
+
forward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears later in the pattern.",
|
77
|
+
backward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears before in the same lookbehind.",
|
78
|
+
disjunctive: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in another alternative.",
|
79
|
+
intoNegativeLookaround: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in a negative lookaround."
|
80
80
|
}
|
81
81
|
},
|
82
82
|
|
@@ -104,16 +104,21 @@ module.exports = {
|
|
104
104
|
|
105
105
|
visitRegExpAST(regExpAST, {
|
106
106
|
onBackreferenceEnter(bref) {
|
107
|
-
const
|
108
|
-
brefPath = getPathToRoot(bref)
|
109
|
-
groupPath = getPathToRoot(group);
|
110
|
-
let messageId = null;
|
107
|
+
const groups = [bref.resolved].flat(),
|
108
|
+
brefPath = getPathToRoot(bref);
|
111
109
|
|
112
|
-
|
110
|
+
const problems = groups.map(group => {
|
111
|
+
const groupPath = getPathToRoot(group);
|
112
|
+
|
113
|
+
if (brefPath.includes(group)) {
|
114
|
+
|
115
|
+
// group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match.
|
116
|
+
return {
|
117
|
+
messageId: "nested",
|
118
|
+
group
|
119
|
+
};
|
120
|
+
}
|
113
121
|
|
114
|
-
// group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match.
|
115
|
-
messageId = "nested";
|
116
|
-
} else {
|
117
122
|
|
118
123
|
// Start from the root to find the lowest common ancestor.
|
119
124
|
let i = brefPath.length - 1,
|
@@ -130,35 +135,80 @@ module.exports = {
|
|
130
135
|
lowestCommonLookaround = commonPath.find(isLookaround),
|
131
136
|
isMatchingBackward = lowestCommonLookaround && lowestCommonLookaround.kind === "lookbehind";
|
132
137
|
|
138
|
+
if (groupCut.at(-1).type === "Alternative") {
|
139
|
+
|
140
|
+
// group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.
|
141
|
+
return {
|
142
|
+
messageId: "disjunctive",
|
143
|
+
group
|
144
|
+
};
|
145
|
+
}
|
133
146
|
if (!isMatchingBackward && bref.end <= group.start) {
|
134
147
|
|
135
148
|
// bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match.
|
136
|
-
|
137
|
-
|
149
|
+
return {
|
150
|
+
messageId: "forward",
|
151
|
+
group
|
152
|
+
};
|
153
|
+
}
|
154
|
+
if (isMatchingBackward && group.end <= bref.start) {
|
138
155
|
|
139
156
|
// the opposite of the previous when the regex is matching backward in a lookbehind context.
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
157
|
+
return {
|
158
|
+
messageId: "backward",
|
159
|
+
group
|
160
|
+
};
|
161
|
+
}
|
162
|
+
if (groupCut.some(isNegativeLookaround)) {
|
146
163
|
|
147
164
|
// group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match.
|
148
|
-
|
165
|
+
return {
|
166
|
+
messageId: "intoNegativeLookaround",
|
167
|
+
group
|
168
|
+
};
|
149
169
|
}
|
170
|
+
|
171
|
+
return null;
|
172
|
+
});
|
173
|
+
|
174
|
+
if (problems.length === 0 || problems.some(problem => !problem)) {
|
175
|
+
|
176
|
+
// If there are no problems or no problems with any group then do not report it.
|
177
|
+
return;
|
150
178
|
}
|
151
179
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
180
|
+
let problemsToReport;
|
181
|
+
|
182
|
+
// Gets problems that appear in the same disjunction.
|
183
|
+
const problemsInSameDisjunction = problems.filter(problem => problem.messageId !== "disjunctive");
|
184
|
+
|
185
|
+
if (problemsInSameDisjunction.length) {
|
186
|
+
|
187
|
+
// Only report problems that appear in the same disjunction.
|
188
|
+
problemsToReport = problemsInSameDisjunction;
|
189
|
+
} else {
|
190
|
+
|
191
|
+
// If all groups appear in different disjunctions, report it.
|
192
|
+
problemsToReport = problems;
|
161
193
|
}
|
194
|
+
|
195
|
+
const [{ messageId, group }, ...other] = problemsToReport;
|
196
|
+
let otherGroups = "";
|
197
|
+
|
198
|
+
if (other.length === 1) {
|
199
|
+
otherGroups = " and another group";
|
200
|
+
} else if (other.length > 1) {
|
201
|
+
otherGroups = ` and other ${other.length} groups`;
|
202
|
+
}
|
203
|
+
context.report({
|
204
|
+
node,
|
205
|
+
messageId,
|
206
|
+
data: {
|
207
|
+
bref: bref.raw,
|
208
|
+
group: group.raw,
|
209
|
+
otherGroups
|
210
|
+
}
|
211
|
+
});
|
162
212
|
}
|
163
213
|
});
|
164
214
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "9.
|
3
|
+
"version": "9.7.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -67,10 +67,10 @@
|
|
67
67
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
68
68
|
"dependencies": {
|
69
69
|
"@eslint-community/eslint-utils": "^4.2.0",
|
70
|
-
"@eslint-community/regexpp": "^4.
|
70
|
+
"@eslint-community/regexpp": "^4.11.0",
|
71
71
|
"@eslint/config-array": "^0.17.0",
|
72
72
|
"@eslint/eslintrc": "^3.1.0",
|
73
|
-
"@eslint/js": "9.
|
73
|
+
"@eslint/js": "9.7.0",
|
74
74
|
"@humanwhocodes/module-importer": "^1.0.1",
|
75
75
|
"@humanwhocodes/retry": "^0.3.0",
|
76
76
|
"@nodelib/fs.walk": "^1.2.8",
|
@@ -79,7 +79,7 @@
|
|
79
79
|
"cross-spawn": "^7.0.2",
|
80
80
|
"debug": "^4.3.2",
|
81
81
|
"escape-string-regexp": "^4.0.0",
|
82
|
-
"eslint-scope": "^8.0.
|
82
|
+
"eslint-scope": "^8.0.2",
|
83
83
|
"eslint-visitor-keys": "^4.0.0",
|
84
84
|
"espree": "^10.1.0",
|
85
85
|
"esquery": "^1.5.0",
|
@@ -104,6 +104,7 @@
|
|
104
104
|
"devDependencies": {
|
105
105
|
"@babel/core": "^7.4.3",
|
106
106
|
"@babel/preset-env": "^7.4.3",
|
107
|
+
"@eslint/core": "^0.1.0",
|
107
108
|
"@types/estree": "^1.0.5",
|
108
109
|
"@types/node": "^20.11.5",
|
109
110
|
"@wdio/browser-runner": "^8.38.3",
|