eslint 8.42.0 → 8.43.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 +1 -1
- package/lib/eslint/eslint-helpers.js +1 -1
- package/lib/eslint/eslint.js +1 -1
- package/lib/rules/block-scoped-var.js +15 -5
- package/lib/rules/logical-assignment-operators.js +0 -1
- package/lib/rules/newline-after-var.js +0 -2
- package/lib/rules/no-extra-parens.js +34 -8
- package/lib/rules/no-irregular-whitespace.js +18 -0
- package/lib/rules/no-unused-expressions.js +3 -5
- package/lib/rules/padding-line-between-statements.js +1 -8
- package/lib/rules/quotes.js +14 -14
- package/lib/rules/utils/ast-utils.js +21 -2
- package/package.json +3 -3
package/README.md
CHANGED
@@ -284,7 +284,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
284
284
|
<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>
|
285
285
|
<p><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>
|
286
286
|
<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> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
|
287
|
-
<p><a href="
|
287
|
+
<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>
|
288
288
|
<!--sponsorsend-->
|
289
289
|
|
290
290
|
## Technology Sponsors
|
@@ -795,7 +795,7 @@ function processOptions({
|
|
795
795
|
// when overrideConfigFile is true that means don't do config file lookup
|
796
796
|
configFile: overrideConfigFile === true ? false : overrideConfigFile,
|
797
797
|
overrideConfig,
|
798
|
-
cwd,
|
798
|
+
cwd: path.normalize(cwd),
|
799
799
|
errorOnUnmatchedPattern,
|
800
800
|
fix,
|
801
801
|
fixTypes,
|
package/lib/eslint/eslint.js
CHANGED
@@ -22,7 +22,7 @@ module.exports = {
|
|
22
22
|
schema: [],
|
23
23
|
|
24
24
|
messages: {
|
25
|
-
outOfScope: "'{{name}}' used outside of binding context."
|
25
|
+
outOfScope: "'{{name}}' declared on line {{definitionLine}} column {{definitionColumn}} is used outside of binding context."
|
26
26
|
}
|
27
27
|
},
|
28
28
|
|
@@ -50,12 +50,22 @@ module.exports = {
|
|
50
50
|
/**
|
51
51
|
* Reports a given reference.
|
52
52
|
* @param {eslint-scope.Reference} reference A reference to report.
|
53
|
+
* @param {eslint-scope.Definition} definition A definition for which to report reference.
|
53
54
|
* @returns {void}
|
54
55
|
*/
|
55
|
-
function report(reference) {
|
56
|
+
function report(reference, definition) {
|
56
57
|
const identifier = reference.identifier;
|
57
|
-
|
58
|
-
|
58
|
+
const definitionPosition = definition.name.loc.start;
|
59
|
+
|
60
|
+
context.report({
|
61
|
+
node: identifier,
|
62
|
+
messageId: "outOfScope",
|
63
|
+
data: {
|
64
|
+
name: identifier.name,
|
65
|
+
definitionLine: definitionPosition.line,
|
66
|
+
definitionColumn: definitionPosition.column + 1
|
67
|
+
}
|
68
|
+
});
|
59
69
|
}
|
60
70
|
|
61
71
|
/**
|
@@ -92,7 +102,7 @@ module.exports = {
|
|
92
102
|
variables[i]
|
93
103
|
.references
|
94
104
|
.filter(isOutsideOfScope)
|
95
|
-
.forEach(report);
|
105
|
+
.forEach(ref => report(ref, variables[i].defs.find(def => def.parent === node)));
|
96
106
|
}
|
97
107
|
}
|
98
108
|
|
@@ -188,7 +188,6 @@ module.exports = {
|
|
188
188
|
}]
|
189
189
|
},
|
190
190
|
fixable: "code",
|
191
|
-
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- Does not detect conditional suggestions
|
192
191
|
hasSuggestions: true,
|
193
192
|
messages: {
|
194
193
|
assignment: "Assignment (=) can be replaced with operator assignment ({{operator}}).",
|
@@ -212,7 +212,6 @@ module.exports = {
|
|
212
212
|
context.report({
|
213
213
|
node,
|
214
214
|
messageId: "unexpected",
|
215
|
-
data: { identifier: node.name },
|
216
215
|
fix(fixer) {
|
217
216
|
const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER);
|
218
217
|
|
@@ -231,7 +230,6 @@ module.exports = {
|
|
231
230
|
context.report({
|
232
231
|
node,
|
233
232
|
messageId: "expected",
|
234
|
-
data: { identifier: node.name },
|
235
233
|
fix(fixer) {
|
236
234
|
if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) {
|
237
235
|
return fixer.insertTextBefore(nextToken, "\n\n");
|
@@ -386,6 +386,30 @@ module.exports = {
|
|
386
386
|
return node && (node.type === "Identifier" || node.type === "MemberExpression");
|
387
387
|
}
|
388
388
|
|
389
|
+
/**
|
390
|
+
* Checks if a node is fixable.
|
391
|
+
* A node is fixable if removing a single pair of surrounding parentheses does not turn it
|
392
|
+
* into a directive after fixing other nodes.
|
393
|
+
* Almost all nodes are fixable, except if all of the following conditions are met:
|
394
|
+
* The node is a string Literal
|
395
|
+
* It has a single pair of parentheses
|
396
|
+
* It is the only child of an ExpressionStatement
|
397
|
+
* @param {ASTNode} node The node to evaluate.
|
398
|
+
* @returns {boolean} Whether or not the node is fixable.
|
399
|
+
* @private
|
400
|
+
*/
|
401
|
+
function isFixable(node) {
|
402
|
+
|
403
|
+
// if it's not a string literal it can be autofixed
|
404
|
+
if (node.type !== "Literal" || typeof node.value !== "string") {
|
405
|
+
return true;
|
406
|
+
}
|
407
|
+
if (isParenthesisedTwice(node)) {
|
408
|
+
return true;
|
409
|
+
}
|
410
|
+
return !astUtils.isTopLevelExpressionStatement(node.parent);
|
411
|
+
}
|
412
|
+
|
389
413
|
/**
|
390
414
|
* Report the node
|
391
415
|
* @param {ASTNode} node node to evaluate
|
@@ -429,14 +453,16 @@ module.exports = {
|
|
429
453
|
node,
|
430
454
|
loc: leftParenToken.loc,
|
431
455
|
messageId: "unexpected",
|
432
|
-
fix(
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
456
|
+
fix: isFixable(node)
|
457
|
+
? fixer => {
|
458
|
+
const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]);
|
459
|
+
|
460
|
+
return fixer.replaceTextRange([
|
461
|
+
leftParenToken.range[0],
|
462
|
+
rightParenToken.range[1]
|
463
|
+
], (requiresLeadingSpace(node) ? " " : "") + parenthesizedSource + (requiresTrailingSpace(node) ? " " : ""));
|
464
|
+
}
|
465
|
+
: null
|
440
466
|
});
|
441
467
|
}
|
442
468
|
|
@@ -55,6 +55,10 @@ module.exports = {
|
|
55
55
|
skipRegExps: {
|
56
56
|
type: "boolean",
|
57
57
|
default: false
|
58
|
+
},
|
59
|
+
skipJSXText: {
|
60
|
+
type: "boolean",
|
61
|
+
default: false
|
58
62
|
}
|
59
63
|
},
|
60
64
|
additionalProperties: false
|
@@ -77,6 +81,7 @@ module.exports = {
|
|
77
81
|
const skipStrings = options.skipStrings !== false;
|
78
82
|
const skipRegExps = !!options.skipRegExps;
|
79
83
|
const skipTemplates = !!options.skipTemplates;
|
84
|
+
const skipJSXText = !!options.skipJSXText;
|
80
85
|
|
81
86
|
const sourceCode = context.sourceCode;
|
82
87
|
const commentNodes = sourceCode.getAllComments();
|
@@ -144,6 +149,18 @@ module.exports = {
|
|
144
149
|
}
|
145
150
|
}
|
146
151
|
|
152
|
+
/**
|
153
|
+
* Checks JSX nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
|
154
|
+
* @param {ASTNode} node to check for matching errors.
|
155
|
+
* @returns {void}
|
156
|
+
* @private
|
157
|
+
*/
|
158
|
+
function removeInvalidNodeErrorsInJSXText(node) {
|
159
|
+
if (ALL_IRREGULARS.test(node.raw)) {
|
160
|
+
removeWhitespaceError(node);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
147
164
|
/**
|
148
165
|
* Checks the program source for irregular whitespace
|
149
166
|
* @param {ASTNode} node The program node
|
@@ -239,6 +256,7 @@ module.exports = {
|
|
239
256
|
|
240
257
|
nodes.Literal = removeInvalidNodeErrorsInLiteral;
|
241
258
|
nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop;
|
259
|
+
nodes.JSXText = skipJSXText ? removeInvalidNodeErrorsInJSXText : noop;
|
242
260
|
nodes["Program:exit"] = function() {
|
243
261
|
if (skipComments) {
|
244
262
|
|
@@ -4,6 +4,8 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
const astUtils = require("./utils/ast-utils");
|
8
|
+
|
7
9
|
//------------------------------------------------------------------------------
|
8
10
|
// Rule Definition
|
9
11
|
//------------------------------------------------------------------------------
|
@@ -112,8 +114,6 @@ module.exports = {
|
|
112
114
|
* @returns {boolean} whether the given node is considered a directive in its current position
|
113
115
|
*/
|
114
116
|
function isDirective(node) {
|
115
|
-
const parent = node.parent,
|
116
|
-
grandparent = parent.parent;
|
117
117
|
|
118
118
|
/**
|
119
119
|
* https://tc39.es/ecma262/#directive-prologue
|
@@ -121,9 +121,7 @@ module.exports = {
|
|
121
121
|
* Only `FunctionBody`, `ScriptBody` and `ModuleBody` can have directive prologue.
|
122
122
|
* Class static blocks do not have directive prologue.
|
123
123
|
*/
|
124
|
-
return (
|
125
|
-
(/Function/u.test(grandparent.type))) &&
|
126
|
-
directives(parent).includes(node);
|
124
|
+
return astUtils.isTopLevelExpressionStatement(node) && directives(node.parent).includes(node);
|
127
125
|
}
|
128
126
|
|
129
127
|
/**
|
@@ -138,14 +138,7 @@ function isBlockLikeStatement(sourceCode, node) {
|
|
138
138
|
*/
|
139
139
|
function isDirective(node, sourceCode) {
|
140
140
|
return (
|
141
|
-
node
|
142
|
-
(
|
143
|
-
node.parent.type === "Program" ||
|
144
|
-
(
|
145
|
-
node.parent.type === "BlockStatement" &&
|
146
|
-
astUtils.isFunction(node.parent.parent)
|
147
|
-
)
|
148
|
-
) &&
|
141
|
+
astUtils.isTopLevelExpressionStatement(node) &&
|
149
142
|
node.expression.type === "Literal" &&
|
150
143
|
typeof node.expression.value === "string" &&
|
151
144
|
!astUtils.isParenthesised(sourceCode, node.expression)
|
package/lib/rules/quotes.js
CHANGED
@@ -157,7 +157,8 @@ module.exports = {
|
|
157
157
|
|
158
158
|
/**
|
159
159
|
* Checks whether or not a given node is a directive.
|
160
|
-
* The directive is a `ExpressionStatement` which has only a string literal
|
160
|
+
* The directive is a `ExpressionStatement` which has only a string literal not surrounded by
|
161
|
+
* parentheses.
|
161
162
|
* @param {ASTNode} node A node to check.
|
162
163
|
* @returns {boolean} Whether or not the node is a directive.
|
163
164
|
* @private
|
@@ -166,23 +167,23 @@ module.exports = {
|
|
166
167
|
return (
|
167
168
|
node.type === "ExpressionStatement" &&
|
168
169
|
node.expression.type === "Literal" &&
|
169
|
-
typeof node.expression.value === "string"
|
170
|
+
typeof node.expression.value === "string" &&
|
171
|
+
!astUtils.isParenthesised(sourceCode, node.expression)
|
170
172
|
);
|
171
173
|
}
|
172
174
|
|
173
175
|
/**
|
174
|
-
* Checks whether
|
175
|
-
*
|
176
|
+
* Checks whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
|
177
|
+
* @see {@link http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive}
|
176
178
|
* @param {ASTNode} node A node to check.
|
177
|
-
* @returns {boolean} Whether
|
179
|
+
* @returns {boolean} Whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
|
178
180
|
* @private
|
179
181
|
*/
|
180
|
-
function
|
181
|
-
|
182
|
-
|
183
|
-
if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) {
|
182
|
+
function isExpressionInOrJustAfterDirectivePrologue(node) {
|
183
|
+
if (!astUtils.isTopLevelExpressionStatement(node.parent)) {
|
184
184
|
return false;
|
185
185
|
}
|
186
|
+
const block = node.parent.parent;
|
186
187
|
|
187
188
|
// Check the node is at a prologue.
|
188
189
|
for (let i = 0; i < block.body.length; ++i) {
|
@@ -212,7 +213,7 @@ module.exports = {
|
|
212
213
|
|
213
214
|
// Directive Prologues.
|
214
215
|
case "ExpressionStatement":
|
215
|
-
return
|
216
|
+
return !astUtils.isParenthesised(sourceCode, node) && isExpressionInOrJustAfterDirectivePrologue(node);
|
216
217
|
|
217
218
|
// LiteralPropertyName.
|
218
219
|
case "Property":
|
@@ -328,12 +329,11 @@ module.exports = {
|
|
328
329
|
description: settings.description
|
329
330
|
},
|
330
331
|
fix(fixer) {
|
331
|
-
if (
|
332
|
+
if (astUtils.isTopLevelExpressionStatement(node.parent) && !astUtils.isParenthesised(sourceCode, node)) {
|
332
333
|
|
333
334
|
/*
|
334
|
-
* TemplateLiterals
|
335
|
-
*
|
336
|
-
* the behavior of the code.
|
335
|
+
* TemplateLiterals aren't actually directives, but fixing them might turn
|
336
|
+
* them into directives and change the behavior of the code.
|
337
337
|
*/
|
338
338
|
return null;
|
339
339
|
}
|
@@ -986,6 +986,25 @@ function isConstant(scope, node, inBooleanPosition) {
|
|
986
986
|
return false;
|
987
987
|
}
|
988
988
|
|
989
|
+
/**
|
990
|
+
* Checks whether a node is an ExpressionStatement at the top level of a file or function body.
|
991
|
+
* A top-level ExpressionStatement node is a directive if it contains a single unparenthesized
|
992
|
+
* string literal and if it occurs either as the first sibling or immediately after another
|
993
|
+
* directive.
|
994
|
+
* @param {ASTNode} node The node to check.
|
995
|
+
* @returns {boolean} Whether or not the node is an ExpressionStatement at the top level of a
|
996
|
+
* file or function body.
|
997
|
+
*/
|
998
|
+
function isTopLevelExpressionStatement(node) {
|
999
|
+
if (node.type !== "ExpressionStatement") {
|
1000
|
+
return false;
|
1001
|
+
}
|
1002
|
+
const parent = node.parent;
|
1003
|
+
|
1004
|
+
return parent.type === "Program" || (parent.type === "BlockStatement" && isFunction(parent.parent));
|
1005
|
+
|
1006
|
+
}
|
1007
|
+
|
989
1008
|
//------------------------------------------------------------------------------
|
990
1009
|
// Public Interface
|
991
1010
|
//------------------------------------------------------------------------------
|
@@ -1501,7 +1520,6 @@ module.exports = {
|
|
1501
1520
|
return directives;
|
1502
1521
|
},
|
1503
1522
|
|
1504
|
-
|
1505
1523
|
/**
|
1506
1524
|
* Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
|
1507
1525
|
* after the node will be parsed as a decimal point, rather than a property-access dot.
|
@@ -2120,5 +2138,6 @@ module.exports = {
|
|
2120
2138
|
isLogicalAssignmentOperator,
|
2121
2139
|
getSwitchCaseColonToken,
|
2122
2140
|
getModuleExportName,
|
2123
|
-
isConstant
|
2141
|
+
isConstant,
|
2142
|
+
isTopLevelExpressionStatement
|
2124
2143
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.43.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -63,7 +63,7 @@
|
|
63
63
|
"@eslint-community/eslint-utils": "^4.2.0",
|
64
64
|
"@eslint-community/regexpp": "^4.4.0",
|
65
65
|
"@eslint/eslintrc": "^2.0.3",
|
66
|
-
"@eslint/js": "8.
|
66
|
+
"@eslint/js": "8.43.0",
|
67
67
|
"@humanwhocodes/config-array": "^0.11.10",
|
68
68
|
"@humanwhocodes/module-importer": "^1.0.1",
|
69
69
|
"@nodelib/fs.walk": "^1.2.8",
|
@@ -113,7 +113,7 @@
|
|
113
113
|
"eslint": "file:.",
|
114
114
|
"eslint-config-eslint": "file:packages/eslint-config-eslint",
|
115
115
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
116
|
-
"eslint-plugin-eslint-plugin": "^
|
116
|
+
"eslint-plugin-eslint-plugin": "^5.1.0",
|
117
117
|
"eslint-plugin-internal-rules": "file:tools/internal-rules",
|
118
118
|
"eslint-plugin-jsdoc": "^38.1.6",
|
119
119
|
"eslint-plugin-n": "^15.2.4",
|