eslint 8.38.0 → 8.39.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 -6
- package/lib/linter/linter.js +1 -33
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-lonely-if.js +2 -3
- package/lib/rules/no-unused-expressions.js +5 -7
- package/lib/rules/prefer-object-spread.js +0 -1
- package/lib/rules/valid-typeof.js +1 -1
- package/lib/rules/wrap-regex.js +2 -3
- package/lib/rules/yoda.js +1 -1
- package/lib/source-code/source-code.js +47 -4
- package/lib/source-code/token-store/utils.js +21 -16
- package/package.json +3 -3
package/README.md
CHANGED
@@ -248,11 +248,6 @@ Bryan Mishkin
|
|
248
248
|
<img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
|
249
249
|
Francesco Trotta
|
250
250
|
</a>
|
251
|
-
</td><td align="center" valign="top" width="11%">
|
252
|
-
<a href="https://github.com/yeonjuan">
|
253
|
-
<img src="https://github.com/yeonjuan.png?s=75" width="75" height="75"><br />
|
254
|
-
YeonJuan
|
255
|
-
</a>
|
256
251
|
</td></tr></tbody></table>
|
257
252
|
|
258
253
|
### Website Team
|
@@ -288,7 +283,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
288
283
|
<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>
|
289
284
|
<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>
|
290
285
|
<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>
|
291
|
-
<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>
|
286
|
+
<p><a href="https://twicsy.com/buy-instagram-likes"><img src="https://images.opencollective.com/twicsy/7af290f/avatar.png" alt="Twicsy" height="32"></a> <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>
|
292
287
|
<!--sponsorsend-->
|
293
288
|
|
294
289
|
## Technology Sponsors
|
package/lib/linter/linter.js
CHANGED
@@ -857,38 +857,6 @@ function parse(text, languageOptions, filePath) {
|
|
857
857
|
}
|
858
858
|
}
|
859
859
|
|
860
|
-
/**
|
861
|
-
* Marks a variable as used in the current scope
|
862
|
-
* @param {SourceCode} sourceCode The source code for the currently linted file.
|
863
|
-
* @param {ASTNode} currentNode The node currently being traversed
|
864
|
-
* @param {LanguageOptions} languageOptions The options used to parse this text
|
865
|
-
* @param {string} name The name of the variable that should be marked as used.
|
866
|
-
* @returns {boolean} True if the variable was found and marked as used, false if not.
|
867
|
-
*/
|
868
|
-
function markVariableAsUsed(sourceCode, currentNode, languageOptions, name) {
|
869
|
-
const parserOptions = languageOptions.parserOptions;
|
870
|
-
const sourceType = languageOptions.sourceType;
|
871
|
-
const hasGlobalReturn =
|
872
|
-
(parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn) ||
|
873
|
-
sourceType === "commonjs";
|
874
|
-
const specialScope = hasGlobalReturn || sourceType === "module";
|
875
|
-
const currentScope = sourceCode.getScope(currentNode);
|
876
|
-
|
877
|
-
// Special Node.js scope means we need to start one level deeper
|
878
|
-
const initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope;
|
879
|
-
|
880
|
-
for (let scope = initialScope; scope; scope = scope.upper) {
|
881
|
-
const variable = scope.variables.find(scopeVar => scopeVar.name === name);
|
882
|
-
|
883
|
-
if (variable) {
|
884
|
-
variable.eslintUsed = true;
|
885
|
-
return true;
|
886
|
-
}
|
887
|
-
}
|
888
|
-
|
889
|
-
return false;
|
890
|
-
}
|
891
|
-
|
892
860
|
/**
|
893
861
|
* Runs a rule, and gets its listeners
|
894
862
|
* @param {Rule} rule A normalized rule with a `create` method
|
@@ -987,7 +955,7 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
|
|
987
955
|
getPhysicalFilename: () => physicalFilename || filename,
|
988
956
|
getScope: () => sourceCode.getScope(currentNode),
|
989
957
|
getSourceCode: () => sourceCode,
|
990
|
-
markVariableAsUsed: name => markVariableAsUsed(
|
958
|
+
markVariableAsUsed: name => sourceCode.markVariableAsUsed(name, currentNode),
|
991
959
|
parserOptions: {
|
992
960
|
...languageOptions.parserOptions
|
993
961
|
},
|
@@ -32,9 +32,8 @@ module.exports = {
|
|
32
32
|
|
33
33
|
return {
|
34
34
|
IfStatement(node) {
|
35
|
-
const
|
36
|
-
|
37
|
-
grandparent = ancestors.pop();
|
35
|
+
const parent = node.parent,
|
36
|
+
grandparent = parent.parent;
|
38
37
|
|
39
38
|
if (parent && parent.type === "BlockStatement" &&
|
40
39
|
parent.body.length === 1 && grandparent &&
|
@@ -70,8 +70,7 @@ module.exports = {
|
|
70
70
|
allowShortCircuit = config.allowShortCircuit || false,
|
71
71
|
allowTernary = config.allowTernary || false,
|
72
72
|
allowTaggedTemplates = config.allowTaggedTemplates || false,
|
73
|
-
enforceForJSX = config.enforceForJSX || false
|
74
|
-
sourceCode = context.getSourceCode();
|
73
|
+
enforceForJSX = config.enforceForJSX || false;
|
75
74
|
|
76
75
|
/**
|
77
76
|
* Has AST suggesting a directive.
|
@@ -110,12 +109,11 @@ module.exports = {
|
|
110
109
|
/**
|
111
110
|
* Detect if a Node is a directive.
|
112
111
|
* @param {ASTNode} node any node
|
113
|
-
* @param {ASTNode[]} ancestors the given node's ancestors
|
114
112
|
* @returns {boolean} whether the given node is considered a directive in its current position
|
115
113
|
*/
|
116
|
-
function isDirective(node
|
117
|
-
const parent =
|
118
|
-
grandparent =
|
114
|
+
function isDirective(node) {
|
115
|
+
const parent = node.parent,
|
116
|
+
grandparent = parent.parent;
|
119
117
|
|
120
118
|
/**
|
121
119
|
* https://tc39.es/ecma262/#directive-prologue
|
@@ -181,7 +179,7 @@ module.exports = {
|
|
181
179
|
|
182
180
|
return {
|
183
181
|
ExpressionStatement(node) {
|
184
|
-
if (Checker.isDisallowed(node.expression) && !isDirective(node
|
182
|
+
if (Checker.isDisallowed(node.expression) && !isDirective(node)) {
|
185
183
|
context.report({ node, messageId: "unusedExpression" });
|
186
184
|
}
|
187
185
|
}
|
@@ -83,7 +83,7 @@ module.exports = {
|
|
83
83
|
|
84
84
|
UnaryExpression(node) {
|
85
85
|
if (isTypeofExpression(node)) {
|
86
|
-
const parent =
|
86
|
+
const { parent } = node;
|
87
87
|
|
88
88
|
if (parent.type === "BinaryExpression" && OPERATORS.has(parent.operator)) {
|
89
89
|
const sibling = parent.left === node ? parent.right : parent.left;
|
package/lib/rules/wrap-regex.js
CHANGED
@@ -40,10 +40,9 @@ module.exports = {
|
|
40
40
|
if (nodeType === "RegularExpression") {
|
41
41
|
const beforeToken = sourceCode.getTokenBefore(node);
|
42
42
|
const afterToken = sourceCode.getTokenAfter(node);
|
43
|
-
const
|
44
|
-
const grandparent = ancestors[ancestors.length - 1];
|
43
|
+
const { parent } = node;
|
45
44
|
|
46
|
-
if (
|
45
|
+
if (parent.type === "MemberExpression" && parent.object === node &&
|
47
46
|
!(beforeToken && beforeToken.value === "(" && afterToken && afterToken.value === ")")) {
|
48
47
|
context.report({
|
49
48
|
node,
|
package/lib/rules/yoda.js
CHANGED
@@ -343,7 +343,7 @@ module.exports = {
|
|
343
343
|
) &&
|
344
344
|
!(!isEqualityOperator(node.operator) && onlyEquality) &&
|
345
345
|
isComparisonOperator(node.operator) &&
|
346
|
-
!(exceptRange && isRangeTest(
|
346
|
+
!(exceptRange && isRangeTest(node.parent))
|
347
347
|
) {
|
348
348
|
context.report({
|
349
349
|
node,
|
@@ -646,12 +646,12 @@ class SourceCode extends TokenStore {
|
|
646
646
|
}
|
647
647
|
|
648
648
|
/**
|
649
|
-
*
|
650
|
-
*
|
649
|
+
* Get the variables that `node` defines.
|
650
|
+
* This is a convenience method that passes through
|
651
651
|
* to the same method on the `scopeManager`.
|
652
|
-
* @param {ASTNode} node The node
|
652
|
+
* @param {ASTNode} node The node for which the variables are obtained.
|
653
653
|
* @returns {Array<Variable>} An array of variable nodes representing
|
654
|
-
* the
|
654
|
+
* the variables that `node` defines.
|
655
655
|
*/
|
656
656
|
getDeclaredVariables(node) {
|
657
657
|
return this.scopeManager.getDeclaredVariables(node);
|
@@ -681,6 +681,49 @@ class SourceCode extends TokenStore {
|
|
681
681
|
}
|
682
682
|
/* eslint-enable class-methods-use-this -- node is owned by SourceCode */
|
683
683
|
|
684
|
+
/**
|
685
|
+
* Marks a variable as used in the current scope
|
686
|
+
* @param {string} name The name of the variable to mark as used.
|
687
|
+
* @param {ASTNode} [refNode] The closest node to the variable reference.
|
688
|
+
* @returns {boolean} True if the variable was found and marked as used, false if not.
|
689
|
+
*/
|
690
|
+
markVariableAsUsed(name, refNode = this.ast) {
|
691
|
+
|
692
|
+
const currentScope = this.getScope(refNode);
|
693
|
+
let initialScope = currentScope;
|
694
|
+
|
695
|
+
/*
|
696
|
+
* When we are in an ESM or CommonJS module, we need to start searching
|
697
|
+
* from the top-level scope, not the global scope. For ESM the top-level
|
698
|
+
* scope is the module scope; for CommonJS the top-level scope is the
|
699
|
+
* outer function scope.
|
700
|
+
*
|
701
|
+
* Without this check, we might miss a variable declared with `var` at
|
702
|
+
* the top-level because it won't exist in the global scope.
|
703
|
+
*/
|
704
|
+
if (
|
705
|
+
currentScope.type === "global" &&
|
706
|
+
currentScope.childScopes.length > 0 &&
|
707
|
+
|
708
|
+
// top-level scopes refer to a `Program` node
|
709
|
+
currentScope.childScopes[0].block === this.ast
|
710
|
+
) {
|
711
|
+
initialScope = currentScope.childScopes[0];
|
712
|
+
}
|
713
|
+
|
714
|
+
for (let scope = initialScope; scope; scope = scope.upper) {
|
715
|
+
const variable = scope.variables.find(scopeVar => scopeVar.name === name);
|
716
|
+
|
717
|
+
if (variable) {
|
718
|
+
variable.eslintUsed = true;
|
719
|
+
return true;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
|
723
|
+
return false;
|
724
|
+
}
|
725
|
+
|
726
|
+
|
684
727
|
}
|
685
728
|
|
686
729
|
module.exports = SourceCode;
|
@@ -4,20 +4,6 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
-
//------------------------------------------------------------------------------
|
8
|
-
// Helpers
|
9
|
-
//------------------------------------------------------------------------------
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Gets `token.range[0]` from the given token.
|
13
|
-
* @param {Node|Token|Comment} token The token to get.
|
14
|
-
* @returns {number} The start location.
|
15
|
-
* @private
|
16
|
-
*/
|
17
|
-
function getStartLocation(token) {
|
18
|
-
return token.range[0];
|
19
|
-
}
|
20
|
-
|
21
7
|
//------------------------------------------------------------------------------
|
22
8
|
// Exports
|
23
9
|
//------------------------------------------------------------------------------
|
@@ -30,9 +16,28 @@ function getStartLocation(token) {
|
|
30
16
|
* @returns {number} The found index or `tokens.length`.
|
31
17
|
*/
|
32
18
|
exports.search = function search(tokens, location) {
|
33
|
-
|
19
|
+
for (let minIndex = 0, maxIndex = tokens.length - 1; minIndex <= maxIndex;) {
|
34
20
|
|
35
|
-
|
21
|
+
/*
|
22
|
+
* Calculate the index in the middle between minIndex and maxIndex.
|
23
|
+
* `| 0` is used to round a fractional value down to the nearest integer: this is similar to
|
24
|
+
* using `Math.trunc()` or `Math.floor()`, but performance tests have shown this method to
|
25
|
+
* be faster.
|
26
|
+
*/
|
27
|
+
const index = (minIndex + maxIndex) / 2 | 0;
|
28
|
+
const token = tokens[index];
|
29
|
+
const tokenStartLocation = token.range[0];
|
30
|
+
|
31
|
+
if (location <= tokenStartLocation) {
|
32
|
+
if (index === minIndex) {
|
33
|
+
return index;
|
34
|
+
}
|
35
|
+
maxIndex = index;
|
36
|
+
} else {
|
37
|
+
minIndex = index + 1;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
return tokens.length;
|
36
41
|
};
|
37
42
|
|
38
43
|
/**
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.39.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.2",
|
66
|
-
"@eslint/js": "8.
|
66
|
+
"@eslint/js": "8.39.0",
|
67
67
|
"@humanwhocodes/config-array": "^0.11.8",
|
68
68
|
"@humanwhocodes/module-importer": "^1.0.1",
|
69
69
|
"@nodelib/fs.walk": "^1.2.8",
|
@@ -73,7 +73,7 @@
|
|
73
73
|
"debug": "^4.3.2",
|
74
74
|
"doctrine": "^3.0.0",
|
75
75
|
"escape-string-regexp": "^4.0.0",
|
76
|
-
"eslint-scope": "^7.
|
76
|
+
"eslint-scope": "^7.2.0",
|
77
77
|
"eslint-visitor-keys": "^3.4.0",
|
78
78
|
"espree": "^9.5.1",
|
79
79
|
"esquery": "^1.4.2",
|