eslint 8.0.0 → 8.3.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.
Files changed (41) hide show
  1. package/README.md +8 -2
  2. package/lib/cli-engine/cli-engine.js +10 -21
  3. package/lib/eslint/eslint.js +2 -15
  4. package/lib/linter/code-path-analysis/code-path-analyzer.js +6 -1
  5. package/lib/linter/code-path-analysis/code-path.js +1 -1
  6. package/lib/linter/config-comment-parser.js +1 -1
  7. package/lib/linter/linter.js +2 -2
  8. package/lib/linter/node-event-generator.js +7 -0
  9. package/lib/rule-tester/rule-tester.js +5 -2
  10. package/lib/rules/block-scoped-var.js +2 -0
  11. package/lib/rules/block-spacing.js +10 -3
  12. package/lib/rules/brace-style.js +6 -0
  13. package/lib/rules/class-methods-use-this.js +10 -1
  14. package/lib/rules/complexity.js +14 -6
  15. package/lib/rules/indent.js +21 -0
  16. package/lib/rules/index.js +1 -0
  17. package/lib/rules/key-spacing.js +14 -13
  18. package/lib/rules/keyword-spacing.js +15 -1
  19. package/lib/rules/lines-around-comment.js +54 -7
  20. package/lib/rules/max-depth.js +2 -0
  21. package/lib/rules/max-statements.js +10 -0
  22. package/lib/rules/no-eval.js +2 -0
  23. package/lib/rules/no-extra-semi.js +1 -1
  24. package/lib/rules/no-inner-declarations.js +26 -4
  25. package/lib/rules/no-invalid-this.js +4 -0
  26. package/lib/rules/no-lone-blocks.js +8 -2
  27. package/lib/rules/no-redeclare.js +2 -0
  28. package/lib/rules/no-unused-expressions.js +6 -0
  29. package/lib/rules/no-unused-private-class-members.js +194 -0
  30. package/lib/rules/no-use-before-define.js +175 -74
  31. package/lib/rules/one-var.js +5 -1
  32. package/lib/rules/padded-blocks.js +8 -0
  33. package/lib/rules/padding-line-between-statements.js +2 -0
  34. package/lib/rules/prefer-const.js +1 -1
  35. package/lib/rules/require-atomic-updates.js +14 -2
  36. package/lib/rules/semi-style.js +8 -2
  37. package/lib/rules/semi.js +18 -9
  38. package/lib/rules/utils/ast-utils.js +15 -3
  39. package/lib/rules/vars-on-top.js +25 -12
  40. package/lib/shared/types.js +1 -1
  41. package/package.json +9 -9
@@ -541,6 +541,8 @@ module.exports = {
541
541
  FunctionDeclaration: startFunction,
542
542
  FunctionExpression: startFunction,
543
543
  ArrowFunctionExpression: startFunction,
544
+ StaticBlock: startFunction, // StaticBlock creates a new scope for `var` variables
545
+
544
546
  BlockStatement: startBlock,
545
547
  ForStatement: startBlock,
546
548
  ForInStatement: startBlock,
@@ -552,10 +554,12 @@ module.exports = {
552
554
  "ForInStatement:exit": endBlock,
553
555
  "SwitchStatement:exit": endBlock,
554
556
  "BlockStatement:exit": endBlock,
557
+
555
558
  "Program:exit": endFunction,
556
559
  "FunctionDeclaration:exit": endFunction,
557
560
  "FunctionExpression:exit": endFunction,
558
- "ArrowFunctionExpression:exit": endFunction
561
+ "ArrowFunctionExpression:exit": endFunction,
562
+ "StaticBlock:exit": endFunction
559
563
  };
560
564
 
561
565
  }
@@ -106,6 +106,12 @@ module.exports = {
106
106
  if (node.type === "SwitchStatement") {
107
107
  return sourceCode.getTokenBefore(node.cases[0]);
108
108
  }
109
+
110
+ if (node.type === "StaticBlock") {
111
+ return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
112
+ }
113
+
114
+ // `BlockStatement` or `ClassBody`
109
115
  return sourceCode.getFirstToken(node);
110
116
  }
111
117
 
@@ -172,6 +178,7 @@ module.exports = {
172
178
  function requirePaddingFor(node) {
173
179
  switch (node.type) {
174
180
  case "BlockStatement":
181
+ case "StaticBlock":
175
182
  return options.blocks;
176
183
  case "SwitchStatement":
177
184
  return options.switches;
@@ -282,6 +289,7 @@ module.exports = {
282
289
  }
283
290
  checkPadding(node);
284
291
  };
292
+ rule.StaticBlock = rule.BlockStatement;
285
293
  }
286
294
 
287
295
  if (Object.prototype.hasOwnProperty.call(options, "classes")) {
@@ -618,9 +618,11 @@ module.exports = {
618
618
  Program: enterScope,
619
619
  BlockStatement: enterScope,
620
620
  SwitchStatement: enterScope,
621
+ StaticBlock: enterScope,
621
622
  "Program:exit": exitScope,
622
623
  "BlockStatement:exit": exitScope,
623
624
  "SwitchStatement:exit": exitScope,
625
+ "StaticBlock:exit": exitScope,
624
626
 
625
627
  ":statement": verify,
626
628
 
@@ -17,7 +17,7 @@ const astUtils = require("./utils/ast-utils");
17
17
  //------------------------------------------------------------------------------
18
18
 
19
19
  const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u;
20
- const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u;
20
+ const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|StaticBlock|SwitchCase)$/u;
21
21
  const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u;
22
22
 
23
23
  /**
@@ -176,7 +176,17 @@ module.exports = {
176
176
  },
177
177
 
178
178
  fixable: null,
179
- schema: [],
179
+
180
+ schema: [{
181
+ type: "object",
182
+ properties: {
183
+ allowProperties: {
184
+ type: "boolean",
185
+ default: false
186
+ }
187
+ },
188
+ additionalProperties: false
189
+ }],
180
190
 
181
191
  messages: {
182
192
  nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.",
@@ -185,6 +195,8 @@ module.exports = {
185
195
  },
186
196
 
187
197
  create(context) {
198
+ const allowProperties = !!context.options[0] && context.options[0].allowProperties;
199
+
188
200
  const sourceCode = context.getSourceCode();
189
201
  const assignmentReferences = new Map();
190
202
  const segmentInfo = new SegmentInfo();
@@ -284,7 +296,7 @@ module.exports = {
284
296
  value: variable.name
285
297
  }
286
298
  });
287
- } else {
299
+ } else if (!allowProperties) {
288
300
  context.report({
289
301
  node: node.parent,
290
302
  messageId: "nonAtomicObjectUpdate",
@@ -25,7 +25,8 @@ const SELECTOR = [
25
25
 
26
26
  /**
27
27
  * Get the child node list of a given node.
28
- * This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`.
28
+ * This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
29
+ * `ClassBody#body`, or `SwitchCase#consequent`.
29
30
  * This is used to check whether a node is the first/last child.
30
31
  * @param {Node} node A node to get child node list.
31
32
  * @returns {Node[]|null} The child node list.
@@ -33,7 +34,12 @@ const SELECTOR = [
33
34
  function getChildren(node) {
34
35
  const t = node.type;
35
36
 
36
- if (t === "BlockStatement" || t === "Program" || t === "ClassBody") {
37
+ if (
38
+ t === "BlockStatement" ||
39
+ t === "StaticBlock" ||
40
+ t === "Program" ||
41
+ t === "ClassBody"
42
+ ) {
37
43
  return node.body;
38
44
  }
39
45
  if (t === "SwitchCase") {
package/lib/rules/semi.js CHANGED
@@ -306,22 +306,31 @@ module.exports = {
306
306
  }
307
307
 
308
308
  /**
309
- * Checks a node to see if it's in a one-liner block statement.
309
+ * Checks a node to see if it's the last item in a one-liner block.
310
+ * Block is any `BlockStatement` or `StaticBlock` node. Block is a one-liner if its
311
+ * braces (and consequently everything between them) are on the same line.
310
312
  * @param {ASTNode} node The node to check.
311
- * @returns {boolean} whether the node is in a one-liner block statement.
313
+ * @returns {boolean} whether the node is the last item in a one-liner block.
312
314
  */
313
- function isOneLinerBlock(node) {
315
+ function isLastInOneLinerBlock(node) {
314
316
  const parent = node.parent;
315
317
  const nextToken = sourceCode.getTokenAfter(node);
316
318
 
317
319
  if (!nextToken || nextToken.value !== "}") {
318
320
  return false;
319
321
  }
320
- return (
321
- !!parent &&
322
- parent.type === "BlockStatement" &&
323
- parent.loc.start.line === parent.loc.end.line
324
- );
322
+
323
+ if (parent.type === "BlockStatement") {
324
+ return parent.loc.start.line === parent.loc.end.line;
325
+ }
326
+
327
+ if (parent.type === "StaticBlock") {
328
+ const openingBrace = sourceCode.getFirstToken(parent, { skip: 1 }); // skip the `static` token
329
+
330
+ return openingBrace.loc.start.line === parent.loc.end.line;
331
+ }
332
+
333
+ return false;
325
334
  }
326
335
 
327
336
  /**
@@ -343,7 +352,7 @@ module.exports = {
343
352
  report(node);
344
353
  }
345
354
  } else {
346
- const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node));
355
+ const oneLinerBlock = (exceptOneLine && isLastInOneLinerBlock(node));
347
356
 
348
357
  if (isSemi && oneLinerBlock) {
349
358
  report(node, true);
@@ -35,7 +35,7 @@ const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|g
35
35
  const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
36
36
 
37
37
  // A set of node types that can contain a list of statements
38
- const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
38
+ const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "StaticBlock", "SwitchCase"]);
39
39
 
40
40
  const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;
41
41
 
@@ -937,6 +937,8 @@ module.exports = {
937
937
  *
938
938
  * First, this checks the node:
939
939
  *
940
+ * - The given node is not in `PropertyDefinition#value` position.
941
+ * - The given node is not `StaticBlock`.
940
942
  * - The function name does not start with uppercase. It's a convention to capitalize the names
941
943
  * of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
942
944
  * - The function does not have a JSDoc comment that has a @this tag.
@@ -951,7 +953,8 @@ module.exports = {
951
953
  * - The location is not on an ES2015 class.
952
954
  * - Its `bind`/`call`/`apply` method is not called directly.
953
955
  * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
954
- * @param {ASTNode} node A function node to check.
956
+ * @param {ASTNode} node A function node to check. It also can be an implicit function, like `StaticBlock`
957
+ * or any expression that is `PropertyDefinition#value` node.
955
958
  * @param {SourceCode} sourceCode A SourceCode instance to get comments.
956
959
  * @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
957
960
  * with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
@@ -964,7 +967,12 @@ module.exports = {
964
967
  * Therefore, A expression node at `PropertyDefinition#value` is a function.
965
968
  * In this case, `this` is always not default binding.
966
969
  */
967
- if (node && node.parent && node.parent.type === "PropertyDefinition" && node.value === node) {
970
+ if (node.parent.type === "PropertyDefinition" && node.parent.value === node) {
971
+ return false;
972
+ }
973
+
974
+ // Class static blocks are implicit functions. In this case, `this` is always not default binding.
975
+ if (node.type === "StaticBlock") {
968
976
  return false;
969
977
  }
970
978
 
@@ -1825,6 +1833,10 @@ module.exports = {
1825
1833
  return true;
1826
1834
  }
1827
1835
 
1836
+ if (rightToken.type === "PrivateIdentifier") {
1837
+ return true;
1838
+ }
1839
+
1828
1840
  return false;
1829
1841
  },
1830
1842
 
@@ -77,10 +77,12 @@ module.exports = {
77
77
  const l = statements.length;
78
78
  let i = 0;
79
79
 
80
- // skip over directives
81
- for (; i < l; ++i) {
82
- if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) {
83
- break;
80
+ // Skip over directives and imports. Static blocks don't have either.
81
+ if (node.parent.type !== "StaticBlock") {
82
+ for (; i < l; ++i) {
83
+ if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) {
84
+ break;
85
+ }
84
86
  }
85
87
  }
86
88
 
@@ -111,16 +113,27 @@ module.exports = {
111
113
  /**
112
114
  * Checks whether variable is on top at functional block scope level
113
115
  * @param {ASTNode} node The node to check
114
- * @param {ASTNode} parent Parent of the node
115
- * @param {ASTNode} grandParent Parent of the node's parent
116
116
  * @returns {void}
117
117
  */
118
- function blockScopeVarCheck(node, parent, grandParent) {
119
- if (!(/Function/u.test(grandParent.type) &&
120
- parent.type === "BlockStatement" &&
121
- isVarOnTop(node, parent.body))) {
122
- context.report({ node, messageId: "top" });
118
+ function blockScopeVarCheck(node) {
119
+ const { parent } = node;
120
+
121
+ if (
122
+ parent.type === "BlockStatement" &&
123
+ /Function/u.test(parent.parent.type) &&
124
+ isVarOnTop(node, parent.body)
125
+ ) {
126
+ return;
123
127
  }
128
+
129
+ if (
130
+ parent.type === "StaticBlock" &&
131
+ isVarOnTop(node, parent.body)
132
+ ) {
133
+ return;
134
+ }
135
+
136
+ context.report({ node, messageId: "top" });
124
137
  }
125
138
 
126
139
  //--------------------------------------------------------------------------
@@ -134,7 +147,7 @@ module.exports = {
134
147
  } else if (node.parent.type === "Program") {
135
148
  globalVarCheck(node, node.parent);
136
149
  } else {
137
- blockScopeVarCheck(node, node.parent, node.parent.parent);
150
+ blockScopeVarCheck(node);
138
151
  }
139
152
  }
140
153
  };
@@ -21,7 +21,7 @@ module.exports = {};
21
21
  /**
22
22
  * @typedef {Object} ParserOptions
23
23
  * @property {EcmaFeatures} [ecmaFeatures] The optional features.
24
- * @property {3|5|6|7|8|9|10|11|12|2015|2016|2017|2018|2019|2020|2021} [ecmaVersion] The ECMAScript version (or revision number).
24
+ * @property {3|5|6|7|8|9|10|11|12|13|2015|2016|2017|2018|2019|2020|2021|2022} [ecmaVersion] The ECMAScript version (or revision number).
25
25
  * @property {"script"|"module"} [sourceType] The source code type.
26
26
  */
27
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "8.0.0",
3
+ "version": "8.3.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -47,7 +47,7 @@
47
47
  "homepage": "https://eslint.org",
48
48
  "bugs": "https://github.com/eslint/eslint/issues/",
49
49
  "dependencies": {
50
- "@eslint/eslintrc": "^1.0.2",
50
+ "@eslint/eslintrc": "^1.0.4",
51
51
  "@humanwhocodes/config-array": "^0.6.0",
52
52
  "ajv": "^6.10.0",
53
53
  "chalk": "^4.0.0",
@@ -56,10 +56,10 @@
56
56
  "doctrine": "^3.0.0",
57
57
  "enquirer": "^2.3.5",
58
58
  "escape-string-regexp": "^4.0.0",
59
- "eslint-scope": "^6.0.0",
59
+ "eslint-scope": "^7.1.0",
60
60
  "eslint-utils": "^3.0.0",
61
- "eslint-visitor-keys": "^3.0.0",
62
- "espree": "^9.0.0",
61
+ "eslint-visitor-keys": "^3.1.0",
62
+ "espree": "^9.1.0",
63
63
  "esquery": "^1.4.0",
64
64
  "esutils": "^2.0.2",
65
65
  "fast-deep-equal": "^3.1.3",
@@ -81,7 +81,7 @@
81
81
  "progress": "^2.0.0",
82
82
  "regexpp": "^3.2.0",
83
83
  "semver": "^7.2.1",
84
- "strip-ansi": "^6.0.0",
84
+ "strip-ansi": "^6.0.1",
85
85
  "strip-json-comments": "^3.1.0",
86
86
  "text-table": "^0.2.0",
87
87
  "v8-compile-cache": "^2.0.3"
@@ -99,11 +99,11 @@
99
99
  "eslint": "file:.",
100
100
  "eslint-config-eslint": "file:packages/eslint-config-eslint",
101
101
  "eslint-plugin-eslint-comments": "^3.2.0",
102
- "eslint-plugin-eslint-plugin": "^3.5.3",
102
+ "eslint-plugin-eslint-plugin": "^4.0.1",
103
103
  "eslint-plugin-internal-rules": "file:tools/internal-rules",
104
- "eslint-plugin-jsdoc": "^36.0.6",
104
+ "eslint-plugin-jsdoc": "^37.0.0",
105
105
  "eslint-plugin-node": "^11.1.0",
106
- "eslint-release": "^3.1.2",
106
+ "eslint-release": "^3.2.0",
107
107
  "eslump": "^3.0.0",
108
108
  "esprima": "^4.0.1",
109
109
  "fs-teardown": "^0.1.3",