eslint 8.33.0 → 8.35.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 +8 -4
- package/lib/cli-engine/cli-engine.js +2 -2
- package/lib/cli-engine/file-enumerator.js +2 -2
- package/lib/config/flat-config-array.js +14 -8
- package/lib/eslint/eslint-helpers.js +1 -38
- package/lib/rules/array-callback-return.js +1 -1
- package/lib/rules/array-element-newline.js +1 -0
- package/lib/rules/lines-around-comment.js +11 -0
- package/lib/rules/logical-assignment-operators.js +1 -1
- package/lib/rules/no-constant-binary-expression.js +32 -25
- package/lib/rules/no-eval.js +1 -1
- package/lib/rules/no-extra-parens.js +34 -1
- package/lib/rules/no-useless-return.js +1 -1
- package/messages/no-config-found.js +1 -1
- package/package.json +8 -3
- package/conf/eslint-all.js +0 -31
- package/conf/eslint-recommended.js +0 -76
package/README.md
CHANGED
@@ -16,8 +16,7 @@
|
|
16
16
|
[Report Bugs](https://eslint.org/docs/latest/contribute/report-bugs) |
|
17
17
|
[Code of Conduct](https://eslint.org/conduct) |
|
18
18
|
[Twitter](https://twitter.com/geteslint) |
|
19
|
-
[
|
20
|
-
[Chat Room](https://eslint.org/chat)
|
19
|
+
[Discord](https://eslint.org/chat)
|
21
20
|
|
22
21
|
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
|
23
22
|
|
@@ -129,7 +128,7 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a
|
|
129
128
|
|
130
129
|
### Where to ask for help?
|
131
130
|
|
132
|
-
|
131
|
+
Open a [discussion](https://github.com/eslint/eslint/discussions) or stop by our [Discord server](https://eslint.org/chat).
|
133
132
|
|
134
133
|
### Why doesn't ESLint lock dependency versions?
|
135
134
|
|
@@ -255,6 +254,11 @@ Bryan Mishkin
|
|
255
254
|
Sara Soueidan
|
256
255
|
</a>
|
257
256
|
</td><td align="center" valign="top" width="11%">
|
257
|
+
<a href="https://github.com/fasttime">
|
258
|
+
<img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
|
259
|
+
Francesco Trotta
|
260
|
+
</a>
|
261
|
+
</td><td align="center" valign="top" width="11%">
|
258
262
|
<a href="https://github.com/yeonjuan">
|
259
263
|
<img src="https://github.com/yeonjuan.png?s=75" width="75" height="75"><br />
|
260
264
|
YeonJuan
|
@@ -294,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
294
298
|
<p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
295
299
|
<p><a href="https://ridicorp.com/career/"><img src="https://images.opencollective.com/ridi-corporation/175dcf3/logo.png" alt="RIDI" height="96"></a> <a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
|
296
300
|
<p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
|
297
|
-
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" 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://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" 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://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
|
301
|
+
<p><a href="https://paydaysay.com/"><img src="https://images.opencollective.com/payday-say-organization/9cd2467/logo.png" alt="PayDay Say" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" 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://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" 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://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
|
298
302
|
<!--sponsorsend-->
|
299
303
|
|
300
304
|
## Technology Sponsors
|
@@ -615,8 +615,8 @@ class CLIEngine {
|
|
615
615
|
useEslintrc: options.useEslintrc,
|
616
616
|
builtInRules,
|
617
617
|
loadRules,
|
618
|
-
getEslintRecommendedConfig: () => require("
|
619
|
-
getEslintAllConfig: () => require("
|
618
|
+
getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
|
619
|
+
getEslintAllConfig: () => require("@eslint/js").configs.all
|
620
620
|
});
|
621
621
|
const fileEnumerator = new FileEnumerator({
|
622
622
|
configArrayFactory,
|
@@ -217,8 +217,8 @@ class FileEnumerator {
|
|
217
217
|
cwd = process.cwd(),
|
218
218
|
configArrayFactory = new CascadingConfigArrayFactory({
|
219
219
|
cwd,
|
220
|
-
getEslintRecommendedConfig: () => require("
|
221
|
-
getEslintAllConfig: () => require("
|
220
|
+
getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
|
221
|
+
getEslintAllConfig: () => require("@eslint/js").configs.all
|
222
222
|
}),
|
223
223
|
extensions = null,
|
224
224
|
globInputPaths = true,
|
@@ -13,7 +13,7 @@ const { ConfigArray, ConfigArraySymbol } = require("@humanwhocodes/config-array"
|
|
13
13
|
const { flatConfigSchema } = require("./flat-config-schema");
|
14
14
|
const { RuleValidator } = require("./rule-validator");
|
15
15
|
const { defaultConfig } = require("./default-config");
|
16
|
-
const
|
16
|
+
const jsPlugin = require("@eslint/js");
|
17
17
|
|
18
18
|
//-----------------------------------------------------------------------------
|
19
19
|
// Helpers
|
@@ -96,17 +96,23 @@ class FlatConfigArray extends ConfigArray {
|
|
96
96
|
*/
|
97
97
|
[ConfigArraySymbol.preprocessConfig](config) {
|
98
98
|
if (config === "eslint:recommended") {
|
99
|
-
|
99
|
+
|
100
|
+
// if we are in a Node.js environment warn the user
|
101
|
+
if (typeof process !== "undefined" && process.emitWarning) {
|
102
|
+
process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
|
103
|
+
}
|
104
|
+
|
105
|
+
return jsPlugin.configs.recommended;
|
100
106
|
}
|
101
107
|
|
102
108
|
if (config === "eslint:all") {
|
103
109
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
return
|
110
|
+
// if we are in a Node.js environment warn the user
|
111
|
+
if (typeof process !== "undefined" && process.emitWarning) {
|
112
|
+
process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
|
113
|
+
}
|
114
|
+
|
115
|
+
return jsPlugin.configs.all;
|
110
116
|
}
|
111
117
|
|
112
118
|
/*
|
@@ -223,7 +223,7 @@ function globMatch({ basePath, pattern }) {
|
|
223
223
|
* should be thrown when a pattern is unmatched.
|
224
224
|
* @returns {Promise<Array<string>>} An array of matching file paths
|
225
225
|
* or an empty array if there are no matches.
|
226
|
-
* @throws {
|
226
|
+
* @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
|
227
227
|
* match any files.
|
228
228
|
*/
|
229
229
|
async function globSearch({
|
@@ -568,41 +568,6 @@ async function findFiles({
|
|
568
568
|
];
|
569
569
|
}
|
570
570
|
|
571
|
-
|
572
|
-
/**
|
573
|
-
* Checks whether a file exists at the given location
|
574
|
-
* @param {string} resolvedPath A path from the CWD
|
575
|
-
* @throws {Error} As thrown by `fs.statSync` or `fs.isFile`.
|
576
|
-
* @returns {boolean} `true` if a file exists
|
577
|
-
*/
|
578
|
-
function fileExists(resolvedPath) {
|
579
|
-
try {
|
580
|
-
return fs.statSync(resolvedPath).isFile();
|
581
|
-
} catch (error) {
|
582
|
-
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
583
|
-
return false;
|
584
|
-
}
|
585
|
-
throw error;
|
586
|
-
}
|
587
|
-
}
|
588
|
-
|
589
|
-
/**
|
590
|
-
* Checks whether a directory exists at the given location
|
591
|
-
* @param {string} resolvedPath A path from the CWD
|
592
|
-
* @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`.
|
593
|
-
* @returns {boolean} `true` if a directory exists
|
594
|
-
*/
|
595
|
-
function directoryExists(resolvedPath) {
|
596
|
-
try {
|
597
|
-
return fs.statSync(resolvedPath).isDirectory();
|
598
|
-
} catch (error) {
|
599
|
-
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
600
|
-
return false;
|
601
|
-
}
|
602
|
-
throw error;
|
603
|
-
}
|
604
|
-
}
|
605
|
-
|
606
571
|
//-----------------------------------------------------------------------------
|
607
572
|
// Results-related Helpers
|
608
573
|
//-----------------------------------------------------------------------------
|
@@ -924,8 +889,6 @@ function getCacheFile(cacheFile, cwd) {
|
|
924
889
|
|
925
890
|
module.exports = {
|
926
891
|
isGlobPattern,
|
927
|
-
directoryExists,
|
928
|
-
fileExists,
|
929
892
|
findFiles,
|
930
893
|
|
931
894
|
isNonEmptyString,
|
@@ -16,7 +16,7 @@ const astUtils = require("./utils/ast-utils");
|
|
16
16
|
//------------------------------------------------------------------------------
|
17
17
|
|
18
18
|
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
|
19
|
-
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u;
|
19
|
+
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u;
|
20
20
|
|
21
21
|
/**
|
22
22
|
* Checks a given code path segment is reachable.
|
@@ -113,6 +113,10 @@ module.exports = {
|
|
113
113
|
},
|
114
114
|
applyDefaultIgnorePatterns: {
|
115
115
|
type: "boolean"
|
116
|
+
},
|
117
|
+
afterHashbangComment: {
|
118
|
+
type: "boolean",
|
119
|
+
default: false
|
116
120
|
}
|
117
121
|
},
|
118
122
|
additionalProperties: false
|
@@ -449,6 +453,13 @@ module.exports = {
|
|
449
453
|
before: options.beforeBlockComment
|
450
454
|
});
|
451
455
|
}
|
456
|
+
} else if (token.type === "Shebang") {
|
457
|
+
if (options.afterHashbangComment) {
|
458
|
+
checkForEmptyLine(token, {
|
459
|
+
after: options.afterHashbangComment,
|
460
|
+
before: false
|
461
|
+
});
|
462
|
+
}
|
452
463
|
}
|
453
464
|
});
|
454
465
|
}
|
@@ -112,7 +112,7 @@ function isBooleanCast(expression, scope) {
|
|
112
112
|
/**
|
113
113
|
* Returns true for:
|
114
114
|
* truthiness checks: value, Boolean(value), !!value
|
115
|
-
*
|
115
|
+
* falsiness checks: !value, !Boolean(value)
|
116
116
|
* nullish checks: value == null, value === undefined || value === null
|
117
117
|
* @param {ASTNode} expression Test condition
|
118
118
|
* @param {import('eslint-scope').Scope} scope Scope of the expression
|
@@ -14,6 +14,23 @@ const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set(["+", "-", "*", "/", "%", "|"
|
|
14
14
|
// Helpers
|
15
15
|
//------------------------------------------------------------------------------
|
16
16
|
|
17
|
+
/**
|
18
|
+
* Checks whether or not a node is `null` or `undefined`. Similar to the one
|
19
|
+
* found in ast-utils.js, but this one correctly handles the edge case that
|
20
|
+
* `undefined` has been redefined.
|
21
|
+
* @param {Scope} scope Scope in which the expression was found.
|
22
|
+
* @param {ASTNode} node A node to check.
|
23
|
+
* @returns {boolean} Whether or not the node is a `null` or `undefined`.
|
24
|
+
* @public
|
25
|
+
*/
|
26
|
+
function isNullOrUndefined(scope, node) {
|
27
|
+
return (
|
28
|
+
isNullLiteral(node) ||
|
29
|
+
(node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
|
30
|
+
(node.type === "UnaryExpression" && node.operator === "void")
|
31
|
+
);
|
32
|
+
}
|
33
|
+
|
17
34
|
/**
|
18
35
|
* Test if an AST node has a statically knowable constant nullishness. Meaning,
|
19
36
|
* it will always resolve to a constant value of either: `null`, `undefined`
|
@@ -21,9 +38,14 @@ const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set(["+", "-", "*", "/", "%", "|"
|
|
21
38
|
* three states at runtime would return `false`.
|
22
39
|
* @param {Scope} scope The scope in which the node was found.
|
23
40
|
* @param {ASTNode} node The AST node being tested.
|
41
|
+
* @param {boolean} nonNullish if `true` then nullish values are not considered constant.
|
24
42
|
* @returns {boolean} Does `node` have constant nullishness?
|
25
43
|
*/
|
26
|
-
function hasConstantNullishness(scope, node) {
|
44
|
+
function hasConstantNullishness(scope, node, nonNullish) {
|
45
|
+
if (nonNullish && isNullOrUndefined(scope, node)) {
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
|
27
49
|
switch (node.type) {
|
28
50
|
case "ObjectExpression": // Objects are never nullish
|
29
51
|
case "ArrayExpression": // Arrays are never nullish
|
@@ -45,9 +67,12 @@ function hasConstantNullishness(scope, node) {
|
|
45
67
|
return (functionName === "Boolean" || functionName === "String" || functionName === "Number") &&
|
46
68
|
isReferenceToGlobalVariable(scope, node.callee);
|
47
69
|
}
|
70
|
+
case "LogicalExpression": {
|
71
|
+
return node.operator === "??" && hasConstantNullishness(scope, node.right, true);
|
72
|
+
}
|
48
73
|
case "AssignmentExpression":
|
49
74
|
if (node.operator === "=") {
|
50
|
-
return hasConstantNullishness(scope, node.right);
|
75
|
+
return hasConstantNullishness(scope, node.right, nonNullish);
|
51
76
|
}
|
52
77
|
|
53
78
|
/*
|
@@ -80,7 +105,7 @@ function hasConstantNullishness(scope, node) {
|
|
80
105
|
case "SequenceExpression": {
|
81
106
|
const last = node.expressions[node.expressions.length - 1];
|
82
107
|
|
83
|
-
return hasConstantNullishness(scope, last);
|
108
|
+
return hasConstantNullishness(scope, last, nonNullish);
|
84
109
|
}
|
85
110
|
case "Identifier":
|
86
111
|
return node.name === "undefined" && isReferenceToGlobalVariable(scope, node);
|
@@ -348,7 +373,7 @@ function isAlwaysNew(scope, node) {
|
|
348
373
|
* user-defined constructors could return a sentinel
|
349
374
|
* object.
|
350
375
|
*
|
351
|
-
* Catching these is especially useful for primitive
|
376
|
+
* Catching these is especially useful for primitive constructors
|
352
377
|
* which return boxed values, a surprising gotcha' in JavaScript.
|
353
378
|
*/
|
354
379
|
return Object.hasOwnProperty.call(globals.builtin, node.callee.name) &&
|
@@ -378,24 +403,6 @@ function isAlwaysNew(scope, node) {
|
|
378
403
|
}
|
379
404
|
}
|
380
405
|
|
381
|
-
/**
|
382
|
-
* Checks whether or not a node is `null` or `undefined`. Similar to the one
|
383
|
-
* found in ast-utils.js, but this one correctly handles the edge case that
|
384
|
-
* `undefined` has been redefined.
|
385
|
-
* @param {Scope} scope Scope in which the expression was found.
|
386
|
-
* @param {ASTNode} node A node to check.
|
387
|
-
* @returns {boolean} Whether or not the node is a `null` or `undefined`.
|
388
|
-
* @public
|
389
|
-
*/
|
390
|
-
function isNullOrUndefined(scope, node) {
|
391
|
-
return (
|
392
|
-
isNullLiteral(node) ||
|
393
|
-
(node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
|
394
|
-
(node.type === "UnaryExpression" && node.operator === "void")
|
395
|
-
);
|
396
|
-
}
|
397
|
-
|
398
|
-
|
399
406
|
/**
|
400
407
|
* Checks if one operand will cause the result to be constant.
|
401
408
|
* @param {Scope} scope Scope in which the expression was found.
|
@@ -407,14 +414,14 @@ function isNullOrUndefined(scope, node) {
|
|
407
414
|
function findBinaryExpressionConstantOperand(scope, a, b, operator) {
|
408
415
|
if (operator === "==" || operator === "!=") {
|
409
416
|
if (
|
410
|
-
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
|
417
|
+
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
|
411
418
|
(isStaticBoolean(scope, a) && hasConstantLooseBooleanComparison(scope, b))
|
412
419
|
) {
|
413
420
|
return b;
|
414
421
|
}
|
415
422
|
} else if (operator === "===" || operator === "!==") {
|
416
423
|
if (
|
417
|
-
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
|
424
|
+
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
|
418
425
|
(isStaticBoolean(scope, a) && hasConstantStrictBooleanComparison(scope, b))
|
419
426
|
) {
|
420
427
|
return b;
|
@@ -453,7 +460,7 @@ module.exports = {
|
|
453
460
|
|
454
461
|
if ((operator === "&&" || operator === "||") && isConstant(scope, left, true)) {
|
455
462
|
context.report({ node: left, messageId: "constantShortCircuit", data: { property: "truthiness", operator } });
|
456
|
-
} else if (operator === "??" && hasConstantNullishness(scope, left)) {
|
463
|
+
} else if (operator === "??" && hasConstantNullishness(scope, left, false)) {
|
457
464
|
context.report({ node: left, messageId: "constantShortCircuit", data: { property: "nullishness", operator } });
|
458
465
|
}
|
459
466
|
},
|
package/lib/rules/no-eval.js
CHANGED
@@ -72,7 +72,7 @@ module.exports = {
|
|
72
72
|
let funcInfo = null;
|
73
73
|
|
74
74
|
/**
|
75
|
-
*
|
75
|
+
* Pushes a `this` scope (non-arrow function, class static block, or class field initializer) information to the stack.
|
76
76
|
* Top-level scopes are handled separately.
|
77
77
|
*
|
78
78
|
* This is used in order to check whether or not `this` binding is a
|
@@ -766,6 +766,38 @@ module.exports = {
|
|
766
766
|
return false;
|
767
767
|
}
|
768
768
|
|
769
|
+
/**
|
770
|
+
* Checks if the left-hand side of an assignment is an identifier, the operator is one of
|
771
|
+
* `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous class or function.
|
772
|
+
*
|
773
|
+
* As per https://tc39.es/ecma262/#sec-assignment-operators-runtime-semantics-evaluation, an
|
774
|
+
* assignment involving one of the operators `=`, `&&=`, `||=` or `??=` where the right-hand
|
775
|
+
* side is an anonymous class or function and the left-hand side is an *unparenthesized*
|
776
|
+
* identifier has different semantics than other assignments.
|
777
|
+
* Specifically, when an expression like `foo = function () {}` is evaluated, `foo.name`
|
778
|
+
* will be set to the string "foo", i.e. the identifier name. The same thing does not happen
|
779
|
+
* when evaluating `(foo) = function () {}`.
|
780
|
+
* Since the parenthesizing of the identifier in the left-hand side is significant in this
|
781
|
+
* special case, the parentheses, if present, should not be flagged as unnecessary.
|
782
|
+
* @param {ASTNode} node an AssignmentExpression node.
|
783
|
+
* @returns {boolean} `true` if the left-hand side of the assignment is an identifier, the
|
784
|
+
* operator is one of `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous
|
785
|
+
* class or function; otherwise, `false`.
|
786
|
+
*/
|
787
|
+
function isAnonymousFunctionAssignmentException({ left, operator, right }) {
|
788
|
+
if (left.type === "Identifier" && ["=", "&&=", "||=", "??="].includes(operator)) {
|
789
|
+
const rhsType = right.type;
|
790
|
+
|
791
|
+
if (rhsType === "ArrowFunctionExpression") {
|
792
|
+
return true;
|
793
|
+
}
|
794
|
+
if ((rhsType === "FunctionExpression" || rhsType === "ClassExpression") && !right.id) {
|
795
|
+
return true;
|
796
|
+
}
|
797
|
+
}
|
798
|
+
return false;
|
799
|
+
}
|
800
|
+
|
769
801
|
return {
|
770
802
|
ArrayExpression(node) {
|
771
803
|
node.elements
|
@@ -804,7 +836,8 @@ module.exports = {
|
|
804
836
|
},
|
805
837
|
|
806
838
|
AssignmentExpression(node) {
|
807
|
-
if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)
|
839
|
+
if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left) &&
|
840
|
+
(!isAnonymousFunctionAssignmentException(node) || isParenthesisedTwice(node.left))) {
|
808
841
|
report(node.left);
|
809
842
|
}
|
810
843
|
|
@@ -10,6 +10,6 @@ ESLint couldn't find a configuration file. To set up a configuration file for th
|
|
10
10
|
|
11
11
|
ESLint looked for configuration files in ${directoryPath} and its ancestors. If it found none, it then looked in your home directory.
|
12
12
|
|
13
|
-
If you think you already have a configuration file or if you need more help, please stop by the ESLint
|
13
|
+
If you think you already have a configuration file or if you need more help, please stop by the ESLint Discord server: https://eslint.org/chat
|
14
14
|
`.trimStart();
|
15
15
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.35.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -37,6 +37,10 @@
|
|
37
37
|
"lint-staged": {
|
38
38
|
"*.js": "eslint --fix",
|
39
39
|
"*.md": "markdownlint --fix",
|
40
|
+
"lib/rules/*.js": [
|
41
|
+
"node tools/update-eslint-all.js",
|
42
|
+
"git add packages/js/src/configs/eslint-all.js"
|
43
|
+
],
|
40
44
|
"docs/src/rules/*.md": [
|
41
45
|
"node tools/fetch-docs-links.js",
|
42
46
|
"git add docs/src/_data/further_reading_links.json"
|
@@ -56,7 +60,8 @@
|
|
56
60
|
"homepage": "https://eslint.org",
|
57
61
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
58
62
|
"dependencies": {
|
59
|
-
"@eslint/eslintrc": "^
|
63
|
+
"@eslint/eslintrc": "^2.0.0",
|
64
|
+
"@eslint/js": "8.35.0",
|
60
65
|
"@humanwhocodes/config-array": "^0.11.8",
|
61
66
|
"@humanwhocodes/module-importer": "^1.0.1",
|
62
67
|
"@nodelib/fs.walk": "^1.2.8",
|
@@ -70,7 +75,7 @@
|
|
70
75
|
"eslint-utils": "^3.0.0",
|
71
76
|
"eslint-visitor-keys": "^3.3.0",
|
72
77
|
"espree": "^9.4.0",
|
73
|
-
"esquery": "^1.4.
|
78
|
+
"esquery": "^1.4.2",
|
74
79
|
"esutils": "^2.0.2",
|
75
80
|
"fast-deep-equal": "^3.1.3",
|
76
81
|
"file-entry-cache": "^6.0.1",
|
package/conf/eslint-all.js
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Config to enable all rules.
|
3
|
-
* @author Robert Fletcher
|
4
|
-
*/
|
5
|
-
|
6
|
-
"use strict";
|
7
|
-
|
8
|
-
//------------------------------------------------------------------------------
|
9
|
-
// Requirements
|
10
|
-
//------------------------------------------------------------------------------
|
11
|
-
|
12
|
-
const builtInRules = require("../lib/rules");
|
13
|
-
|
14
|
-
//------------------------------------------------------------------------------
|
15
|
-
// Helpers
|
16
|
-
//------------------------------------------------------------------------------
|
17
|
-
|
18
|
-
const allRules = {};
|
19
|
-
|
20
|
-
for (const [ruleId, rule] of builtInRules) {
|
21
|
-
if (!rule.meta.deprecated) {
|
22
|
-
allRules[ruleId] = "error";
|
23
|
-
}
|
24
|
-
}
|
25
|
-
|
26
|
-
//------------------------------------------------------------------------------
|
27
|
-
// Public Interface
|
28
|
-
//------------------------------------------------------------------------------
|
29
|
-
|
30
|
-
/** @type {import("../lib/shared/types").ConfigData} */
|
31
|
-
module.exports = { rules: allRules };
|
@@ -1,76 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Configuration applied when a user configuration extends from
|
3
|
-
* eslint:recommended.
|
4
|
-
* @author Nicholas C. Zakas
|
5
|
-
*/
|
6
|
-
|
7
|
-
"use strict";
|
8
|
-
|
9
|
-
/* eslint sort-keys: ["error", "asc"] -- Long, so make more readable */
|
10
|
-
|
11
|
-
/** @type {import("../lib/shared/types").ConfigData} */
|
12
|
-
module.exports = {
|
13
|
-
rules: {
|
14
|
-
"constructor-super": "error",
|
15
|
-
"for-direction": "error",
|
16
|
-
"getter-return": "error",
|
17
|
-
"no-async-promise-executor": "error",
|
18
|
-
"no-case-declarations": "error",
|
19
|
-
"no-class-assign": "error",
|
20
|
-
"no-compare-neg-zero": "error",
|
21
|
-
"no-cond-assign": "error",
|
22
|
-
"no-const-assign": "error",
|
23
|
-
"no-constant-condition": "error",
|
24
|
-
"no-control-regex": "error",
|
25
|
-
"no-debugger": "error",
|
26
|
-
"no-delete-var": "error",
|
27
|
-
"no-dupe-args": "error",
|
28
|
-
"no-dupe-class-members": "error",
|
29
|
-
"no-dupe-else-if": "error",
|
30
|
-
"no-dupe-keys": "error",
|
31
|
-
"no-duplicate-case": "error",
|
32
|
-
"no-empty": "error",
|
33
|
-
"no-empty-character-class": "error",
|
34
|
-
"no-empty-pattern": "error",
|
35
|
-
"no-ex-assign": "error",
|
36
|
-
"no-extra-boolean-cast": "error",
|
37
|
-
"no-extra-semi": "error",
|
38
|
-
"no-fallthrough": "error",
|
39
|
-
"no-func-assign": "error",
|
40
|
-
"no-global-assign": "error",
|
41
|
-
"no-import-assign": "error",
|
42
|
-
"no-inner-declarations": "error",
|
43
|
-
"no-invalid-regexp": "error",
|
44
|
-
"no-irregular-whitespace": "error",
|
45
|
-
"no-loss-of-precision": "error",
|
46
|
-
"no-misleading-character-class": "error",
|
47
|
-
"no-mixed-spaces-and-tabs": "error",
|
48
|
-
"no-new-symbol": "error",
|
49
|
-
"no-nonoctal-decimal-escape": "error",
|
50
|
-
"no-obj-calls": "error",
|
51
|
-
"no-octal": "error",
|
52
|
-
"no-prototype-builtins": "error",
|
53
|
-
"no-redeclare": "error",
|
54
|
-
"no-regex-spaces": "error",
|
55
|
-
"no-self-assign": "error",
|
56
|
-
"no-setter-return": "error",
|
57
|
-
"no-shadow-restricted-names": "error",
|
58
|
-
"no-sparse-arrays": "error",
|
59
|
-
"no-this-before-super": "error",
|
60
|
-
"no-undef": "error",
|
61
|
-
"no-unexpected-multiline": "error",
|
62
|
-
"no-unreachable": "error",
|
63
|
-
"no-unsafe-finally": "error",
|
64
|
-
"no-unsafe-negation": "error",
|
65
|
-
"no-unsafe-optional-chaining": "error",
|
66
|
-
"no-unused-labels": "error",
|
67
|
-
"no-unused-vars": "error",
|
68
|
-
"no-useless-backreference": "error",
|
69
|
-
"no-useless-catch": "error",
|
70
|
-
"no-useless-escape": "error",
|
71
|
-
"no-with": "error",
|
72
|
-
"require-yield": "error",
|
73
|
-
"use-isnan": "error",
|
74
|
-
"valid-typeof": "error"
|
75
|
-
}
|
76
|
-
};
|