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 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
@@ -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(sourceCode, currentNode, languageOptions, name),
958
+ markVariableAsUsed: name => sourceCode.markVariableAsUsed(name, currentNode),
991
959
  parserOptions: {
992
960
  ...languageOptions.parserOptions
993
961
  },
@@ -76,7 +76,7 @@ module.exports = {
76
76
  return;
77
77
  }
78
78
 
79
- const block = sourceCode.getAncestors(node).pop();
79
+ const block = node.parent;
80
80
 
81
81
  if (loneBlocks[loneBlocks.length - 1] === block) {
82
82
  loneBlocks.pop();
@@ -32,9 +32,8 @@ module.exports = {
32
32
 
33
33
  return {
34
34
  IfStatement(node) {
35
- const ancestors = sourceCode.getAncestors(node),
36
- parent = ancestors.pop(),
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, ancestors) {
117
- const parent = ancestors[ancestors.length - 1],
118
- grandparent = ancestors[ancestors.length - 2];
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, sourceCode.getAncestors(node))) {
182
+ if (Checker.isDisallowed(node.expression) && !isDirective(node)) {
185
183
  context.report({ node, messageId: "unusedExpression" });
186
184
  }
187
185
  }
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * @fileoverview Prefers object spread property over Object.assign
3
3
  * @author Sharmila Jesupaul
4
- * See LICENSE file in root directory for full license.
5
4
  */
6
5
 
7
6
  "use strict";
@@ -83,7 +83,7 @@ module.exports = {
83
83
 
84
84
  UnaryExpression(node) {
85
85
  if (isTypeofExpression(node)) {
86
- const parent = sourceCode.getAncestors(node).pop();
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;
@@ -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 ancestors = sourceCode.getAncestors(node);
44
- const grandparent = ancestors[ancestors.length - 1];
43
+ const { parent } = node;
45
44
 
46
- if (grandparent.type === "MemberExpression" && grandparent.object === node &&
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(sourceCode.getAncestors(node).pop()))
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
- * Gets all of the declared variables in the scope associated
650
- * with `node`. This is a convenience method that passes through
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 from which to retrieve the scope to check.
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 declared variables in the scope associated with `node`.
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
- const index = tokens.findIndex(el => location <= getStartLocation(el));
19
+ for (let minIndex = 0, maxIndex = tokens.length - 1; minIndex <= maxIndex;) {
34
20
 
35
- return index === -1 ? tokens.length : index;
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.38.0",
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.38.0",
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.1.1",
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",