eslint 8.37.0 → 8.38.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
@@ -244,11 +244,6 @@ The people who review and fix bugs and help triage issues.
244
244
  Bryan Mishkin
245
245
  </a>
246
246
  </td><td align="center" valign="top" width="11%">
247
- <a href="https://github.com/btmills">
248
- <img src="https://github.com/btmills.png?s=75" width="75" height="75"><br />
249
- Brandon Mills
250
- </a>
251
- </td><td align="center" valign="top" width="11%">
252
247
  <a href="https://github.com/fasttime">
253
248
  <img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
254
249
  Francesco Trotta
@@ -905,22 +905,6 @@ function createRuleListeners(rule, ruleContext) {
905
905
  }
906
906
  }
907
907
 
908
- /**
909
- * Gets all the ancestors of a given node
910
- * @param {ASTNode} node The node
911
- * @returns {ASTNode[]} All the ancestor nodes in the AST, not including the provided node, starting
912
- * from the root node and going inwards to the parent node.
913
- */
914
- function getAncestors(node) {
915
- const ancestorsStartingAtParent = [];
916
-
917
- for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
918
- ancestorsStartingAtParent.push(ancestor);
919
- }
920
-
921
- return ancestorsStartingAtParent.reverse();
922
- }
923
-
924
908
  // methods that exist on SourceCode object
925
909
  const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
926
910
  getSource: "getText",
@@ -996,8 +980,8 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
996
980
  Object.assign(
997
981
  Object.create(BASE_TRAVERSAL_CONTEXT),
998
982
  {
999
- getAncestors: () => getAncestors(currentNode),
1000
- getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager),
983
+ getAncestors: () => sourceCode.getAncestors(currentNode),
984
+ getDeclaredVariables: node => sourceCode.getDeclaredVariables(node),
1001
985
  getCwd: () => cwd,
1002
986
  getFilename: () => filename,
1003
987
  getPhysicalFilename: () => physicalFilename || filename,
@@ -28,6 +28,7 @@ module.exports = {
28
28
 
29
29
  create(context) {
30
30
  let stack = [];
31
+ const sourceCode = context.getSourceCode();
31
32
 
32
33
  /**
33
34
  * Makes a block scope.
@@ -83,7 +84,7 @@ module.exports = {
83
84
  }
84
85
 
85
86
  // Gets declared variables, and checks its references.
86
- const variables = context.getDeclaredVariables(node);
87
+ const variables = sourceCode.getDeclaredVariables(node);
87
88
 
88
89
  for (let i = 0; i < variables.length; ++i) {
89
90
 
@@ -296,7 +296,7 @@ module.exports = {
296
296
  "ClassExpression",
297
297
  "CatchClause"
298
298
  ]](node) {
299
- for (const variable of context.getDeclaredVariables(node)) {
299
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
300
300
  if (isGoodName(variable.name)) {
301
301
  continue;
302
302
  }
@@ -346,7 +346,7 @@ module.exports = {
346
346
 
347
347
  // Report camelcase in import --------------------------------------
348
348
  ImportDeclaration(node) {
349
- for (const variable of context.getDeclaredVariables(node)) {
349
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
350
350
  if (isGoodName(variable.name)) {
351
351
  continue;
352
352
  }
@@ -159,7 +159,7 @@ module.exports = {
159
159
  function handleFunction(node) {
160
160
 
161
161
  // Skip recursive functions.
162
- const nameVar = context.getDeclaredVariables(node)[0];
162
+ const nameVar = sourceCode.getDeclaredVariables(node)[0];
163
163
 
164
164
  if (isFunctionName(nameVar) && nameVar.references.length > 0) {
165
165
  return;
@@ -78,7 +78,7 @@ module.exports = {
78
78
  const currentScope = sourceCode.getScope(node);
79
79
 
80
80
  if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
81
- const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.has(parent.type));
81
+ const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type));
82
82
 
83
83
  if (!isGoodRequire) {
84
84
  context.report({ node, messageId: "unexpected" });
@@ -31,20 +31,11 @@ module.exports = {
31
31
  },
32
32
 
33
33
  fixable: "code",
34
- schema: {
35
- anyOf: [
36
- {
37
- type: "array",
38
- items: [
39
- {
40
- enum: ["always", "never"]
41
- }
42
- ],
43
- minItems: 0,
44
- maxItems: 1
45
- }
46
- ]
47
- },
34
+ schema: [
35
+ {
36
+ enum: ["always", "never"]
37
+ }
38
+ ],
48
39
  messages: {
49
40
  missing: "Missing '()' invoking a constructor.",
50
41
  unnecessary: "Unnecessary '()' invoking a constructor with no arguments."
@@ -31,6 +31,8 @@ module.exports = {
31
31
 
32
32
  create(context) {
33
33
 
34
+ const sourceCode = context.getSourceCode();
35
+
34
36
  /**
35
37
  * Finds and reports references that are non initializer and writable.
36
38
  * @param {Variable} variable A variable to check.
@@ -49,7 +51,7 @@ module.exports = {
49
51
  * @returns {void}
50
52
  */
51
53
  function checkForClass(node) {
52
- context.getDeclaredVariables(node).forEach(checkVariable);
54
+ sourceCode.getDeclaredVariables(node).forEach(checkVariable);
53
55
  }
54
56
 
55
57
  return {
@@ -31,6 +31,8 @@ module.exports = {
31
31
 
32
32
  create(context) {
33
33
 
34
+ const sourceCode = context.getSourceCode();
35
+
34
36
  /**
35
37
  * Finds and reports references that are non initializer and writable.
36
38
  * @param {Variable} variable A variable to check.
@@ -45,7 +47,7 @@ module.exports = {
45
47
  return {
46
48
  VariableDeclaration(node) {
47
49
  if (node.kind === "const") {
48
- context.getDeclaredVariables(node).forEach(checkVariable);
50
+ sourceCode.getDeclaredVariables(node).forEach(checkVariable);
49
51
  }
50
52
  }
51
53
  };
@@ -15,7 +15,7 @@ module.exports = {
15
15
  type: "suggestion",
16
16
 
17
17
  docs: {
18
- description: "Disallow division operators explicitly at the beginning of regular expressions",
18
+ description: "Disallow equal signs explicitly at the beginning of regular expressions",
19
19
  recommended: false,
20
20
  url: "https://eslint.org/docs/rules/no-div-regex"
21
21
  },
@@ -29,6 +29,8 @@ module.exports = {
29
29
 
30
30
  create(context) {
31
31
 
32
+ const sourceCode = context.getSourceCode();
33
+
32
34
  //--------------------------------------------------------------------------
33
35
  // Helpers
34
36
  //--------------------------------------------------------------------------
@@ -49,7 +51,7 @@ module.exports = {
49
51
  * @private
50
52
  */
51
53
  function checkParams(node) {
52
- const variables = context.getDeclaredVariables(node);
54
+ const variables = sourceCode.getDeclaredVariables(node);
53
55
 
54
56
  for (let i = 0; i < variables.length; ++i) {
55
57
  const variable = variables[i];
@@ -31,6 +31,8 @@ module.exports = {
31
31
 
32
32
  create(context) {
33
33
 
34
+ const sourceCode = context.getSourceCode();
35
+
34
36
  /**
35
37
  * Finds and reports references that are non initializer and writable.
36
38
  * @param {Variable} variable A variable to check.
@@ -44,7 +46,7 @@ module.exports = {
44
46
 
45
47
  return {
46
48
  CatchClause(node) {
47
- context.getDeclaredVariables(node).forEach(checkVariable);
49
+ sourceCode.getDeclaredVariables(node).forEach(checkVariable);
48
50
  }
49
51
  };
50
52
 
@@ -31,6 +31,8 @@ module.exports = {
31
31
 
32
32
  create(context) {
33
33
 
34
+ const sourceCode = context.getSourceCode();
35
+
34
36
  /**
35
37
  * Reports a reference if is non initializer and writable.
36
38
  * @param {References} references Collection of reference to check.
@@ -65,7 +67,7 @@ module.exports = {
65
67
  * @returns {void}
66
68
  */
67
69
  function checkForFunction(node) {
68
- context.getDeclaredVariables(node).forEach(checkVariable);
70
+ sourceCode.getDeclaredVariables(node).forEach(checkVariable);
69
71
  }
70
72
 
71
73
  return {
@@ -200,7 +200,7 @@ module.exports = {
200
200
  ImportDeclaration(node) {
201
201
  const scope = sourceCode.getScope(node);
202
202
 
203
- for (const variable of context.getDeclaredVariables(node)) {
203
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
204
204
  const shouldCheckMembers = variable.defs.some(
205
205
  d => d.node.type === "ImportNamespaceSpecifier"
206
206
  );
@@ -68,14 +68,15 @@ module.exports = {
68
68
  /**
69
69
  * Checks the enclosing block of the current node for block-level bindings,
70
70
  * and "marks it" as valid if any.
71
+ * @param {ASTNode} node The current node to check.
71
72
  * @returns {void}
72
73
  */
73
- function markLoneBlock() {
74
+ function markLoneBlock(node) {
74
75
  if (loneBlocks.length === 0) {
75
76
  return;
76
77
  }
77
78
 
78
- const block = context.getAncestors().pop();
79
+ const block = sourceCode.getAncestors(node).pop();
79
80
 
80
81
  if (loneBlocks[loneBlocks.length - 1] === block) {
81
82
  loneBlocks.pop();
@@ -117,13 +118,13 @@ module.exports = {
117
118
 
118
119
  ruleDef.VariableDeclaration = function(node) {
119
120
  if (node.kind === "let" || node.kind === "const") {
120
- markLoneBlock();
121
+ markLoneBlock(node);
121
122
  }
122
123
  };
123
124
 
124
125
  ruleDef.FunctionDeclaration = function(node) {
125
126
  if (sourceCode.getScope(node).isStrict) {
126
- markLoneBlock();
127
+ markLoneBlock(node);
127
128
  }
128
129
  };
129
130
 
@@ -32,7 +32,7 @@ module.exports = {
32
32
 
33
33
  return {
34
34
  IfStatement(node) {
35
- const ancestors = context.getAncestors(),
35
+ const ancestors = sourceCode.getAncestors(node),
36
36
  parent = ancestors.pop(),
37
37
  grandparent = ancestors.pop();
38
38
 
@@ -70,6 +70,7 @@ module.exports = {
70
70
  const props = context.options[0] && context.options[0].props;
71
71
  const ignoredPropertyAssignmentsFor = context.options[0] && context.options[0].ignorePropertyModificationsFor || [];
72
72
  const ignoredPropertyAssignmentsForRegex = context.options[0] && context.options[0].ignorePropertyModificationsForRegex || [];
73
+ const sourceCode = context.getSourceCode();
73
74
 
74
75
  /**
75
76
  * Checks whether or not the reference modifies properties of its variable.
@@ -214,7 +215,7 @@ module.exports = {
214
215
  * @returns {void}
215
216
  */
216
217
  function checkForFunction(node) {
217
- context.getDeclaredVariables(node).forEach(checkVariable);
218
+ sourceCode.getDeclaredVariables(node).forEach(checkVariable);
218
219
  }
219
220
 
220
221
  return {
@@ -99,6 +99,7 @@ module.exports = {
99
99
 
100
100
  const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports);
101
101
  const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports;
102
+ const sourceCode = context.getSourceCode();
102
103
 
103
104
  /**
104
105
  * Checks and reports given exported name.
@@ -176,7 +177,7 @@ module.exports = {
176
177
  if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
177
178
  checkExportedName(declaration.id);
178
179
  } else if (declaration.type === "VariableDeclaration") {
179
- context.getDeclaredVariables(declaration)
180
+ sourceCode.getDeclaredVariables(declaration)
180
181
  .map(v => v.defs.find(d => d.parent === declaration))
181
182
  .map(d => d.name) // Identifier nodes
182
183
  .forEach(checkExportedName);
@@ -43,10 +43,11 @@ module.exports = {
43
43
 
44
44
 
45
45
  const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]);
46
+ const sourceCode = context.getSourceCode();
46
47
 
47
48
  return {
48
49
  "VariableDeclaration, :function, CatchClause"(node) {
49
- for (const variable of context.getDeclaredVariables(node)) {
50
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
50
51
  if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) {
51
52
  context.report({
52
53
  node: variable.defs[0].name,
@@ -84,6 +84,7 @@ module.exports = {
84
84
  const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true;
85
85
  const allowInArrayDestructuring = typeof options.allowInArrayDestructuring !== "undefined" ? options.allowInArrayDestructuring : true;
86
86
  const allowInObjectDestructuring = typeof options.allowInObjectDestructuring !== "undefined" ? options.allowInObjectDestructuring : true;
87
+ const sourceCode = context.getSourceCode();
87
88
 
88
89
  //-------------------------------------------------------------------------
89
90
  // Helpers
@@ -213,7 +214,7 @@ module.exports = {
213
214
  * @private
214
215
  */
215
216
  function checkForDanglingUnderscoreInVariableExpression(node) {
216
- context.getDeclaredVariables(node).forEach(variable => {
217
+ sourceCode.getDeclaredVariables(node).forEach(variable => {
217
218
  const definition = variable.defs.find(def => def.node === node);
218
219
  const identifierNode = definition.name;
219
220
  const identifier = identifierNode.name;
@@ -70,7 +70,8 @@ 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;
73
+ enforceForJSX = config.enforceForJSX || false,
74
+ sourceCode = context.getSourceCode();
74
75
 
75
76
  /**
76
77
  * Has AST suggesting a directive.
@@ -180,7 +181,7 @@ module.exports = {
180
181
 
181
182
  return {
182
183
  ExpressionStatement(node) {
183
- if (Checker.isDisallowed(node.expression) && !isDirective(node, context.getAncestors())) {
184
+ if (Checker.isDisallowed(node.expression) && !isDirective(node, sourceCode.getAncestors(node))) {
184
185
  context.report({ node, messageId: "unusedExpression" });
185
186
  }
186
187
  }
@@ -555,7 +555,7 @@ module.exports = {
555
555
  */
556
556
  function isAfterLastUsedArg(variable) {
557
557
  const def = variable.defs[0];
558
- const params = context.getDeclaredVariables(def.node);
558
+ const params = sourceCode.getDeclaredVariables(def.node);
559
559
  const posteriorParams = params.slice(params.indexOf(variable) + 1);
560
560
 
561
561
  // If any used parameters occur after this parameter, do not report.
@@ -210,7 +210,7 @@ module.exports = {
210
210
  if (!declarator.init) {
211
211
  return false;
212
212
  }
213
- const variables = context.getDeclaredVariables(declarator);
213
+ const variables = sourceCode.getDeclaredVariables(declarator);
214
214
 
215
215
  return variables.some(hasReferenceInTDZ(declarator.init));
216
216
  }
@@ -268,7 +268,7 @@ module.exports = {
268
268
  * @returns {boolean} `true` if it can fix the node.
269
269
  */
270
270
  function canFix(node) {
271
- const variables = context.getDeclaredVariables(node);
271
+ const variables = sourceCode.getDeclaredVariables(node);
272
272
  const scopeNode = getScopeNode(node);
273
273
 
274
274
  if (node.parent.type === "SwitchCase" ||
@@ -263,7 +263,7 @@ module.exports = {
263
263
  }
264
264
 
265
265
  // Skip recursive functions.
266
- const nameVar = context.getDeclaredVariables(node)[0];
266
+ const nameVar = sourceCode.getDeclaredVariables(node)[0];
267
267
 
268
268
  if (isFunctionName(nameVar) && nameVar.references.length > 0) {
269
269
  return;
@@ -493,7 +493,7 @@ module.exports = {
493
493
 
494
494
  VariableDeclaration(node) {
495
495
  if (node.kind === "let" && !isInitOfForStatement(node)) {
496
- variables.push(...context.getDeclaredVariables(node));
496
+ variables.push(...sourceCode.getDeclaredVariables(node));
497
497
  }
498
498
  }
499
499
  };
@@ -41,6 +41,7 @@ module.exports = {
41
41
  create(context) {
42
42
 
43
43
  const ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject;
44
+ const sourceCode = context.getSourceCode();
44
45
 
45
46
  //----------------------------------------------------------------------
46
47
  // Helpers
@@ -100,7 +101,7 @@ module.exports = {
100
101
  node.arguments.length && astUtils.isFunction(node.arguments[0]) &&
101
102
  node.arguments[0].params.length > 1 && node.arguments[0].params[1].type === "Identifier"
102
103
  ) {
103
- context.getDeclaredVariables(node.arguments[0])
104
+ sourceCode.getDeclaredVariables(node.arguments[0])
104
105
 
105
106
  /*
106
107
  * Find the first variable that matches the second parameter's name.
@@ -78,6 +78,10 @@ module.exports = {
78
78
 
79
79
  for (const { node: refNode } of tracker.iterateGlobalReferences(trackMap)) {
80
80
  const [patternNode, flagsNode] = refNode.arguments;
81
+
82
+ if (patternNode && patternNode.type === "SpreadElement") {
83
+ continue;
84
+ }
81
85
  const pattern = getStringIfConstant(patternNode, scope);
82
86
  const flags = getStringIfConstant(flagsNode, scope);
83
87
 
@@ -83,7 +83,7 @@ module.exports = {
83
83
 
84
84
  UnaryExpression(node) {
85
85
  if (isTypeofExpression(node)) {
86
- const parent = context.getAncestors().pop();
86
+ const parent = sourceCode.getAncestors(node).pop();
87
87
 
88
88
  if (parent.type === "BinaryExpression" && OPERATORS.has(parent.operator)) {
89
89
  const sibling = parent.left === node ? parent.right : parent.left;
@@ -40,7 +40,7 @@ module.exports = {
40
40
  if (nodeType === "RegularExpression") {
41
41
  const beforeToken = sourceCode.getTokenBefore(node);
42
42
  const afterToken = sourceCode.getTokenAfter(node);
43
- const ancestors = context.getAncestors();
43
+ const ancestors = sourceCode.getAncestors(node);
44
44
  const grandparent = ancestors[ancestors.length - 1];
45
45
 
46
46
  if (grandparent.type === "MemberExpression" && grandparent.object === 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(context.getAncestors().pop()))
346
+ !(exceptRange && isRangeTest(sourceCode.getAncestors(node).pop()))
347
347
  ) {
348
348
  context.report({
349
349
  node,
@@ -14,6 +14,12 @@ const
14
14
  astUtils = require("../shared/ast-utils"),
15
15
  Traverser = require("../shared/traverser");
16
16
 
17
+ //------------------------------------------------------------------------------
18
+ // Type Definitions
19
+ //------------------------------------------------------------------------------
20
+
21
+ /** @typedef {import("eslint-scope").Variable} Variable */
22
+
17
23
  //------------------------------------------------------------------------------
18
24
  // Private
19
25
  //------------------------------------------------------------------------------
@@ -639,6 +645,42 @@ class SourceCode extends TokenStore {
639
645
  return this.scopeManager.scopes[0];
640
646
  }
641
647
 
648
+ /**
649
+ * Gets all of the declared variables in the scope associated
650
+ * with `node`. This is a convenience method that passes through
651
+ * to the same method on the `scopeManager`.
652
+ * @param {ASTNode} node The node from which to retrieve the scope to check.
653
+ * @returns {Array<Variable>} An array of variable nodes representing
654
+ * the declared variables in the scope associated with `node`.
655
+ */
656
+ getDeclaredVariables(node) {
657
+ return this.scopeManager.getDeclaredVariables(node);
658
+ }
659
+
660
+ /* eslint-disable class-methods-use-this -- node is owned by SourceCode */
661
+ /**
662
+ * Gets all the ancestors of a given node
663
+ * @param {ASTNode} node The node
664
+ * @returns {Array<ASTNode>} All the ancestor nodes in the AST, not including the provided node, starting
665
+ * from the root node at index 0 and going inwards to the parent node.
666
+ * @throws {TypeError} When `node` is missing.
667
+ */
668
+ getAncestors(node) {
669
+
670
+ if (!node) {
671
+ throw new TypeError("Missing required argument: node.");
672
+ }
673
+
674
+ const ancestorsStartingAtParent = [];
675
+
676
+ for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
677
+ ancestorsStartingAtParent.push(ancestor);
678
+ }
679
+
680
+ return ancestorsStartingAtParent.reverse();
681
+ }
682
+ /* eslint-enable class-methods-use-this -- node is owned by SourceCode */
683
+
642
684
  }
643
685
 
644
686
  module.exports = SourceCode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "8.37.0",
3
+ "version": "8.38.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.37.0",
66
+ "@eslint/js": "8.38.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",