eslint-plugin-unicorn 67.0.0 → 69.0.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 (192) hide show
  1. package/index.js +4 -0
  2. package/package.json +8 -3
  3. package/readme.md +165 -16
  4. package/rules/ast/is-empty-node.js +1 -5
  5. package/rules/ast/is-empty-object-expression.js +2 -2
  6. package/rules/better-dom-traversing.js +17 -8
  7. package/rules/class-reference-in-static-methods.js +14 -2
  8. package/rules/comment-content.js +136 -18
  9. package/rules/consistent-assert.js +1 -1
  10. package/rules/consistent-boolean-name.js +44 -5
  11. package/rules/consistent-compound-words.js +7 -5
  12. package/rules/consistent-conditional-object-spread.js +360 -0
  13. package/rules/consistent-destructuring.js +5 -0
  14. package/rules/consistent-existence-index-check.js +1 -1
  15. package/rules/consistent-json-file-read.js +4 -16
  16. package/rules/consistent-optional-chaining.js +3 -20
  17. package/rules/consistent-tuple-labels.js +49 -0
  18. package/rules/custom-error-definition.js +26 -7
  19. package/rules/default-export-style.js +569 -0
  20. package/rules/expiring-todo-comments.js +1 -1
  21. package/rules/explicit-length-check.js +7 -32
  22. package/rules/import-style.js +8 -6
  23. package/rules/index.js +50 -1
  24. package/rules/logical-assignment-operators.js +17 -4
  25. package/rules/{prevent-abbreviations.js → name-replacements.js} +11 -9
  26. package/rules/new-for-builtins.js +39 -5
  27. package/rules/no-accessor-recursion.js +7 -0
  28. package/rules/no-accidental-bitwise-operator.js +97 -0
  29. package/rules/no-array-callback-reference.js +1 -7
  30. package/rules/no-array-concat-in-loop.js +45 -0
  31. package/rules/no-array-front-mutation.js +64 -0
  32. package/rules/no-array-sort-for-min-max.js +225 -0
  33. package/rules/no-array-splice.js +78 -64
  34. package/rules/no-boolean-sort-comparator.js +215 -0
  35. package/rules/no-break-in-nested-loop.js +33 -0
  36. package/rules/no-chained-comparison.js +116 -0
  37. package/rules/no-collection-bracket-access.js +165 -0
  38. package/rules/no-computed-property-existence-check.js +6 -0
  39. package/rules/no-confusing-array-splice.js +2 -21
  40. package/rules/no-confusing-array-with.js +2 -20
  41. package/rules/no-constant-zero-expression.js +91 -0
  42. package/rules/no-declarations-before-early-exit.js +29 -36
  43. package/rules/no-double-comparison.js +117 -0
  44. package/rules/no-duplicate-if-branches.js +143 -0
  45. package/rules/no-duplicate-logical-operands.js +151 -0
  46. package/rules/no-for-each.js +11 -12
  47. package/rules/no-for-loop.js +3 -15
  48. package/rules/no-impossible-length-comparison.js +166 -0
  49. package/rules/no-incorrect-query-selector.js +8 -4
  50. package/rules/no-incorrect-template-string-interpolation.js +106 -43
  51. package/rules/no-instanceof-builtins.js +73 -14
  52. package/rules/no-invalid-argument-count.js +110 -54
  53. package/rules/no-invalid-character-comparison.js +121 -0
  54. package/rules/no-invalid-fetch-options.js +3 -1
  55. package/rules/no-invalid-well-known-symbol-methods.js +205 -0
  56. package/rules/no-keyword-prefix.js +14 -4
  57. package/rules/no-late-current-target-access.js +13 -107
  58. package/rules/no-late-event-control.js +127 -0
  59. package/rules/no-loop-iterable-mutation.js +541 -0
  60. package/rules/no-manually-wrapped-comments.js +10 -2
  61. package/rules/no-misrefactored-assignment.js +102 -0
  62. package/rules/no-named-default.js +35 -2
  63. package/rules/no-nonstandard-builtin-properties.js +1383 -0
  64. package/rules/no-object-methods-with-collections.js +4 -289
  65. package/rules/no-process-exit.js +16 -12
  66. package/rules/no-redundant-comparison.js +5 -12
  67. package/rules/no-return-array-push.js +20 -5
  68. package/rules/no-selector-as-dom-name.js +150 -0
  69. package/rules/no-thenable.js +27 -11
  70. package/rules/no-top-level-side-effects.js +8 -1
  71. package/rules/no-uncalled-method.js +2 -8
  72. package/rules/no-undeclared-class-members.js +8 -6
  73. package/rules/no-unnecessary-boolean-comparison.js +131 -0
  74. package/rules/no-unnecessary-global-this.js +36 -1
  75. package/rules/no-unnecessary-splice.js +15 -20
  76. package/rules/no-unreadable-for-of-expression.js +2 -1
  77. package/rules/no-unreadable-object-destructuring.js +15 -0
  78. package/rules/no-unsafe-property-key.js +10 -15
  79. package/rules/no-unsafe-string-replacement.js +31 -0
  80. package/rules/no-unused-array-method-return.js +11 -2
  81. package/rules/no-unused-properties.js +4 -3
  82. package/rules/no-useless-boolean-cast.js +58 -1
  83. package/rules/no-useless-coercion.js +71 -15
  84. package/rules/no-useless-compound-assignment.js +110 -0
  85. package/rules/no-useless-concat.js +27 -3
  86. package/rules/no-useless-delete-check.js +353 -0
  87. package/rules/no-useless-else.js +27 -62
  88. package/rules/no-useless-error-capture-stack-trace.js +1 -1
  89. package/rules/no-useless-fallback-in-spread.js +7 -118
  90. package/rules/no-useless-iterator-to-array.js +165 -115
  91. package/rules/no-useless-logical-operand.js +248 -0
  92. package/rules/no-useless-undefined.js +11 -28
  93. package/rules/no-xor-as-exponentiation.js +59 -0
  94. package/rules/prefer-abort-signal-timeout.js +395 -0
  95. package/rules/prefer-aggregate-error.js +478 -0
  96. package/rules/prefer-array-find.js +95 -5
  97. package/rules/prefer-array-flat-map.js +9 -21
  98. package/rules/prefer-array-flat.js +1 -24
  99. package/rules/prefer-array-from-async.js +273 -0
  100. package/rules/prefer-array-iterable-methods.js +157 -0
  101. package/rules/prefer-array-some.js +56 -31
  102. package/rules/prefer-at.js +6 -30
  103. package/rules/prefer-await.js +29 -0
  104. package/rules/prefer-boolean-return.js +224 -0
  105. package/rules/prefer-code-point.js +58 -8
  106. package/rules/prefer-continue.js +377 -0
  107. package/rules/prefer-default-parameters.js +10 -6
  108. package/rules/prefer-dispose.js +1 -5
  109. package/rules/prefer-dom-node-replace-children.js +353 -0
  110. package/rules/prefer-early-return.js +160 -30
  111. package/rules/prefer-else-if.js +50 -53
  112. package/rules/prefer-error-is-error.js +181 -0
  113. package/rules/prefer-event-target.js +3 -13
  114. package/rules/prefer-flat-math-min-max.js +103 -0
  115. package/rules/prefer-global-this.js +1 -1
  116. package/rules/prefer-has-check.js +1 -4
  117. package/rules/prefer-hoisting-branch-code.js +424 -0
  118. package/rules/prefer-identifier-import-export-specifiers.js +6 -11
  119. package/rules/prefer-includes-over-repeated-comparisons.js +5 -1
  120. package/rules/prefer-includes.js +6 -0
  121. package/rules/prefer-iterator-concat.js +21 -1
  122. package/rules/prefer-logical-operator-over-ternary.js +12 -20
  123. package/rules/prefer-math-constants.js +103 -0
  124. package/rules/prefer-math-min-max.js +1 -5
  125. package/rules/prefer-minimal-ternary.js +41 -13
  126. package/rules/prefer-modern-dom-apis.js +1 -45
  127. package/rules/prefer-node-protocol.js +1 -0
  128. package/rules/prefer-number-properties.js +2 -5
  129. package/rules/prefer-object-from-entries.js +6 -1
  130. package/rules/prefer-object-iterable-methods.js +36 -11
  131. package/rules/prefer-observer-apis.js +498 -0
  132. package/rules/prefer-optional-catch-binding.js +30 -24
  133. package/rules/prefer-private-class-fields.js +2 -8
  134. package/rules/prefer-promise-try.js +238 -0
  135. package/rules/prefer-promise-with-resolvers.js +248 -0
  136. package/rules/prefer-query-selector.js +79 -17
  137. package/rules/prefer-queue-microtask.js +7 -9
  138. package/rules/prefer-regexp-escape.js +263 -0
  139. package/rules/prefer-set-methods.js +337 -0
  140. package/rules/prefer-set-size.js +10 -2
  141. package/rules/prefer-short-arrow-method.js +3 -3
  142. package/rules/prefer-single-replace.js +218 -0
  143. package/rules/prefer-spread.js +14 -21
  144. package/rules/prefer-string-replace-all.js +5 -0
  145. package/rules/prefer-structured-clone.js +2 -2
  146. package/rules/prefer-switch.js +1 -0
  147. package/rules/prefer-ternary.js +4 -2
  148. package/rules/prefer-toggle-attribute.js +293 -0
  149. package/rules/prefer-type-literal-last.js +22 -54
  150. package/rules/prefer-unary-minus.js +103 -0
  151. package/rules/prefer-url-can-parse.js +308 -0
  152. package/rules/prefer-url-search-parameters.js +411 -0
  153. package/rules/prefer-while-loop-condition.js +252 -0
  154. package/rules/require-passive-events.js +11 -4
  155. package/rules/require-proxy-trap-boolean-return.js +40 -126
  156. package/rules/rule/to-eslint-listener.js +5 -3
  157. package/rules/shared/array-concat-in-loop.js +151 -0
  158. package/rules/shared/identifier-checks.js +4 -16
  159. package/rules/shared/late-event-handler.js +82 -0
  160. package/rules/shared/{abbreviations.js → name-replacements.js} +63 -0
  161. package/rules/shared/no-array-mutate-rule.js +19 -2
  162. package/rules/shared/regexp-escape.js +81 -0
  163. package/rules/shared/splice-replacements.js +1 -18
  164. package/rules/string-content.js +11 -4
  165. package/rules/template-indent.js +2 -8
  166. package/rules/throw-new-error.js +7 -0
  167. package/rules/utils/block-scope.js +42 -0
  168. package/rules/utils/builtin-collection-type.js +267 -0
  169. package/rules/utils/builtins.js +50 -1
  170. package/rules/utils/comments.js +16 -0
  171. package/rules/utils/comparison.js +17 -0
  172. package/rules/utils/contains-suspension-point.js +35 -0
  173. package/rules/utils/get-const-variable-initializer.js +31 -0
  174. package/rules/utils/global-reference-tracker.js +14 -1
  175. package/rules/utils/has-optional-chain-element.js +36 -4
  176. package/rules/utils/index.js +38 -2
  177. package/rules/utils/is-boolean.js +26 -1
  178. package/rules/utils/is-event.js +127 -0
  179. package/rules/utils/is-function-self-used-inside.js +1 -5
  180. package/rules/utils/is-weak-map.js +21 -0
  181. package/rules/utils/is-weak-set.js +21 -0
  182. package/rules/utils/length-or-size.js +53 -0
  183. package/rules/utils/member-expression.js +18 -0
  184. package/rules/utils/needs-semicolon.js +1 -5
  185. package/rules/utils/numeric.js +20 -0
  186. package/rules/utils/should-add-parentheses-to-logical-expression-child.js +8 -14
  187. package/rules/utils/should-add-parentheses-to-member-expression-object.js +1 -5
  188. package/rules/utils/should-add-parentheses-to-unary-expression.js +8 -2
  189. package/rules/utils/should-report-replace-children-receiver.js +210 -0
  190. package/rules/utils/track-branch-exits.js +79 -0
  191. package/rules/utils/type-helpers.js +166 -8
  192. package/rules/utils/types.js +22 -0
package/rules/index.js CHANGED
@@ -8,6 +8,7 @@ export {default as 'consistent-assert'} from './consistent-assert.js';
8
8
  export {default as 'consistent-boolean-name'} from './consistent-boolean-name.js';
9
9
  export {default as 'consistent-class-member-order'} from './consistent-class-member-order.js';
10
10
  export {default as 'consistent-compound-words'} from './consistent-compound-words.js';
11
+ export {default as 'consistent-conditional-object-spread'} from './consistent-conditional-object-spread.js';
11
12
  export {default as 'consistent-date-clone'} from './consistent-date-clone.js';
12
13
  export {default as 'consistent-destructuring'} from './consistent-destructuring.js';
13
14
  export {default as 'consistent-empty-array-spread'} from './consistent-empty-array-spread.js';
@@ -18,7 +19,9 @@ export {default as 'consistent-function-style'} from './consistent-function-styl
18
19
  export {default as 'consistent-json-file-read'} from './consistent-json-file-read.js';
19
20
  export {default as 'consistent-optional-chaining'} from './consistent-optional-chaining.js';
20
21
  export {default as 'consistent-template-literal-escape'} from './consistent-template-literal-escape.js';
22
+ export {default as 'consistent-tuple-labels'} from './consistent-tuple-labels.js';
21
23
  export {default as 'custom-error-definition'} from './custom-error-definition.js';
24
+ export {default as 'default-export-style'} from './default-export-style.js';
22
25
  export {default as 'dom-node-dataset'} from './dom-node-dataset.js';
23
26
  export {default as 'empty-brace-spaces'} from './empty-brace-spaces.js';
24
27
  export {default as 'error-message'} from './error-message.js';
@@ -32,30 +35,42 @@ export {default as 'import-style'} from './import-style.js';
32
35
  export {default as 'isolated-functions'} from './isolated-functions.js';
33
36
  export {default as 'logical-assignment-operators'} from './logical-assignment-operators.js';
34
37
  export {default as 'max-nested-calls'} from './max-nested-calls.js';
38
+ export {default as 'name-replacements'} from './name-replacements.js';
35
39
  export {default as 'new-for-builtins'} from './new-for-builtins.js';
36
40
  export {default as 'no-abusive-eslint-disable'} from './no-abusive-eslint-disable.js';
37
41
  export {default as 'no-accessor-recursion'} from './no-accessor-recursion.js';
42
+ export {default as 'no-accidental-bitwise-operator'} from './no-accidental-bitwise-operator.js';
38
43
  export {default as 'no-anonymous-default-export'} from './no-anonymous-default-export.js';
39
44
  export {default as 'no-array-callback-reference'} from './no-array-callback-reference.js';
45
+ export {default as 'no-array-concat-in-loop'} from './no-array-concat-in-loop.js';
40
46
  export {default as 'no-array-fill-with-reference-type'} from './no-array-fill-with-reference-type.js';
41
47
  export {default as 'no-array-from-fill'} from './no-array-from-fill.js';
48
+ export {default as 'no-array-front-mutation'} from './no-array-front-mutation.js';
42
49
  export {default as 'no-array-method-this-argument'} from './no-array-method-this-argument.js';
43
50
  export {default as 'no-array-reduce'} from './no-array-reduce.js';
44
51
  export {default as 'no-array-reverse'} from './no-array-reverse.js';
52
+ export {default as 'no-array-sort-for-min-max'} from './no-array-sort-for-min-max.js';
45
53
  export {default as 'no-array-sort'} from './no-array-sort.js';
46
54
  export {default as 'no-array-splice'} from './no-array-splice.js';
47
55
  export {default as 'no-asterisk-prefix-in-documentation-comments'} from './no-asterisk-prefix-in-documentation-comments.js';
48
56
  export {default as 'no-await-expression-member'} from './no-await-expression-member.js';
49
57
  export {default as 'no-await-in-promise-methods'} from './no-await-in-promise-methods.js';
50
58
  export {default as 'no-blob-to-file'} from './no-blob-to-file.js';
59
+ export {default as 'no-boolean-sort-comparator'} from './no-boolean-sort-comparator.js';
51
60
  export {default as 'no-break-in-nested-loop'} from './no-break-in-nested-loop.js';
52
61
  export {default as 'no-canvas-to-image'} from './no-canvas-to-image.js';
62
+ export {default as 'no-chained-comparison'} from './no-chained-comparison.js';
63
+ export {default as 'no-collection-bracket-access'} from './no-collection-bracket-access.js';
53
64
  export {default as 'no-computed-property-existence-check'} from './no-computed-property-existence-check.js';
54
65
  export {default as 'no-confusing-array-splice'} from './no-confusing-array-splice.js';
55
66
  export {default as 'no-confusing-array-with'} from './no-confusing-array-with.js';
56
67
  export {default as 'no-console-spaces'} from './no-console-spaces.js';
68
+ export {default as 'no-constant-zero-expression'} from './no-constant-zero-expression.js';
57
69
  export {default as 'no-declarations-before-early-exit'} from './no-declarations-before-early-exit.js';
58
70
  export {default as 'no-document-cookie'} from './no-document-cookie.js';
71
+ export {default as 'no-double-comparison'} from './no-double-comparison.js';
72
+ export {default as 'no-duplicate-if-branches'} from './no-duplicate-if-branches.js';
73
+ export {default as 'no-duplicate-logical-operands'} from './no-duplicate-logical-operands.js';
59
74
  export {default as 'no-duplicate-loops'} from './no-duplicate-loops.js';
60
75
  export {default as 'no-duplicate-set-values'} from './no-duplicate-set-values.js';
61
76
  export {default as 'no-empty-file'} from './no-empty-file.js';
@@ -65,19 +80,25 @@ export {default as 'no-for-each'} from './no-for-each.js';
65
80
  export {default as 'no-for-loop'} from './no-for-loop.js';
66
81
  export {default as 'no-global-object-property-assignment'} from './no-global-object-property-assignment.js';
67
82
  export {default as 'no-immediate-mutation'} from './no-immediate-mutation.js';
83
+ export {default as 'no-impossible-length-comparison'} from './no-impossible-length-comparison.js';
68
84
  export {default as 'no-incorrect-query-selector'} from './no-incorrect-query-selector.js';
69
85
  export {default as 'no-incorrect-template-string-interpolation'} from './no-incorrect-template-string-interpolation.js';
70
86
  export {default as 'no-instanceof-builtins'} from './no-instanceof-builtins.js';
71
87
  export {default as 'no-invalid-argument-count'} from './no-invalid-argument-count.js';
88
+ export {default as 'no-invalid-character-comparison'} from './no-invalid-character-comparison.js';
72
89
  export {default as 'no-invalid-fetch-options'} from './no-invalid-fetch-options.js';
73
90
  export {default as 'no-invalid-file-input-accept'} from './no-invalid-file-input-accept.js';
74
91
  export {default as 'no-invalid-remove-event-listener'} from './no-invalid-remove-event-listener.js';
92
+ export {default as 'no-invalid-well-known-symbol-methods'} from './no-invalid-well-known-symbol-methods.js';
75
93
  export {default as 'no-keyword-prefix'} from './no-keyword-prefix.js';
76
94
  export {default as 'no-late-current-target-access'} from './no-late-current-target-access.js';
95
+ export {default as 'no-late-event-control'} from './no-late-event-control.js';
77
96
  export {default as 'no-lonely-if'} from './no-lonely-if.js';
97
+ export {default as 'no-loop-iterable-mutation'} from './no-loop-iterable-mutation.js';
78
98
  export {default as 'no-magic-array-flat-depth'} from './no-magic-array-flat-depth.js';
79
99
  export {default as 'no-manually-wrapped-comments'} from './no-manually-wrapped-comments.js';
80
100
  export {default as 'no-mismatched-map-key'} from './no-mismatched-map-key.js';
101
+ export {default as 'no-misrefactored-assignment'} from './no-misrefactored-assignment.js';
81
102
  export {default as 'no-named-default'} from './no-named-default.js';
82
103
  export {default as 'no-negated-array-predicate'} from './no-negated-array-predicate.js';
83
104
  export {default as 'no-negated-comparison'} from './no-negated-comparison.js';
@@ -87,6 +108,7 @@ export {default as 'no-nested-ternary'} from './no-nested-ternary.js';
87
108
  export {default as 'no-new-array'} from './no-new-array.js';
88
109
  export {default as 'no-new-buffer'} from './no-new-buffer.js';
89
110
  export {default as 'no-non-function-verb-prefix'} from './no-non-function-verb-prefix.js';
111
+ export {default as 'no-nonstandard-builtin-properties'} from './no-nonstandard-builtin-properties.js';
90
112
  export {default as 'no-null'} from './no-null.js';
91
113
  export {default as 'no-object-as-default-parameter'} from './no-object-as-default-parameter.js';
92
114
  export {default as 'no-object-methods-with-collections'} from './no-object-methods-with-collections.js';
@@ -94,6 +116,7 @@ export {default as 'no-optional-chaining-on-undeclared-variable'} from './no-opt
94
116
  export {default as 'no-process-exit'} from './no-process-exit.js';
95
117
  export {default as 'no-redundant-comparison'} from './no-redundant-comparison.js';
96
118
  export {default as 'no-return-array-push'} from './no-return-array-push.js';
119
+ export {default as 'no-selector-as-dom-name'} from './no-selector-as-dom-name.js';
97
120
  export {default as 'no-single-promise-in-promise-methods'} from './no-single-promise-in-promise-methods.js';
98
121
  export {default as 'no-static-only-class'} from './no-static-only-class.js';
99
122
  export {default as 'no-subtraction-comparison'} from './no-subtraction-comparison.js';
@@ -108,6 +131,7 @@ export {default as 'no-undeclared-class-members'} from './no-undeclared-class-me
108
131
  export {default as 'no-unnecessary-array-flat-depth'} from './no-unnecessary-array-flat-depth.js';
109
132
  export {default as 'no-unnecessary-array-splice-count'} from './no-unnecessary-array-splice-count.js';
110
133
  export {default as 'no-unnecessary-await'} from './no-unnecessary-await.js';
134
+ export {default as 'no-unnecessary-boolean-comparison'} from './no-unnecessary-boolean-comparison.js';
111
135
  export {default as 'no-unnecessary-global-this'} from './no-unnecessary-global-this.js';
112
136
  export {default as 'no-unnecessary-nested-ternary'} from './no-unnecessary-nested-ternary.js';
113
137
  export {default as 'no-unnecessary-polyfills'} from './no-unnecessary-polyfills.js';
@@ -127,13 +151,16 @@ export {default as 'no-unused-properties'} from './no-unused-properties.js';
127
151
  export {default as 'no-useless-boolean-cast'} from './no-useless-boolean-cast.js';
128
152
  export {default as 'no-useless-coercion'} from './no-useless-coercion.js';
129
153
  export {default as 'no-useless-collection-argument'} from './no-useless-collection-argument.js';
154
+ export {default as 'no-useless-compound-assignment'} from './no-useless-compound-assignment.js';
130
155
  export {default as 'no-useless-concat'} from './no-useless-concat.js';
131
156
  export {default as 'no-useless-continue'} from './no-useless-continue.js';
157
+ export {default as 'no-useless-delete-check'} from './no-useless-delete-check.js';
132
158
  export {default as 'no-useless-else'} from './no-useless-else.js';
133
159
  export {default as 'no-useless-error-capture-stack-trace'} from './no-useless-error-capture-stack-trace.js';
134
160
  export {default as 'no-useless-fallback-in-spread'} from './no-useless-fallback-in-spread.js';
135
161
  export {default as 'no-useless-iterator-to-array'} from './no-useless-iterator-to-array.js';
136
162
  export {default as 'no-useless-length-check'} from './no-useless-length-check.js';
163
+ export {default as 'no-useless-logical-operand'} from './no-useless-logical-operand.js';
137
164
  export {default as 'no-useless-override'} from './no-useless-override.js';
138
165
  export {default as 'no-useless-promise-resolve-reject'} from './no-useless-promise-resolve-reject.js';
139
166
  export {default as 'no-useless-recursion'} from './no-useless-recursion.js';
@@ -141,17 +168,22 @@ export {default as 'no-useless-spread'} from './no-useless-spread.js';
141
168
  export {default as 'no-useless-switch-case'} from './no-useless-switch-case.js';
142
169
  export {default as 'no-useless-template-literals'} from './no-useless-template-literals.js';
143
170
  export {default as 'no-useless-undefined'} from './no-useless-undefined.js';
171
+ export {default as 'no-xor-as-exponentiation'} from './no-xor-as-exponentiation.js';
144
172
  export {default as 'no-zero-fractions'} from './no-zero-fractions.js';
145
173
  export {default as 'number-literal-case'} from './number-literal-case.js';
146
174
  export {default as 'numeric-separators-style'} from './numeric-separators-style.js';
147
175
  export {default as 'operator-assignment'} from './operator-assignment.js';
176
+ export {default as 'prefer-abort-signal-timeout'} from './prefer-abort-signal-timeout.js';
148
177
  export {default as 'prefer-add-event-listener-options'} from './prefer-add-event-listener-options.js';
149
178
  export {default as 'prefer-add-event-listener'} from './prefer-add-event-listener.js';
179
+ export {default as 'prefer-aggregate-error'} from './prefer-aggregate-error.js';
150
180
  export {default as 'prefer-array-find'} from './prefer-array-find.js';
151
181
  export {default as 'prefer-array-flat-map'} from './prefer-array-flat-map.js';
152
182
  export {default as 'prefer-array-flat'} from './prefer-array-flat.js';
183
+ export {default as 'prefer-array-from-async'} from './prefer-array-from-async.js';
153
184
  export {default as 'prefer-array-from-map'} from './prefer-array-from-map.js';
154
185
  export {default as 'prefer-array-index-of'} from './prefer-array-index-of.js';
186
+ export {default as 'prefer-array-iterable-methods'} from './prefer-array-iterable-methods.js';
155
187
  export {default as 'prefer-array-last-methods'} from './prefer-array-last-methods.js';
156
188
  export {default as 'prefer-array-slice'} from './prefer-array-slice.js';
157
189
  export {default as 'prefer-array-some'} from './prefer-array-some.js';
@@ -159,9 +191,11 @@ export {default as 'prefer-at'} from './prefer-at.js';
159
191
  export {default as 'prefer-await'} from './prefer-await.js';
160
192
  export {default as 'prefer-bigint-literals'} from './prefer-bigint-literals.js';
161
193
  export {default as 'prefer-blob-reading-methods'} from './prefer-blob-reading-methods.js';
194
+ export {default as 'prefer-boolean-return'} from './prefer-boolean-return.js';
162
195
  export {default as 'prefer-class-fields'} from './prefer-class-fields.js';
163
196
  export {default as 'prefer-classlist-toggle'} from './prefer-classlist-toggle.js';
164
197
  export {default as 'prefer-code-point'} from './prefer-code-point.js';
198
+ export {default as 'prefer-continue'} from './prefer-continue.js';
165
199
  export {default as 'prefer-date-now'} from './prefer-date-now.js';
166
200
  export {default as 'prefer-default-parameters'} from './prefer-default-parameters.js';
167
201
  export {default as 'prefer-direct-iteration'} from './prefer-direct-iteration.js';
@@ -169,15 +203,19 @@ export {default as 'prefer-dispose'} from './prefer-dispose.js';
169
203
  export {default as 'prefer-dom-node-append'} from './prefer-dom-node-append.js';
170
204
  export {default as 'prefer-dom-node-html-methods'} from './prefer-dom-node-html-methods.js';
171
205
  export {default as 'prefer-dom-node-remove'} from './prefer-dom-node-remove.js';
206
+ export {default as 'prefer-dom-node-replace-children'} from './prefer-dom-node-replace-children.js';
172
207
  export {default as 'prefer-dom-node-text-content'} from './prefer-dom-node-text-content.js';
173
208
  export {default as 'prefer-early-return'} from './prefer-early-return.js';
174
209
  export {default as 'prefer-else-if'} from './prefer-else-if.js';
210
+ export {default as 'prefer-error-is-error'} from './prefer-error-is-error.js';
175
211
  export {default as 'prefer-event-target'} from './prefer-event-target.js';
176
212
  export {default as 'prefer-export-from'} from './prefer-export-from.js';
213
+ export {default as 'prefer-flat-math-min-max'} from './prefer-flat-math-min-max.js';
177
214
  export {default as 'prefer-get-or-insert-computed'} from './prefer-get-or-insert-computed.js';
178
215
  export {default as 'prefer-global-number-constants'} from './prefer-global-number-constants.js';
179
216
  export {default as 'prefer-global-this'} from './prefer-global-this.js';
180
217
  export {default as 'prefer-has-check'} from './prefer-has-check.js';
218
+ export {default as 'prefer-hoisting-branch-code'} from './prefer-hoisting-branch-code.js';
181
219
  export {default as 'prefer-https'} from './prefer-https.js';
182
220
  export {default as 'prefer-identifier-import-export-specifiers'} from './prefer-identifier-import-export-specifiers.js';
183
221
  export {default as 'prefer-import-meta-properties'} from './prefer-import-meta-properties.js';
@@ -192,6 +230,7 @@ export {default as 'prefer-location-assign'} from './prefer-location-assign.js';
192
230
  export {default as 'prefer-logical-operator-over-ternary'} from './prefer-logical-operator-over-ternary.js';
193
231
  export {default as 'prefer-map-from-entries'} from './prefer-map-from-entries.js';
194
232
  export {default as 'prefer-math-abs'} from './prefer-math-abs.js';
233
+ export {default as 'prefer-math-constants'} from './prefer-math-constants.js';
195
234
  export {default as 'prefer-math-min-max'} from './prefer-math-min-max.js';
196
235
  export {default as 'prefer-math-trunc'} from './prefer-math-trunc.js';
197
236
  export {default as 'prefer-minimal-ternary'} from './prefer-minimal-ternary.js';
@@ -208,17 +247,22 @@ export {default as 'prefer-object-define-properties'} from './prefer-object-defi
208
247
  export {default as 'prefer-object-destructuring-defaults'} from './prefer-object-destructuring-defaults.js';
209
248
  export {default as 'prefer-object-from-entries'} from './prefer-object-from-entries.js';
210
249
  export {default as 'prefer-object-iterable-methods'} from './prefer-object-iterable-methods.js';
250
+ export {default as 'prefer-observer-apis'} from './prefer-observer-apis.js';
211
251
  export {default as 'prefer-optional-catch-binding'} from './prefer-optional-catch-binding.js';
212
252
  export {default as 'prefer-path2d'} from './prefer-path2d.js';
213
253
  export {default as 'prefer-private-class-fields'} from './prefer-private-class-fields.js';
254
+ export {default as 'prefer-promise-try'} from './prefer-promise-try.js';
255
+ export {default as 'prefer-promise-with-resolvers'} from './prefer-promise-with-resolvers.js';
214
256
  export {default as 'prefer-prototype-methods'} from './prefer-prototype-methods.js';
215
257
  export {default as 'prefer-query-selector'} from './prefer-query-selector.js';
216
258
  export {default as 'prefer-queue-microtask'} from './prefer-queue-microtask.js';
217
259
  export {default as 'prefer-reflect-apply'} from './prefer-reflect-apply.js';
260
+ export {default as 'prefer-regexp-escape'} from './prefer-regexp-escape.js';
218
261
  export {default as 'prefer-regexp-test'} from './prefer-regexp-test.js';
219
262
  export {default as 'prefer-response-static-json'} from './prefer-response-static-json.js';
220
263
  export {default as 'prefer-scoped-selector'} from './prefer-scoped-selector.js';
221
264
  export {default as 'prefer-set-has'} from './prefer-set-has.js';
265
+ export {default as 'prefer-set-methods'} from './prefer-set-methods.js';
222
266
  export {default as 'prefer-set-size'} from './prefer-set-size.js';
223
267
  export {default as 'prefer-short-arrow-method'} from './prefer-short-arrow-method.js';
224
268
  export {default as 'prefer-simple-condition-first'} from './prefer-simple-condition-first.js';
@@ -226,6 +270,7 @@ export {default as 'prefer-simple-sort-comparator'} from './prefer-simple-sort-c
226
270
  export {default as 'prefer-single-array-predicate'} from './prefer-single-array-predicate.js';
227
271
  export {default as 'prefer-single-call'} from './prefer-single-call.js';
228
272
  export {default as 'prefer-single-object-destructuring'} from './prefer-single-object-destructuring.js';
273
+ export {default as 'prefer-single-replace'} from './prefer-single-replace.js';
229
274
  export {default as 'prefer-smaller-scope'} from './prefer-smaller-scope.js';
230
275
  export {default as 'prefer-split-limit'} from './prefer-split-limit.js';
231
276
  export {default as 'prefer-spread'} from './prefer-spread.js';
@@ -241,13 +286,17 @@ export {default as 'prefer-structured-clone'} from './prefer-structured-clone.js
241
286
  export {default as 'prefer-switch'} from './prefer-switch.js';
242
287
  export {default as 'prefer-temporal'} from './prefer-temporal.js';
243
288
  export {default as 'prefer-ternary'} from './prefer-ternary.js';
289
+ export {default as 'prefer-toggle-attribute'} from './prefer-toggle-attribute.js';
244
290
  export {default as 'prefer-top-level-await'} from './prefer-top-level-await.js';
245
291
  export {default as 'prefer-type-error'} from './prefer-type-error.js';
246
292
  export {default as 'prefer-type-literal-last'} from './prefer-type-literal-last.js';
247
293
  export {default as 'prefer-uint8array-base64'} from './prefer-uint8array-base64.js';
294
+ export {default as 'prefer-unary-minus'} from './prefer-unary-minus.js';
248
295
  export {default as 'prefer-unicode-code-point-escapes'} from './prefer-unicode-code-point-escapes.js';
296
+ export {default as 'prefer-url-can-parse'} from './prefer-url-can-parse.js';
249
297
  export {default as 'prefer-url-href'} from './prefer-url-href.js';
250
- export {default as 'prevent-abbreviations'} from './prevent-abbreviations.js';
298
+ export {default as 'prefer-url-search-parameters'} from './prefer-url-search-parameters.js';
299
+ export {default as 'prefer-while-loop-condition'} from './prefer-while-loop-condition.js';
251
300
  export {default as 'relative-url-style'} from './relative-url-style.js';
252
301
  export {default as 'require-array-join-separator'} from './require-array-join-separator.js';
253
302
  export {default as 'require-array-sort-compare'} from './require-array-sort-compare.js';
@@ -3,12 +3,19 @@ import {getBuiltinRule} from './utils/index.js';
3
3
  const baseRule = getBuiltinRule('logical-assignment-operators');
4
4
 
5
5
  const MESSAGE_ID_IF = 'if';
6
+ const MESSAGE_ID_IF_NULLISH = 'ifNullish';
6
7
  const MESSAGE_ID_CONVERT_IF = 'convertIf';
7
8
  const LOGICAL_OR_ASSIGNMENT_OPERATOR = '||=';
8
9
  const LOGICAL_OR_OPERATOR = '||';
9
10
  const NULLISH_COALESCING_ASSIGNMENT_OPERATOR = '??=';
10
11
  const NULLISH_COALESCING_OPERATOR = '??';
11
12
 
13
+ const messages = {
14
+ ...baseRule.meta.messages,
15
+ // A falsy `if` assignment is offered as both `||=` and `??=`, so name both operators. The phrasing matches the base rule's `if` message, which renders the operator without backticks.
16
+ [MESSAGE_ID_IF_NULLISH]: '\'if\' statement can be replaced with a logical operator assignment with operator ||= or ??=.',
17
+ };
18
+
12
19
  const getFix = problem => problem.fix ?? problem.suggest?.[0]?.fix;
13
20
 
14
21
  const shouldAddNullishSuggestion = problem =>
@@ -46,14 +53,20 @@ function getProblem(problem, sourceCode) {
46
53
  return problem;
47
54
  }
48
55
 
56
+ // Both `||=` and `??=` apply here, so the message names both operators.
57
+ const problemWithMessage = {
58
+ ...withoutFixes(problem),
59
+ messageId: MESSAGE_ID_IF_NULLISH,
60
+ };
61
+
49
62
  if (sourceCode.getCommentsInside(problem.node).length > 0) {
50
- return withoutFixes(problem);
63
+ return problemWithMessage;
51
64
  }
52
65
 
53
66
  const fix = getFix(problem);
54
67
 
55
68
  return {
56
- ...withoutFixes(problem),
69
+ ...problemWithMessage,
57
70
  suggest: [
58
71
  {
59
72
  messageId: MESSAGE_ID_CONVERT_IF,
@@ -100,9 +113,9 @@ const config = {
100
113
  hasSuggestions: baseRule.meta.hasSuggestions,
101
114
  schema: baseRule.meta.schema,
102
115
  defaultOptions: [
103
- baseRule.meta.defaultOptions[0],
116
+ baseRule.meta.defaultOptions?.[0],
104
117
  ],
105
- messages: baseRule.meta.messages,
118
+ messages,
106
119
  languages: [
107
120
  'js/js',
108
121
  ],
@@ -10,7 +10,7 @@ import {
10
10
  lowerFirst,
11
11
  isVirtualFilename,
12
12
  } from './utils/index.js';
13
- import {defaultReplacements, defaultAllowList, defaultIgnore} from './shared/abbreviations.js';
13
+ import {defaultReplacements, defaultAllowList, defaultIgnore} from './shared/name-replacements.js';
14
14
  import {
15
15
  isClassVariable,
16
16
  shouldCheckDefaultOrNamespaceImportName,
@@ -465,13 +465,15 @@ const create = context => {
465
465
  return;
466
466
  }
467
467
 
468
- const identifierReplacements = getNameReplacements(node.name, options);
469
-
470
- if (identifierReplacements.total === 0) {
468
+ // The cheap AST check filters out non-property identifiers before the more
469
+ // expensive name analysis in `getNameReplacements`.
470
+ if (!shouldReportIdentifierAsProperty(node)) {
471
471
  return;
472
472
  }
473
473
 
474
- if (!shouldReportIdentifierAsProperty(node)) {
474
+ const identifierReplacements = getNameReplacements(node.name, options);
475
+
476
+ if (identifierReplacements.total === 0) {
475
477
  return;
476
478
  }
477
479
 
@@ -573,8 +575,8 @@ const schema = {
573
575
  description: 'Whether to extend the default replacements.',
574
576
  },
575
577
  replacements: {
576
- $ref: '#/definitions/abbreviations',
577
- description: 'Custom abbreviation replacements.',
578
+ $ref: '#/definitions/nameReplacements',
579
+ description: 'Custom name replacements.',
578
580
  },
579
581
  extendDefaultAllowList: {
580
582
  type: 'boolean',
@@ -593,7 +595,7 @@ const schema = {
593
595
  },
594
596
  ],
595
597
  definitions: {
596
- abbreviations: {
598
+ nameReplacements: {
597
599
  type: 'object',
598
600
  additionalProperties: {
599
601
  $ref: '#/definitions/replacements',
@@ -626,7 +628,7 @@ const config = {
626
628
  meta: {
627
629
  type: 'suggestion',
628
630
  docs: {
629
- description: 'Prevent abbreviations.',
631
+ description: 'Enforce replacements for variable, property, and filenames.',
630
632
  recommended: true,
631
633
  },
632
634
  fixable: 'code',
@@ -1,5 +1,6 @@
1
1
  import {GlobalReferenceTracker} from './utils/global-reference-tracker.js';
2
2
  import * as builtins from './utils/builtins.js';
3
+ import {hasOptionalChainElement} from './utils/index.js';
3
4
  import {
4
5
  switchCallExpressionToNewExpression,
5
6
  switchNewExpressionToCallExpression,
@@ -12,13 +13,23 @@ const MESSAGE_ID_SUGGESTION_DATE = 'suggestion-date';
12
13
  const messages = {
13
14
  enforce: 'Use `new {{name}}()` instead of `{{name}}()`.',
14
15
  disallow: 'Use `{{name}}()` instead of `new {{name}}()`.',
16
+ disallowCallOrNew: '`{{name}}` is not a function or constructor.',
15
17
  [MESSAGE_ID_ERROR_DATE]: 'Use `String(new Date())` instead of `Date()`.',
16
18
  [MESSAGE_ID_SUGGESTION_DATE]: 'Switch to `String(new Date())`.',
17
19
  };
18
20
 
21
+ const getName = reference => reference.path.join('.');
22
+ const hasOptionalChain = node => node.optional || hasOptionalChainElement(node.callee);
23
+
19
24
  function enforceNewExpression(reference, context) {
20
- const {node, path} = reference;
21
- const [name] = path;
25
+ const {node} = reference;
26
+
27
+ // An optional chain (`Array?.()` or `Intl?.DateTimeFormat()`) can't be rewritten to a `new` expression, which can't be optional.
28
+ if (hasOptionalChain(node)) {
29
+ return;
30
+ }
31
+
32
+ const name = getName(reference);
22
33
 
23
34
  if (name === 'Object') {
24
35
  const {parent} = node;
@@ -65,8 +76,8 @@ function enforceNewExpression(reference, context) {
65
76
  }
66
77
 
67
78
  function enforceCallExpression(reference, context) {
68
- const {node, path} = reference;
69
- const [name] = path;
79
+ const {node} = reference;
80
+ const name = getName(reference);
70
81
 
71
82
  const problem = {
72
83
  node,
@@ -81,6 +92,17 @@ function enforceCallExpression(reference, context) {
81
92
  return problem;
82
93
  }
83
94
 
95
+ function disallowCallOrNewExpression(reference) {
96
+ const {node} = reference;
97
+ const name = getName(reference);
98
+
99
+ return {
100
+ node,
101
+ messageId: 'disallowCallOrNew',
102
+ data: {name},
103
+ };
104
+ }
105
+
84
106
  const newExpressionTracker = new GlobalReferenceTracker({
85
107
  objects: builtins.disallowNew,
86
108
  type: GlobalReferenceTracker.CONSTRUCT,
@@ -91,11 +113,23 @@ const callExpressionTracker = new GlobalReferenceTracker({
91
113
  type: GlobalReferenceTracker.CALL,
92
114
  handle: enforceNewExpression,
93
115
  });
116
+ const callExpressionDisallowTracker = new GlobalReferenceTracker({
117
+ objects: builtins.disallowCallOrNew,
118
+ type: GlobalReferenceTracker.CALL,
119
+ handle: disallowCallOrNewExpression,
120
+ });
121
+ const newExpressionDisallowTracker = new GlobalReferenceTracker({
122
+ objects: builtins.disallowCallOrNew,
123
+ type: GlobalReferenceTracker.CONSTRUCT,
124
+ handle: disallowCallOrNewExpression,
125
+ });
94
126
 
95
127
  /** @param {import('eslint').Rule.RuleContext} context */
96
128
  const create = context => {
97
129
  newExpressionTracker.listen({context});
98
130
  callExpressionTracker.listen({context});
131
+ callExpressionDisallowTracker.listen({context});
132
+ newExpressionDisallowTracker.listen({context});
99
133
  };
100
134
 
101
135
  /** @type {import('eslint').Rule.RuleModule} */
@@ -104,7 +138,7 @@ const config = {
104
138
  meta: {
105
139
  type: 'suggestion',
106
140
  docs: {
107
- description: 'Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`.',
141
+ description: 'Enforce correct use of `new` for builtin constructors.',
108
142
  recommended: 'unopinionated',
109
143
  },
110
144
  fixable: 'code',
@@ -101,6 +101,13 @@ const isPropertyWrite = (thisExpression, property) => {
101
101
  || (parent.type === 'UpdateExpression' && parent.argument === memberExpression)
102
102
  // `[this.foo] = …`
103
103
  || (parent.type === 'ArrayPattern' && parent.elements.includes(memberExpression))
104
+ // `[...this.foo] = …`
105
+ || (parent.type === 'RestElement' && parent.argument === memberExpression)
106
+ // `for (this.foo of …) {}` / `for (this.foo in …) {}`
107
+ || (
108
+ (parent.type === 'ForOfStatement' || parent.type === 'ForInStatement')
109
+ && parent.left === memberExpression
110
+ )
104
111
  // `({property: this.foo} = …)`
105
112
  || (
106
113
  parent.type === 'Property'
@@ -0,0 +1,97 @@
1
+ import {isStringLiteral, isBooleanLiteral, isFunction} from './ast/index.js';
2
+
3
+ /**
4
+ @import {TSESTree as ESTree} from '@typescript-eslint/types';
5
+ @import * as ESLint from 'eslint';
6
+ */
7
+
8
+ const MESSAGE_ID_ERROR = 'no-accidental-bitwise-operator/error';
9
+ const MESSAGE_ID_SUGGESTION = 'no-accidental-bitwise-operator/suggestion';
10
+ const messages = {
11
+ [MESSAGE_ID_ERROR]: 'Unexpected bitwise operator `{{bitwiseOperator}}`. Did you mean the logical operator `{{logicalOperator}}`?',
12
+ [MESSAGE_ID_SUGGESTION]: 'Replace `{{bitwiseOperator}}` with `{{logicalOperator}}`.',
13
+ };
14
+
15
+ const logicalOperators = new Map([
16
+ ['&', '&&'],
17
+ ['|', '||'],
18
+ ['|=', '||='],
19
+ ]);
20
+
21
+ // Value forms that make no sense as a bitwise operand, so the operator is almost
22
+ // certainly a mistyped logical operator. Intentionally excludes `null`, numeric
23
+ // literals, identifiers, and arithmetic expressions, which may be valid numbers.
24
+ const isDefinitelyNonNumeric = node =>
25
+ node.type === 'ObjectExpression'
26
+ || node.type === 'ArrayExpression'
27
+ || node.type === 'ClassExpression'
28
+ || node.type === 'TemplateLiteral'
29
+ || isFunction(node)
30
+ || isStringLiteral(node)
31
+ || isBooleanLiteral(node);
32
+
33
+ // `obj & obj.prop` is a mistyped short-circuit guard (`obj && obj.prop`).
34
+ const isShortCircuitGuard = node =>
35
+ node.operator === '&'
36
+ && node.left.type === 'Identifier'
37
+ && node.right.type === 'MemberExpression'
38
+ && node.right.object.type === 'Identifier'
39
+ && node.right.object.name === node.left.name;
40
+
41
+ // Either a mistyped short-circuit guard (`&`) or a mistyped logical fallback
42
+ // (`options | {}`, `input |= ''`), where the operator was almost certainly meant
43
+ // to be the logical counterpart.
44
+ const isSuspiciousBitwise = node =>
45
+ isShortCircuitGuard(node)
46
+ || ((node.operator === '|' || node.operator === '|=') && isDefinitelyNonNumeric(node.right));
47
+
48
+ /** @param {ESLint.Rule.RuleContext} context */
49
+ const create = context => {
50
+ const {sourceCode} = context;
51
+
52
+ context.on(['BinaryExpression', 'AssignmentExpression'], node => {
53
+ if (!isSuspiciousBitwise(node)) {
54
+ return;
55
+ }
56
+
57
+ const {operator} = node;
58
+ const logicalOperator = logicalOperators.get(operator);
59
+ const operatorToken = sourceCode.getTokenAfter(
60
+ node.left,
61
+ token => token.type === 'Punctuator' && token.value === operator,
62
+ );
63
+
64
+ return {
65
+ node: operatorToken,
66
+ messageId: MESSAGE_ID_ERROR,
67
+ data: {bitwiseOperator: operator, logicalOperator},
68
+ suggest: [
69
+ {
70
+ messageId: MESSAGE_ID_SUGGESTION,
71
+ data: {bitwiseOperator: operator, logicalOperator},
72
+ /** @param {ESLint.Rule.RuleFixer} fixer */
73
+ fix: fixer => fixer.replaceText(operatorToken, logicalOperator),
74
+ },
75
+ ],
76
+ };
77
+ });
78
+ };
79
+
80
+ /** @type {ESLint.Rule.RuleModule} */
81
+ const config = {
82
+ create,
83
+ meta: {
84
+ type: 'problem',
85
+ docs: {
86
+ description: 'Disallow bitwise operators where a logical operator was likely intended.',
87
+ recommended: 'unopinionated',
88
+ },
89
+ hasSuggestions: true,
90
+ messages,
91
+ languages: [
92
+ 'js/js',
93
+ ],
94
+ },
95
+ };
96
+
97
+ export default config;
@@ -151,13 +151,7 @@ const iteratorMethods = new Map([
151
151
 
152
152
  return shouldIgnoreCallExpression?.(callExpression) ?? false;
153
153
  },
154
- shouldIgnoreCallback(callback) {
155
- if (callback.type === 'Identifier' && ignore.includes(callback.name)) {
156
- return true;
157
- }
158
-
159
- return false;
160
- },
154
+ shouldIgnoreCallback: callback => Boolean(callback.type === 'Identifier' && ignore.includes(callback.name)),
161
155
  }]));
162
156
 
163
157
  const defaultIgnoredCallees = [
@@ -0,0 +1,45 @@
1
+ import {getArrayConcatInLoop} from './shared/array-concat-in-loop.js';
2
+
3
+ /**
4
+ @import * as ESLint from 'eslint';
5
+ */
6
+
7
+ const MESSAGE_ID = 'no-array-concat-in-loop';
8
+ const messages = {
9
+ [MESSAGE_ID]: 'Do not use `Array#concat()` to accumulate an array in a loop.',
10
+ };
11
+
12
+ /** @param {ESLint.Rule.RuleContext} context */
13
+ const create = context => {
14
+ context.on('AssignmentExpression', node => {
15
+ const problem = getArrayConcatInLoop(node, context);
16
+
17
+ if (!problem) {
18
+ return;
19
+ }
20
+
21
+ return {
22
+ node: problem.property,
23
+ messageId: MESSAGE_ID,
24
+ };
25
+ });
26
+ };
27
+
28
+ /** @type {ESLint.Rule.RuleModule} */
29
+ const config = {
30
+ create,
31
+ meta: {
32
+ type: 'suggestion',
33
+ docs: {
34
+ description: 'Disallow array accumulation with `Array#concat()` in loops.',
35
+ recommended: true,
36
+ },
37
+ schema: [],
38
+ messages,
39
+ languages: [
40
+ 'js/js',
41
+ ],
42
+ },
43
+ };
44
+
45
+ export default config;