eslint 8.43.0 → 8.45.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
@@ -117,7 +117,7 @@ Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [confi
117
117
 
118
118
  ### What ECMAScript versions does ESLint support?
119
119
 
120
- ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2019, 2020, 2021 and 2022. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/latest/use/configure).
120
+ ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, and 2023. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/latest/use/configure).
121
121
 
122
122
  ### What about experimental features?
123
123
 
@@ -284,7 +284,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
284
284
  <p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
285
285
  <p><a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
286
286
  <p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
287
- <p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
287
+ <p><a href="https://iboysoft.com/"><img src="https://images.opencollective.com/iboysoft-software/7f9d60e/avatar.png" alt="iBoysoft" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465?v=4" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
288
288
  <!--sponsorsend-->
289
289
 
290
290
  ## Technology Sponsors
package/conf/globals.js CHANGED
@@ -128,6 +128,10 @@ const es2023 = {
128
128
  ...es2022
129
129
  };
130
130
 
131
+ const es2024 = {
132
+ ...es2023
133
+ };
134
+
131
135
 
132
136
  //-----------------------------------------------------------------------------
133
137
  // Exports
@@ -145,5 +149,6 @@ module.exports = {
145
149
  es2020,
146
150
  es2021,
147
151
  es2022,
148
- es2023
152
+ es2023,
153
+ es2024
149
154
  };
@@ -158,7 +158,17 @@ function validateFixTypes(fixTypes) {
158
158
  * @private
159
159
  */
160
160
  function calculateStatsPerFile(messages) {
161
- return messages.reduce((stat, message) => {
161
+ const stat = {
162
+ errorCount: 0,
163
+ fatalErrorCount: 0,
164
+ warningCount: 0,
165
+ fixableErrorCount: 0,
166
+ fixableWarningCount: 0
167
+ };
168
+
169
+ for (let i = 0; i < messages.length; i++) {
170
+ const message = messages[i];
171
+
162
172
  if (message.fatal || message.severity === 2) {
163
173
  stat.errorCount++;
164
174
  if (message.fatal) {
@@ -173,14 +183,8 @@ function calculateStatsPerFile(messages) {
173
183
  stat.fixableWarningCount++;
174
184
  }
175
185
  }
176
- return stat;
177
- }, {
178
- errorCount: 0,
179
- fatalErrorCount: 0,
180
- warningCount: 0,
181
- fixableErrorCount: 0,
182
- fixableWarningCount: 0
183
- });
186
+ }
187
+ return stat;
184
188
  }
185
189
 
186
190
  /**
@@ -190,20 +194,25 @@ function calculateStatsPerFile(messages) {
190
194
  * @private
191
195
  */
192
196
  function calculateStatsPerRun(results) {
193
- return results.reduce((stat, result) => {
194
- stat.errorCount += result.errorCount;
195
- stat.fatalErrorCount += result.fatalErrorCount;
196
- stat.warningCount += result.warningCount;
197
- stat.fixableErrorCount += result.fixableErrorCount;
198
- stat.fixableWarningCount += result.fixableWarningCount;
199
- return stat;
200
- }, {
197
+ const stat = {
201
198
  errorCount: 0,
202
199
  fatalErrorCount: 0,
203
200
  warningCount: 0,
204
201
  fixableErrorCount: 0,
205
202
  fixableWarningCount: 0
206
- });
203
+ };
204
+
205
+ for (let i = 0; i < results.length; i++) {
206
+ const result = results[i];
207
+
208
+ stat.errorCount += result.errorCount;
209
+ stat.fatalErrorCount += result.fatalErrorCount;
210
+ stat.warningCount += result.warningCount;
211
+ stat.fixableErrorCount += result.fixableErrorCount;
212
+ stat.fixableWarningCount += result.fixableWarningCount;
213
+ }
214
+
215
+ return stat;
207
216
  }
208
217
 
209
218
  /**
@@ -103,7 +103,17 @@ const importedConfigFileModificationTime = new Map();
103
103
  * @private
104
104
  */
105
105
  function calculateStatsPerFile(messages) {
106
- return messages.reduce((stat, message) => {
106
+ const stat = {
107
+ errorCount: 0,
108
+ fatalErrorCount: 0,
109
+ warningCount: 0,
110
+ fixableErrorCount: 0,
111
+ fixableWarningCount: 0
112
+ };
113
+
114
+ for (let i = 0; i < messages.length; i++) {
115
+ const message = messages[i];
116
+
107
117
  if (message.fatal || message.severity === 2) {
108
118
  stat.errorCount++;
109
119
  if (message.fatal) {
@@ -118,37 +128,8 @@ function calculateStatsPerFile(messages) {
118
128
  stat.fixableWarningCount++;
119
129
  }
120
130
  }
121
- return stat;
122
- }, {
123
- errorCount: 0,
124
- fatalErrorCount: 0,
125
- warningCount: 0,
126
- fixableErrorCount: 0,
127
- fixableWarningCount: 0
128
- });
129
- }
130
-
131
- /**
132
- * It will calculate the error and warning count for collection of results from all files
133
- * @param {LintResult[]} results Collection of messages from all the files
134
- * @returns {Object} Contains the stats
135
- * @private
136
- */
137
- function calculateStatsPerRun(results) {
138
- return results.reduce((stat, result) => {
139
- stat.errorCount += result.errorCount;
140
- stat.fatalErrorCount += result.fatalErrorCount;
141
- stat.warningCount += result.warningCount;
142
- stat.fixableErrorCount += result.fixableErrorCount;
143
- stat.fixableWarningCount += result.fixableWarningCount;
144
- return stat;
145
- }, {
146
- errorCount: 0,
147
- fatalErrorCount: 0,
148
- warningCount: 0,
149
- fixableErrorCount: 0,
150
- fixableWarningCount: 0
151
- });
131
+ }
132
+ return stat;
152
133
  }
153
134
 
154
135
  /**
@@ -550,43 +531,6 @@ function shouldMessageBeFixed(message, config, fixTypes) {
550
531
  return Boolean(rule && rule.meta && fixTypes.has(rule.meta.type));
551
532
  }
552
533
 
553
- /**
554
- * Collect used deprecated rules.
555
- * @param {Array<FlatConfig>} configs The configs to evaluate.
556
- * @returns {IterableIterator<DeprecatedRuleInfo>} Used deprecated rules.
557
- */
558
- function *iterateRuleDeprecationWarnings(configs) {
559
- const processedRuleIds = new Set();
560
-
561
- for (const config of configs) {
562
- for (const [ruleId, ruleConfig] of Object.entries(config.rules)) {
563
-
564
- // Skip if it was processed.
565
- if (processedRuleIds.has(ruleId)) {
566
- continue;
567
- }
568
- processedRuleIds.add(ruleId);
569
-
570
- // Skip if it's not used.
571
- if (!getRuleSeverity(ruleConfig)) {
572
- continue;
573
- }
574
- const rule = getRuleFromConfig(ruleId, config);
575
-
576
- // Skip if it's not deprecated.
577
- if (!(rule && rule.meta && rule.meta.deprecated)) {
578
- continue;
579
- }
580
-
581
- // This rule was used and deprecated.
582
- yield {
583
- ruleId,
584
- replacedBy: rule.meta.replacedBy || []
585
- };
586
- }
587
- }
588
- }
589
-
590
534
  /**
591
535
  * Creates an error to be thrown when an array of results passed to `getRulesMetaForResults` was not created by the current engine.
592
536
  * @returns {TypeError} An error object.
@@ -632,7 +576,6 @@ class FlatESLint {
632
576
  cacheFilePath,
633
577
  lintResultCache,
634
578
  defaultConfigs,
635
- defaultIgnores: () => false,
636
579
  configs: null
637
580
  });
638
581
 
@@ -811,7 +754,6 @@ class FlatESLint {
811
754
  errorOnUnmatchedPattern
812
755
  } = eslintOptions;
813
756
  const startTime = Date.now();
814
- const usedConfigs = [];
815
757
  const fixTypesSet = fixTypes ? new Set(fixTypes) : null;
816
758
 
817
759
  // Delete cache file; should this be done here?
@@ -869,15 +811,6 @@ class FlatESLint {
869
811
  return void 0;
870
812
  }
871
813
 
872
- /*
873
- * Store used configs for:
874
- * - this method uses to collect used deprecated rules.
875
- * - `--fix-type` option uses to get the loaded rule's meta data.
876
- */
877
- if (!usedConfigs.includes(config)) {
878
- usedConfigs.push(config);
879
- }
880
-
881
814
  // Skip if there is cached result.
882
815
  if (lintResultCache) {
883
816
  const cachedResult =
@@ -946,22 +879,10 @@ class FlatESLint {
946
879
  lintResultCache.reconcile();
947
880
  }
948
881
 
949
- let usedDeprecatedRules;
950
882
  const finalResults = results.filter(result => !!result);
951
883
 
952
884
  return processLintReport(this, {
953
- results: finalResults,
954
- ...calculateStatsPerRun(finalResults),
955
-
956
- // Initialize it lazily because CLI and `ESLint` API don't use it.
957
- get usedDeprecatedRules() {
958
- if (!usedDeprecatedRules) {
959
- usedDeprecatedRules = Array.from(
960
- iterateRuleDeprecationWarnings(usedConfigs)
961
- );
962
- }
963
- return usedDeprecatedRules;
964
- }
885
+ results: finalResults
965
886
  });
966
887
  }
967
888
 
@@ -1023,7 +944,6 @@ class FlatESLint {
1023
944
  const results = [];
1024
945
  const startTime = Date.now();
1025
946
  const resolvedFilename = path.resolve(cwd, filePath || "__placeholder__.js");
1026
- let config;
1027
947
 
1028
948
  // Clear the last used config arrays.
1029
949
  if (resolvedFilename && await this.isPathIgnored(resolvedFilename)) {
@@ -1032,9 +952,6 @@ class FlatESLint {
1032
952
  }
1033
953
  } else {
1034
954
 
1035
- // TODO: Needed?
1036
- config = configs.getConfig(resolvedFilename);
1037
-
1038
955
  // Do lint.
1039
956
  results.push(verifyText({
1040
957
  text: code,
@@ -1049,21 +966,9 @@ class FlatESLint {
1049
966
  }
1050
967
 
1051
968
  debug(`Linting complete in: ${Date.now() - startTime}ms`);
1052
- let usedDeprecatedRules;
1053
969
 
1054
970
  return processLintReport(this, {
1055
- results,
1056
- ...calculateStatsPerRun(results),
1057
-
1058
- // Initialize it lazily because CLI and `ESLint` API don't use it.
1059
- get usedDeprecatedRules() {
1060
- if (!usedDeprecatedRules) {
1061
- usedDeprecatedRules = Array.from(
1062
- iterateRuleDeprecationWarnings(config)
1063
- );
1064
- }
1065
- return usedDeprecatedRules;
1066
- }
971
+ results
1067
972
  });
1068
973
 
1069
974
  }
@@ -100,6 +100,22 @@ function normalizeReportLoc(descriptor) {
100
100
  return descriptor.node.loc;
101
101
  }
102
102
 
103
+ /**
104
+ * Clones the given fix object.
105
+ * @param {Fix|null} fix The fix to clone.
106
+ * @returns {Fix|null} Deep cloned fix object or `null` if `null` or `undefined` was passed in.
107
+ */
108
+ function cloneFix(fix) {
109
+ if (!fix) {
110
+ return null;
111
+ }
112
+
113
+ return {
114
+ range: [fix.range[0], fix.range[1]],
115
+ text: fix.text
116
+ };
117
+ }
118
+
103
119
  /**
104
120
  * Check that a fix has a valid range.
105
121
  * @param {Fix|null} fix The fix to validate.
@@ -137,7 +153,7 @@ function mergeFixes(fixes, sourceCode) {
137
153
  return null;
138
154
  }
139
155
  if (fixes.length === 1) {
140
- return fixes[0];
156
+ return cloneFix(fixes[0]);
141
157
  }
142
158
 
143
159
  fixes.sort(compareFixesByRange);
@@ -183,7 +199,7 @@ function normalizeFixes(descriptor, sourceCode) {
183
199
  }
184
200
 
185
201
  assertValidFix(fix);
186
- return fix;
202
+ return cloneFix(fix);
187
203
  }
188
204
 
189
205
  /**
@@ -33,7 +33,7 @@ const { ConfigArraySymbol } = require("@humanwhocodes/config-array");
33
33
  /** @typedef {import("../shared/types").Parser} Parser */
34
34
  /** @typedef {import("../shared/types").LanguageOptions} LanguageOptions */
35
35
 
36
- /* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
36
+
37
37
  /**
38
38
  * A test case that is expected to pass lint.
39
39
  * @typedef {Object} ValidTestCase
@@ -72,7 +72,6 @@ const { ConfigArraySymbol } = require("@humanwhocodes/config-array");
72
72
  * @property {number} [endLine] The 1-based line number of the reported end location.
73
73
  * @property {number} [endColumn] The 1-based column number of the reported end location.
74
74
  */
75
- /* eslint-enable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
76
75
 
77
76
  //------------------------------------------------------------------------------
78
77
  // Private Members
@@ -63,7 +63,7 @@ const { SourceCode } = require("../source-code");
63
63
 
64
64
  /** @typedef {import("../shared/types").Parser} Parser */
65
65
 
66
- /* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
66
+
67
67
  /**
68
68
  * A test case that is expected to pass lint.
69
69
  * @typedef {Object} ValidTestCase
@@ -108,7 +108,6 @@ const { SourceCode } = require("../source-code");
108
108
  * @property {number} [endLine] The 1-based line number of the reported end location.
109
109
  * @property {number} [endColumn] The 1-based column number of the reported end location.
110
110
  */
111
- /* eslint-enable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
112
111
 
113
112
  //------------------------------------------------------------------------------
114
113
  // Private Members
@@ -223,43 +223,6 @@ module.exports = {
223
223
  }
224
224
  }
225
225
 
226
- /**
227
- * Creates a new `AccessorData` object for the given getter or setter node.
228
- * @param {ASTNode} node A getter or setter node.
229
- * @returns {AccessorData} New `AccessorData` object that contains the given node.
230
- * @private
231
- */
232
- function createAccessorData(node) {
233
- const name = astUtils.getStaticPropertyName(node);
234
- const key = (name !== null) ? name : sourceCode.getTokens(node.key);
235
-
236
- return {
237
- key,
238
- getters: node.kind === "get" ? [node] : [],
239
- setters: node.kind === "set" ? [node] : []
240
- };
241
- }
242
-
243
- /**
244
- * Merges the given `AccessorData` object into the given accessors list.
245
- * @param {AccessorData[]} accessors The list to merge into.
246
- * @param {AccessorData} accessorData The object to merge.
247
- * @returns {AccessorData[]} The same instance with the merged object.
248
- * @private
249
- */
250
- function mergeAccessorData(accessors, accessorData) {
251
- const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
252
-
253
- if (equalKeyElement) {
254
- equalKeyElement.getters.push(...accessorData.getters);
255
- equalKeyElement.setters.push(...accessorData.setters);
256
- } else {
257
- accessors.push(accessorData);
258
- }
259
-
260
- return accessors;
261
- }
262
-
263
226
  /**
264
227
  * Checks accessor pairs in the given list of nodes.
265
228
  * @param {ASTNode[]} nodes The list to check.
@@ -267,10 +230,39 @@ module.exports = {
267
230
  * @private
268
231
  */
269
232
  function checkList(nodes) {
270
- const accessors = nodes
271
- .filter(isAccessorKind)
272
- .map(createAccessorData)
273
- .reduce(mergeAccessorData, []);
233
+ const accessors = [];
234
+ let found = false;
235
+
236
+ for (let i = 0; i < nodes.length; i++) {
237
+ const node = nodes[i];
238
+
239
+ if (isAccessorKind(node)) {
240
+
241
+ // Creates a new `AccessorData` object for the given getter or setter node.
242
+ const name = astUtils.getStaticPropertyName(node);
243
+ const key = (name !== null) ? name : sourceCode.getTokens(node.key);
244
+
245
+ // Merges the given `AccessorData` object into the given accessors list.
246
+ for (let j = 0; j < accessors.length; j++) {
247
+ const accessor = accessors[j];
248
+
249
+ if (areEqualKeys(accessor.key, key)) {
250
+ accessor.getters.push(...node.kind === "get" ? [node] : []);
251
+ accessor.setters.push(...node.kind === "set" ? [node] : []);
252
+ found = true;
253
+ break;
254
+ }
255
+ }
256
+ if (!found) {
257
+ accessors.push({
258
+ key,
259
+ getters: node.kind === "get" ? [node] : [],
260
+ setters: node.kind === "set" ? [node] : []
261
+ });
262
+ }
263
+ found = false;
264
+ }
265
+ }
274
266
 
275
267
  for (const { getters, setters } of accessors) {
276
268
  if (checkSetWithoutGet && setters.length && !getters.length) {
@@ -240,19 +240,25 @@ module.exports = {
240
240
  .some(element => element.loc.start.line !== element.loc.end.line);
241
241
  }
242
242
 
243
- const linebreaksCount = node.elements.map((element, i) => {
243
+ let linebreaksCount = 0;
244
+
245
+ for (let i = 0; i < node.elements.length; i++) {
246
+ const element = node.elements[i];
247
+
244
248
  const previousElement = elements[i - 1];
245
249
 
246
250
  if (i === 0 || element === null || previousElement === null) {
247
- return false;
251
+ continue;
248
252
  }
249
253
 
250
254
  const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
251
255
  const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
252
256
  const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);
253
257
 
254
- return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement);
255
- }).filter(isBreak => isBreak === true).length;
258
+ if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
259
+ linebreaksCount++;
260
+ }
261
+ }
256
262
 
257
263
  const needsLinebreaks = (
258
264
  elements.length >= options.minItems ||
@@ -133,8 +133,7 @@ module.exports = {
133
133
  }
134
134
  if (
135
135
  node.computed &&
136
- node.property.type === "TemplateLiteral" &&
137
- node.property.expressions.length === 0
136
+ astUtils.isStaticTemplateLiteral(node.property)
138
137
  ) {
139
138
  checkComputedProperty(node, node.property.quasis[0].value.cooked);
140
139
  }
@@ -137,43 +137,6 @@ module.exports = {
137
137
  });
138
138
  }
139
139
 
140
- /**
141
- * Creates a new `AccessorData` object for the given getter or setter node.
142
- * @param {ASTNode} node A getter or setter node.
143
- * @returns {AccessorData} New `AccessorData` object that contains the given node.
144
- * @private
145
- */
146
- function createAccessorData(node) {
147
- const name = astUtils.getStaticPropertyName(node);
148
- const key = (name !== null) ? name : sourceCode.getTokens(node.key);
149
-
150
- return {
151
- key,
152
- getters: node.kind === "get" ? [node] : [],
153
- setters: node.kind === "set" ? [node] : []
154
- };
155
- }
156
-
157
- /**
158
- * Merges the given `AccessorData` object into the given accessors list.
159
- * @param {AccessorData[]} accessors The list to merge into.
160
- * @param {AccessorData} accessorData The object to merge.
161
- * @returns {AccessorData[]} The same instance with the merged object.
162
- * @private
163
- */
164
- function mergeAccessorData(accessors, accessorData) {
165
- const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
166
-
167
- if (equalKeyElement) {
168
- equalKeyElement.getters.push(...accessorData.getters);
169
- equalKeyElement.setters.push(...accessorData.setters);
170
- } else {
171
- accessors.push(accessorData);
172
- }
173
-
174
- return accessors;
175
- }
176
-
177
140
  /**
178
141
  * Checks accessor pairs in the given list of nodes.
179
142
  * @param {ASTNode[]} nodes The list to check.
@@ -182,11 +145,39 @@ module.exports = {
182
145
  * @private
183
146
  */
184
147
  function checkList(nodes, shouldCheck) {
185
- const accessors = nodes
186
- .filter(shouldCheck)
187
- .filter(isAccessorKind)
188
- .map(createAccessorData)
189
- .reduce(mergeAccessorData, []);
148
+ const accessors = [];
149
+ let found = false;
150
+
151
+ for (let i = 0; i < nodes.length; i++) {
152
+ const node = nodes[i];
153
+
154
+ if (shouldCheck(node) && isAccessorKind(node)) {
155
+
156
+ // Creates a new `AccessorData` object for the given getter or setter node.
157
+ const name = astUtils.getStaticPropertyName(node);
158
+ const key = (name !== null) ? name : sourceCode.getTokens(node.key);
159
+
160
+ // Merges the given `AccessorData` object into the given accessors list.
161
+ for (let j = 0; j < accessors.length; j++) {
162
+ const accessor = accessors[j];
163
+
164
+ if (areEqualKeys(accessor.key, key)) {
165
+ accessor.getters.push(...node.kind === "get" ? [node] : []);
166
+ accessor.setters.push(...node.kind === "set" ? [node] : []);
167
+ found = true;
168
+ break;
169
+ }
170
+ }
171
+ if (!found) {
172
+ accessors.push({
173
+ key,
174
+ getters: node.kind === "get" ? [node] : [],
175
+ setters: node.kind === "set" ? [node] : []
176
+ });
177
+ }
178
+ found = false;
179
+ }
180
+ }
190
181
 
191
182
  for (const { getters, setters } of accessors) {
192
183