eslint 8.47.0 → 8.57.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 (118) hide show
  1. package/README.md +18 -13
  2. package/bin/eslint.js +38 -5
  3. package/conf/rule-type-list.json +25 -33
  4. package/lib/api.js +29 -1
  5. package/lib/cli-engine/cli-engine.js +2 -2
  6. package/lib/cli-engine/lint-result-cache.js +18 -6
  7. package/lib/cli.js +36 -6
  8. package/lib/config/flat-config-schema.js +124 -61
  9. package/lib/config/rule-validator.js +2 -1
  10. package/lib/eslint/eslint-helpers.js +9 -11
  11. package/lib/eslint/eslint.js +7 -0
  12. package/lib/eslint/flat-eslint.js +33 -18
  13. package/lib/linter/apply-disable-directives.js +127 -13
  14. package/lib/linter/code-path-analysis/code-path-analyzer.js +32 -24
  15. package/lib/linter/code-path-analysis/code-path-segment.js +52 -24
  16. package/lib/linter/code-path-analysis/code-path-state.js +1108 -243
  17. package/lib/linter/code-path-analysis/code-path.js +128 -33
  18. package/lib/linter/code-path-analysis/fork-context.js +173 -72
  19. package/lib/linter/config-comment-parser.js +36 -2
  20. package/lib/linter/linter.js +183 -82
  21. package/lib/options.js +24 -3
  22. package/lib/rule-tester/flat-rule-tester.js +113 -25
  23. package/lib/rule-tester/rule-tester.js +176 -23
  24. package/lib/rules/array-bracket-newline.js +3 -0
  25. package/lib/rules/array-bracket-spacing.js +3 -0
  26. package/lib/rules/array-callback-return.js +175 -25
  27. package/lib/rules/array-element-newline.js +3 -0
  28. package/lib/rules/arrow-parens.js +3 -0
  29. package/lib/rules/arrow-spacing.js +3 -0
  30. package/lib/rules/block-spacing.js +3 -0
  31. package/lib/rules/brace-style.js +3 -0
  32. package/lib/rules/comma-dangle.js +3 -0
  33. package/lib/rules/comma-spacing.js +3 -0
  34. package/lib/rules/comma-style.js +3 -0
  35. package/lib/rules/computed-property-spacing.js +3 -0
  36. package/lib/rules/consistent-return.js +32 -7
  37. package/lib/rules/constructor-super.js +37 -14
  38. package/lib/rules/dot-location.js +3 -0
  39. package/lib/rules/eol-last.js +3 -0
  40. package/lib/rules/for-direction.js +38 -24
  41. package/lib/rules/func-call-spacing.js +3 -0
  42. package/lib/rules/function-call-argument-newline.js +3 -0
  43. package/lib/rules/function-paren-newline.js +3 -0
  44. package/lib/rules/generator-star-spacing.js +3 -0
  45. package/lib/rules/getter-return.js +33 -8
  46. package/lib/rules/implicit-arrow-linebreak.js +3 -0
  47. package/lib/rules/indent.js +3 -0
  48. package/lib/rules/index.js +1 -0
  49. package/lib/rules/jsx-quotes.js +3 -0
  50. package/lib/rules/key-spacing.js +3 -0
  51. package/lib/rules/keyword-spacing.js +3 -0
  52. package/lib/rules/linebreak-style.js +3 -0
  53. package/lib/rules/lines-around-comment.js +3 -0
  54. package/lib/rules/lines-between-class-members.js +95 -7
  55. package/lib/rules/logical-assignment-operators.js +31 -3
  56. package/lib/rules/max-len.js +3 -0
  57. package/lib/rules/max-statements-per-line.js +3 -0
  58. package/lib/rules/multiline-ternary.js +3 -0
  59. package/lib/rules/new-parens.js +3 -0
  60. package/lib/rules/newline-per-chained-call.js +3 -0
  61. package/lib/rules/no-array-constructor.js +85 -6
  62. package/lib/rules/no-confusing-arrow.js +3 -0
  63. package/lib/rules/no-console.js +74 -2
  64. package/lib/rules/no-extra-parens.js +3 -0
  65. package/lib/rules/no-extra-semi.js +3 -0
  66. package/lib/rules/no-fallthrough.js +42 -14
  67. package/lib/rules/no-floating-decimal.js +3 -0
  68. package/lib/rules/no-invalid-this.js +1 -1
  69. package/lib/rules/no-misleading-character-class.js +65 -15
  70. package/lib/rules/no-mixed-operators.js +3 -0
  71. package/lib/rules/no-mixed-spaces-and-tabs.js +3 -0
  72. package/lib/rules/no-multi-spaces.js +3 -0
  73. package/lib/rules/no-multiple-empty-lines.js +3 -0
  74. package/lib/rules/no-new-object.js +7 -0
  75. package/lib/rules/no-object-constructor.js +117 -0
  76. package/lib/rules/no-promise-executor-return.js +157 -16
  77. package/lib/rules/no-prototype-builtins.js +90 -2
  78. package/lib/rules/no-restricted-imports.js +54 -31
  79. package/lib/rules/no-restricted-properties.js +15 -28
  80. package/lib/rules/no-tabs.js +3 -0
  81. package/lib/rules/no-this-before-super.js +38 -11
  82. package/lib/rules/no-trailing-spaces.js +3 -0
  83. package/lib/rules/no-unreachable-loop.js +47 -12
  84. package/lib/rules/no-unreachable.js +39 -10
  85. package/lib/rules/no-useless-return.js +35 -4
  86. package/lib/rules/no-whitespace-before-property.js +3 -0
  87. package/lib/rules/nonblock-statement-body-position.js +3 -0
  88. package/lib/rules/object-curly-newline.js +3 -0
  89. package/lib/rules/object-curly-spacing.js +3 -0
  90. package/lib/rules/object-property-newline.js +3 -0
  91. package/lib/rules/one-var-declaration-per-line.js +3 -0
  92. package/lib/rules/operator-linebreak.js +3 -0
  93. package/lib/rules/padded-blocks.js +3 -0
  94. package/lib/rules/padding-line-between-statements.js +3 -0
  95. package/lib/rules/quote-props.js +3 -0
  96. package/lib/rules/quotes.js +3 -0
  97. package/lib/rules/require-atomic-updates.js +21 -7
  98. package/lib/rules/rest-spread-spacing.js +3 -0
  99. package/lib/rules/semi-spacing.js +3 -0
  100. package/lib/rules/semi-style.js +3 -0
  101. package/lib/rules/semi.js +3 -0
  102. package/lib/rules/space-before-blocks.js +3 -0
  103. package/lib/rules/space-before-function-paren.js +3 -0
  104. package/lib/rules/space-in-parens.js +3 -0
  105. package/lib/rules/space-infix-ops.js +3 -0
  106. package/lib/rules/space-unary-ops.js +3 -0
  107. package/lib/rules/spaced-comment.js +3 -0
  108. package/lib/rules/switch-colon-spacing.js +3 -0
  109. package/lib/rules/template-curly-spacing.js +3 -0
  110. package/lib/rules/template-tag-spacing.js +3 -0
  111. package/lib/rules/utils/ast-utils.js +111 -1
  112. package/lib/rules/wrap-iife.js +3 -0
  113. package/lib/rules/wrap-regex.js +3 -0
  114. package/lib/rules/yield-star-spacing.js +3 -0
  115. package/lib/shared/severity.js +49 -0
  116. package/lib/source-code/source-code.js +329 -3
  117. package/messages/eslintrc-incompat.js +1 -1
  118. package/package.json +24 -17
@@ -5,6 +5,12 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const { getStaticValue } = require("@eslint-community/eslint-utils");
13
+
8
14
  //------------------------------------------------------------------------------
9
15
  // Rule Definition
10
16
  //------------------------------------------------------------------------------
@@ -29,6 +35,7 @@ module.exports = {
29
35
  },
30
36
 
31
37
  create(context) {
38
+ const { sourceCode } = context;
32
39
 
33
40
  /**
34
41
  * report an error.
@@ -46,17 +53,17 @@ module.exports = {
46
53
  * check the right side of the assignment
47
54
  * @param {ASTNode} update UpdateExpression to check
48
55
  * @param {int} dir expected direction that could either be turned around or invalidated
49
- * @returns {int} return dir, the negated dir or zero if it's not clear for identifiers
56
+ * @returns {int} return dir, the negated dir, or zero if the counter does not change or the direction is not clear
50
57
  */
51
58
  function getRightDirection(update, dir) {
52
- if (update.right.type === "UnaryExpression") {
53
- if (update.right.operator === "-") {
54
- return -dir;
55
- }
56
- } else if (update.right.type === "Identifier") {
57
- return 0;
59
+ const staticValue = getStaticValue(update.right, sourceCode.getScope(update));
60
+
61
+ if (staticValue && ["bigint", "boolean", "number"].includes(typeof staticValue.value)) {
62
+ const sign = Math.sign(Number(staticValue.value)) || 0; // convert NaN to 0
63
+
64
+ return dir * sign;
58
65
  }
59
- return dir;
66
+ return 0;
60
67
  }
61
68
 
62
69
  /**
@@ -94,30 +101,37 @@ module.exports = {
94
101
  }
95
102
  return 0;
96
103
  }
104
+
97
105
  return {
98
106
  ForStatement(node) {
99
107
 
100
- if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) {
101
- const counter = node.test.left.name;
102
- const operator = node.test.operator;
103
- const update = node.update;
108
+ if (node.test && node.test.type === "BinaryExpression" && node.update) {
109
+ for (const counterPosition of ["left", "right"]) {
110
+ if (node.test[counterPosition].type !== "Identifier") {
111
+ continue;
112
+ }
113
+
114
+ const counter = node.test[counterPosition].name;
115
+ const operator = node.test.operator;
116
+ const update = node.update;
104
117
 
105
- let wrongDirection;
118
+ let wrongDirection;
106
119
 
107
- if (operator === "<" || operator === "<=") {
108
- wrongDirection = -1;
109
- } else if (operator === ">" || operator === ">=") {
110
- wrongDirection = 1;
111
- } else {
112
- return;
113
- }
120
+ if (operator === "<" || operator === "<=") {
121
+ wrongDirection = counterPosition === "left" ? -1 : 1;
122
+ } else if (operator === ">" || operator === ">=") {
123
+ wrongDirection = counterPosition === "left" ? 1 : -1;
124
+ } else {
125
+ return;
126
+ }
114
127
 
115
- if (update.type === "UpdateExpression") {
116
- if (getUpdateDirection(update, counter) === wrongDirection) {
128
+ if (update.type === "UpdateExpression") {
129
+ if (getUpdateDirection(update, counter) === wrongDirection) {
130
+ report(node);
131
+ }
132
+ } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) {
117
133
  report(node);
118
134
  }
119
- } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) {
120
- report(node);
121
135
  }
122
136
  }
123
137
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to control spacing within function calls
3
3
  * @author Matt DuVall <http://www.mattduvall.com>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -18,6 +19,8 @@ const astUtils = require("./utils/ast-utils");
18
19
  /** @type {import('../shared/types').Rule} */
19
20
  module.exports = {
20
21
  meta: {
22
+ deprecated: true,
23
+ replacedBy: [],
21
24
  type: "layout",
22
25
 
23
26
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to enforce line breaks between arguments of a function call
3
3
  * @author Alexey Gonchar <https://github.com/finico>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -12,6 +13,8 @@
12
13
  /** @type {import('../shared/types').Rule} */
13
14
  module.exports = {
14
15
  meta: {
16
+ deprecated: true,
17
+ replacedBy: [],
15
18
  type: "layout",
16
19
 
17
20
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview enforce consistent line breaks inside function parentheses
3
3
  * @author Teddy Katz
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -17,6 +18,8 @@ const astUtils = require("./utils/ast-utils");
17
18
  /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
21
+ deprecated: true,
22
+ replacedBy: [],
20
23
  type: "layout",
21
24
 
22
25
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to check the spacing around the * in generator functions.
3
3
  * @author Jamund Ferguson
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -28,6 +29,8 @@ const OVERRIDE_SCHEMA = {
28
29
  /** @type {import('../shared/types').Rule} */
29
30
  module.exports = {
30
31
  meta: {
32
+ deprecated: true,
33
+ replacedBy: [],
31
34
  type: "layout",
32
35
 
33
36
  docs: {
@@ -14,15 +14,23 @@ const astUtils = require("./utils/ast-utils");
14
14
  //------------------------------------------------------------------------------
15
15
  // Helpers
16
16
  //------------------------------------------------------------------------------
17
+
17
18
  const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
18
19
 
19
20
  /**
20
- * Checks a given code path segment is reachable.
21
- * @param {CodePathSegment} segment A segment to check.
22
- * @returns {boolean} `true` if the segment is reachable.
21
+ * Checks all segments in a set and returns true if any are reachable.
22
+ * @param {Set<CodePathSegment>} segments The segments to check.
23
+ * @returns {boolean} True if any segment is reachable; false otherwise.
23
24
  */
24
- function isReachable(segment) {
25
- return segment.reachable;
25
+ function isAnySegmentReachable(segments) {
26
+
27
+ for (const segment of segments) {
28
+ if (segment.reachable) {
29
+ return true;
30
+ }
31
+ }
32
+
33
+ return false;
26
34
  }
27
35
 
28
36
  //------------------------------------------------------------------------------
@@ -71,7 +79,8 @@ module.exports = {
71
79
  codePath: null,
72
80
  hasReturn: false,
73
81
  shouldCheck: false,
74
- node: null
82
+ node: null,
83
+ currentSegments: []
75
84
  };
76
85
 
77
86
  /**
@@ -85,7 +94,7 @@ module.exports = {
85
94
  */
86
95
  function checkLastSegment(node) {
87
96
  if (funcInfo.shouldCheck &&
88
- funcInfo.codePath.currentSegments.some(isReachable)
97
+ isAnySegmentReachable(funcInfo.currentSegments)
89
98
  ) {
90
99
  context.report({
91
100
  node,
@@ -144,7 +153,8 @@ module.exports = {
144
153
  codePath,
145
154
  hasReturn: false,
146
155
  shouldCheck: isGetter(node),
147
- node
156
+ node,
157
+ currentSegments: new Set()
148
158
  };
149
159
  },
150
160
 
@@ -152,6 +162,21 @@ module.exports = {
152
162
  onCodePathEnd() {
153
163
  funcInfo = funcInfo.upper;
154
164
  },
165
+ onUnreachableCodePathSegmentStart(segment) {
166
+ funcInfo.currentSegments.add(segment);
167
+ },
168
+
169
+ onUnreachableCodePathSegmentEnd(segment) {
170
+ funcInfo.currentSegments.delete(segment);
171
+ },
172
+
173
+ onCodePathSegmentStart(segment) {
174
+ funcInfo.currentSegments.add(segment);
175
+ },
176
+
177
+ onCodePathSegmentEnd(segment) {
178
+ funcInfo.currentSegments.delete(segment);
179
+ },
155
180
 
156
181
  // Checks the return statement is valid.
157
182
  ReturnStatement(node) {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview enforce the location of arrow function bodies
3
3
  * @author Sharmila Jesupaul
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -12,6 +13,8 @@ const { isCommentToken, isNotOpeningParenToken } = require("./utils/ast-utils");
12
13
  /** @type {import('../shared/types').Rule} */
13
14
  module.exports = {
14
15
  meta: {
16
+ deprecated: true,
17
+ replacedBy: [],
15
18
  type: "layout",
16
19
 
17
20
  docs: {
@@ -4,6 +4,7 @@
4
4
  * @author Teddy Katz
5
5
  * @author Vitaly Puzrin
6
6
  * @author Gyandeep Singh
7
+ * @deprecated in ESLint v8.53.0
7
8
  */
8
9
 
9
10
  "use strict";
@@ -493,6 +494,8 @@ const ELEMENT_LIST_SCHEMA = {
493
494
  /** @type {import('../shared/types').Rule} */
494
495
  module.exports = {
495
496
  meta: {
497
+ deprecated: true,
498
+ replacedBy: [],
496
499
  type: "layout",
497
500
 
498
501
  docs: {
@@ -175,6 +175,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
175
175
  "no-new-wrappers": () => require("./no-new-wrappers"),
176
176
  "no-nonoctal-decimal-escape": () => require("./no-nonoctal-decimal-escape"),
177
177
  "no-obj-calls": () => require("./no-obj-calls"),
178
+ "no-object-constructor": () => require("./no-object-constructor"),
178
179
  "no-octal": () => require("./no-octal"),
179
180
  "no-octal-escape": () => require("./no-octal-escape"),
180
181
  "no-param-reassign": () => require("./no-param-reassign"),
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview A rule to ensure consistent quotes used in jsx syntax.
3
3
  * @author Mathias Schreck <https://github.com/lo1tuma>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -39,6 +40,8 @@ const QUOTE_SETTINGS = {
39
40
  /** @type {import('../shared/types').Rule} */
40
41
  module.exports = {
41
42
  meta: {
43
+ deprecated: true,
44
+ replacedBy: [],
42
45
  type: "layout",
43
46
 
44
47
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to specify spacing of object literal keys and values
3
3
  * @author Brandon Mills
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -133,6 +134,8 @@ function initOptions(toOptions, fromOptions) {
133
134
  /** @type {import('../shared/types').Rule} */
134
135
  module.exports = {
135
136
  meta: {
137
+ deprecated: true,
138
+ replacedBy: [],
136
139
  type: "layout",
137
140
 
138
141
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to enforce spacing before and after keywords.
3
3
  * @author Toru Nagashima
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -64,6 +65,8 @@ function isCloseParenOfTemplate(token) {
64
65
  /** @type {import('../shared/types').Rule} */
65
66
  module.exports = {
66
67
  meta: {
68
+ deprecated: true,
69
+ replacedBy: [],
67
70
  type: "layout",
68
71
 
69
72
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to enforce a single linebreak style.
3
3
  * @author Erik Mueller
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -18,6 +19,8 @@ const astUtils = require("./utils/ast-utils");
18
19
  /** @type {import('../shared/types').Rule} */
19
20
  module.exports = {
20
21
  meta: {
22
+ deprecated: true,
23
+ replacedBy: [],
21
24
  type: "layout",
22
25
 
23
26
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Enforces empty lines around comments.
3
3
  * @author Jamund Ferguson
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -52,6 +53,8 @@ function getCommentLineNums(comments) {
52
53
  /** @type {import('../shared/types').Rule} */
53
54
  module.exports = {
54
55
  meta: {
56
+ deprecated: true,
57
+ replacedBy: [],
55
58
  type: "layout",
56
59
 
57
60
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to check empty newline between class members
3
3
  * @author 薛定谔的猫<hh_2013@foxmail.com>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -10,6 +11,21 @@
10
11
 
11
12
  const astUtils = require("./utils/ast-utils");
12
13
 
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ /**
19
+ * Types of class members.
20
+ * Those have `test` method to check it matches to the given class member.
21
+ * @private
22
+ */
23
+ const ClassMemberTypes = {
24
+ "*": { test: () => true },
25
+ field: { test: node => node.type === "PropertyDefinition" },
26
+ method: { test: node => node.type === "MethodDefinition" }
27
+ };
28
+
13
29
  //------------------------------------------------------------------------------
14
30
  // Rule Definition
15
31
  //------------------------------------------------------------------------------
@@ -17,6 +33,8 @@ const astUtils = require("./utils/ast-utils");
17
33
  /** @type {import('../shared/types').Rule} */
18
34
  module.exports = {
19
35
  meta: {
36
+ deprecated: true,
37
+ replacedBy: [],
20
38
  type: "layout",
21
39
 
22
40
  docs: {
@@ -29,7 +47,32 @@ module.exports = {
29
47
 
30
48
  schema: [
31
49
  {
32
- enum: ["always", "never"]
50
+ anyOf: [
51
+ {
52
+ type: "object",
53
+ properties: {
54
+ enforce: {
55
+ type: "array",
56
+ items: {
57
+ type: "object",
58
+ properties: {
59
+ blankLine: { enum: ["always", "never"] },
60
+ prev: { enum: ["method", "field", "*"] },
61
+ next: { enum: ["method", "field", "*"] }
62
+ },
63
+ additionalProperties: false,
64
+ required: ["blankLine", "prev", "next"]
65
+ },
66
+ minItems: 1
67
+ }
68
+ },
69
+ additionalProperties: false,
70
+ required: ["enforce"]
71
+ },
72
+ {
73
+ enum: ["always", "never"]
74
+ }
75
+ ]
33
76
  },
34
77
  {
35
78
  type: "object",
@@ -55,6 +98,7 @@ module.exports = {
55
98
  options[0] = context.options[0] || "always";
56
99
  options[1] = context.options[1] || { exceptAfterSingleLine: false };
57
100
 
101
+ const configureList = typeof options[0] === "object" ? options[0].enforce : [{ blankLine: options[0], prev: "*", next: "*" }];
58
102
  const sourceCode = context.sourceCode;
59
103
 
60
104
  /**
@@ -144,6 +188,38 @@ module.exports = {
144
188
  return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0;
145
189
  }
146
190
 
191
+ /**
192
+ * Checks whether the given node matches the given type.
193
+ * @param {ASTNode} node The class member node to check.
194
+ * @param {string} type The class member type to check.
195
+ * @returns {boolean} `true` if the class member node matched the type.
196
+ * @private
197
+ */
198
+ function match(node, type) {
199
+ return ClassMemberTypes[type].test(node);
200
+ }
201
+
202
+ /**
203
+ * Finds the last matched configuration from the configureList.
204
+ * @param {ASTNode} prevNode The previous node to match.
205
+ * @param {ASTNode} nextNode The current node to match.
206
+ * @returns {string|null} Padding type or `null` if no matches were found.
207
+ * @private
208
+ */
209
+ function getPaddingType(prevNode, nextNode) {
210
+ for (let i = configureList.length - 1; i >= 0; --i) {
211
+ const configure = configureList[i];
212
+ const matched =
213
+ match(prevNode, configure.prev) &&
214
+ match(nextNode, configure.next);
215
+
216
+ if (matched) {
217
+ return configure.blankLine;
218
+ }
219
+ }
220
+ return null;
221
+ }
222
+
147
223
  return {
148
224
  ClassBody(node) {
149
225
  const body = node.body;
@@ -158,22 +234,34 @@ module.exports = {
158
234
  const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1;
159
235
  const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding);
160
236
  const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0);
237
+ const paddingType = getPaddingType(body[i], body[i + 1]);
238
+
239
+ if (paddingType === "never" && isPadded) {
240
+ context.report({
241
+ node: body[i + 1],
242
+ messageId: "never",
161
243
 
162
- if ((options[0] === "always" && !skip && !isPadded) ||
163
- (options[0] === "never" && isPadded)) {
244
+ fix(fixer) {
245
+ if (hasTokenInPadding) {
246
+ return null;
247
+ }
248
+ return fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n");
249
+ }
250
+ });
251
+ } else if (paddingType === "always" && !skip && !isPadded) {
164
252
  context.report({
165
253
  node: body[i + 1],
166
- messageId: isPadded ? "never" : "always",
254
+ messageId: "always",
255
+
167
256
  fix(fixer) {
168
257
  if (hasTokenInPadding) {
169
258
  return null;
170
259
  }
171
- return isPadded
172
- ? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n")
173
- : fixer.insertTextAfter(curLineLastToken, "\n");
260
+ return fixer.insertTextAfter(curLineLastToken, "\n");
174
261
  }
175
262
  });
176
263
  }
264
+
177
265
  }
178
266
  }
179
267
  };
@@ -150,6 +150,31 @@ function isInsideWithBlock(node) {
150
150
  return node.parent.type === "WithStatement" && node.parent.body === node ? true : isInsideWithBlock(node.parent);
151
151
  }
152
152
 
153
+ /**
154
+ * Gets the leftmost operand of a consecutive logical expression.
155
+ * @param {SourceCode} sourceCode The ESLint source code object
156
+ * @param {LogicalExpression} node LogicalExpression
157
+ * @returns {Expression} Leftmost operand
158
+ */
159
+ function getLeftmostOperand(sourceCode, node) {
160
+ let left = node.left;
161
+
162
+ while (left.type === "LogicalExpression" && left.operator === node.operator) {
163
+
164
+ if (astUtils.isParenthesised(sourceCode, left)) {
165
+
166
+ /*
167
+ * It should have associativity,
168
+ * but ignore it if use parentheses to make the evaluation order clear.
169
+ */
170
+ return left;
171
+ }
172
+ left = left.left;
173
+ }
174
+ return left;
175
+
176
+ }
177
+
153
178
  //------------------------------------------------------------------------------
154
179
  // Rule Definition
155
180
  //------------------------------------------------------------------------------
@@ -318,7 +343,10 @@ module.exports = {
318
343
 
319
344
  // foo = foo || bar
320
345
  "AssignmentExpression[operator='='][right.type='LogicalExpression']"(assignment) {
321
- if (!astUtils.isSameReference(assignment.left, assignment.right.left)) {
346
+ const leftOperand = getLeftmostOperand(sourceCode, assignment.right);
347
+
348
+ if (!astUtils.isSameReference(assignment.left, leftOperand)
349
+ ) {
322
350
  return;
323
351
  }
324
352
 
@@ -342,10 +370,10 @@ module.exports = {
342
370
  yield ruleFixer.insertTextBefore(assignmentOperatorToken, assignment.right.operator);
343
371
 
344
372
  // -> foo ||= bar
345
- const logicalOperatorToken = getOperatorToken(assignment.right);
373
+ const logicalOperatorToken = getOperatorToken(leftOperand.parent);
346
374
  const firstRightOperandToken = sourceCode.getTokenAfter(logicalOperatorToken);
347
375
 
348
- yield ruleFixer.removeRange([assignment.right.range[0], firstRightOperandToken.range[0]]);
376
+ yield ruleFixer.removeRange([leftOperand.parent.range[0], firstRightOperandToken.range[0]]);
349
377
  }
350
378
  };
351
379
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to check for max length on a line.
3
3
  * @author Matt DuVall <http://www.mattduvall.com>
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -66,6 +67,8 @@ const OPTIONS_OR_INTEGER_SCHEMA = {
66
67
  /** @type {import('../shared/types').Rule} */
67
68
  module.exports = {
68
69
  meta: {
70
+ deprecated: true,
71
+ replacedBy: [],
69
72
  type: "layout",
70
73
 
71
74
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Specify the maximum number of statements allowed per line.
3
3
  * @author Kenneth Williams
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
  "use strict";
6
7
 
@@ -17,6 +18,8 @@ const astUtils = require("./utils/ast-utils");
17
18
  /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
21
+ deprecated: true,
22
+ replacedBy: [],
20
23
  type: "layout",
21
24
 
22
25
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Enforce newlines between operands of ternary expressions
3
3
  * @author Kai Cataldo
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
14
15
  /** @type {import('../shared/types').Rule} */
15
16
  module.exports = {
16
17
  meta: {
18
+ deprecated: true,
19
+ replacedBy: [],
17
20
  type: "layout",
18
21
 
19
22
  docs: {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to flag when using constructor without parentheses
3
3
  * @author Ilya Volodin
4
+ * @deprecated in ESLint v8.53.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -22,6 +23,8 @@ const astUtils = require("./utils/ast-utils");
22
23
  /** @type {import('../shared/types').Rule} */
23
24
  module.exports = {
24
25
  meta: {
26
+ deprecated: true,
27
+ replacedBy: [],
25
28
  type: "layout",
26
29
 
27
30
  docs: {