Skip to content

Commit 4271e95

Browse files
authored
no-array-for-each: Add auto-fix for some wrongly detected case (#1043)
1 parent a091842 commit 4271e95

File tree

4 files changed

+289
-1
lines changed

4 files changed

+289
-1
lines changed

rules/no-array-for-each.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ function isParameterSafeToFix(parameter, {scope, array, allIdentifiers}) {
212212

213213
const [arrayStart, arrayEnd] = array.range;
214214
for (const identifier of allIdentifiers) {
215-
const {name, range: [start, end]} = identifier;
215+
const {name, range: [start, end], parent} = identifier;
216216
if (
217217
name !== parameterName ||
218218
start < arrayStart ||
@@ -221,6 +221,31 @@ function isParameterSafeToFix(parameter, {scope, array, allIdentifiers}) {
221221
continue;
222222
}
223223

224+
if (
225+
(
226+
(
227+
parent.type === 'FunctionExpression' ||
228+
parent.type === 'ClassExpression' ||
229+
parent.type === 'FunctionDeclaration' ||
230+
parent.type === 'ClassDeclaration'
231+
) &&
232+
parent.id === identifier
233+
) ||
234+
(
235+
parent.type === 'MemberExpression' &&
236+
!parent.computed &&
237+
parent.property === identifier
238+
) ||
239+
(
240+
parent.type === 'Property' &&
241+
!parent.shorthand &&
242+
!parent.computed &&
243+
parent.key === identifier
244+
)
245+
) {
246+
continue;
247+
}
248+
224249
const variable = findVariable(scope, identifier);
225250
if (!variable || variable.scope === scope || isChildScope(scope, variable.scope)) {
226251
return false;

test/no-array-for-each.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,39 @@ test.snapshot({
301301
return [foo] = bar;
302302
}
303303
});
304+
`,
305+
'node.children.index.forEach((children, index) => process(children, index))',
306+
'(node?.children?.index).forEach((children, index) => process(children, index))',
307+
'node[children].index.forEach((children, index) => process(children, index))',
308+
'(node.children?.[index]).forEach((children, index) => process(children, index))',
309+
'[{children: 1, index: 1}].forEach((children, index) => process(children, index))',
310+
'[{[children]: 1, index: 1}].forEach((children, index) => process(children, index))',
311+
'[{[children]: 1, [index]: 1}].forEach((children, index) => process(children, index))',
312+
'[{children, index: 1}].forEach((children, index) => process(children, index))',
313+
'[{children: 1, index}].forEach((children, index) => process(children, index))',
314+
'[function name() {}].forEach((name, index) => process(name, index))',
315+
outdent`
316+
[
317+
function () {
318+
function index() {}
319+
}
320+
].forEach((name, index) => process(name, index))
321+
`,
322+
outdent`
323+
[
324+
function () {
325+
class index {}
326+
}
327+
].forEach((name, index) => process(name, index))
328+
`,
329+
'[class Foo{}].forEach((Foo, index) => process(Foo, index))',
330+
'[class Foo{}].forEach((X, Foo) => process(X, Foo))',
331+
outdent`
332+
[
333+
class Foo {
334+
bar() {}
335+
}
336+
].forEach((Foo, bar) => process(Foo, bar))
304337
`
305338
]
306339
});

test/snapshots/no-array-for-each.js.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,3 +1174,233 @@ Generated by [AVA](https://avajs.dev).
11741174
40 | }␊
11751175
41 | });␊
11761176
`
1177+
1178+
## Invalid #62
1179+
1 | node.children.index.forEach((children, index) => process(children, index))
1180+
1181+
> Output
1182+
1183+
`␊
1184+
1 | for (const [index, children] of node.children.index.entries()) process(children, index)␊
1185+
`
1186+
1187+
> Error 1/1
1188+
1189+
`␊
1190+
> 1 | node.children.index.forEach((children, index) => process(children, index))␊
1191+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1192+
`
1193+
1194+
## Invalid #63
1195+
1 | (node?.children?.index).forEach((children, index) => process(children, index))
1196+
1197+
> Output
1198+
1199+
`␊
1200+
1 | for (const [index, children] of (node?.children?.index).entries()) process(children, index)␊
1201+
`
1202+
1203+
> Error 1/1
1204+
1205+
`␊
1206+
> 1 | (node?.children?.index).forEach((children, index) => process(children, index))␊
1207+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1208+
`
1209+
1210+
## Invalid #64
1211+
1 | node[children].index.forEach((children, index) => process(children, index))
1212+
1213+
> Error 1/1
1214+
1215+
`␊
1216+
> 1 | node[children].index.forEach((children, index) => process(children, index))␊
1217+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1218+
`
1219+
1220+
## Invalid #65
1221+
1 | (node.children?.[index]).forEach((children, index) => process(children, index))
1222+
1223+
> Error 1/1
1224+
1225+
`␊
1226+
> 1 | (node.children?.[index]).forEach((children, index) => process(children, index))␊
1227+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1228+
`
1229+
1230+
## Invalid #66
1231+
1 | [{children: 1, index: 1}].forEach((children, index) => process(children, index))
1232+
1233+
> Output
1234+
1235+
`␊
1236+
1 | for (const [index, children] of [{children: 1, index: 1}].entries()) process(children, index)␊
1237+
`
1238+
1239+
> Error 1/1
1240+
1241+
`␊
1242+
> 1 | [{children: 1, index: 1}].forEach((children, index) => process(children, index))␊
1243+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1244+
`
1245+
1246+
## Invalid #67
1247+
1 | [{[children]: 1, index: 1}].forEach((children, index) => process(children, index))
1248+
1249+
> Error 1/1
1250+
1251+
`␊
1252+
> 1 | [{[children]: 1, index: 1}].forEach((children, index) => process(children, index))␊
1253+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1254+
`
1255+
1256+
## Invalid #68
1257+
1 | [{[children]: 1, [index]: 1}].forEach((children, index) => process(children, index))
1258+
1259+
> Error 1/1
1260+
1261+
`␊
1262+
> 1 | [{[children]: 1, [index]: 1}].forEach((children, index) => process(children, index))␊
1263+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1264+
`
1265+
1266+
## Invalid #69
1267+
1 | [{children, index: 1}].forEach((children, index) => process(children, index))
1268+
1269+
> Error 1/1
1270+
1271+
`␊
1272+
> 1 | [{children, index: 1}].forEach((children, index) => process(children, index))␊
1273+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1274+
`
1275+
1276+
## Invalid #70
1277+
1 | [{children: 1, index}].forEach((children, index) => process(children, index))
1278+
1279+
> Error 1/1
1280+
1281+
`␊
1282+
> 1 | [{children: 1, index}].forEach((children, index) => process(children, index))␊
1283+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1284+
`
1285+
1286+
## Invalid #71
1287+
1 | [function name() {}].forEach((name, index) => process(name, index))
1288+
1289+
> Output
1290+
1291+
`␊
1292+
1 | for (const [index, name] of [function name() {}].entries()) process(name, index)␊
1293+
`
1294+
1295+
> Error 1/1
1296+
1297+
`␊
1298+
> 1 | [function name() {}].forEach((name, index) => process(name, index))␊
1299+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1300+
`
1301+
1302+
## Invalid #72
1303+
1 | [
1304+
2 | function () {
1305+
3 | function index() {}
1306+
4 | }
1307+
5 | ].forEach((name, index) => process(name, index))
1308+
1309+
> Output
1310+
1311+
`␊
1312+
1 | for (const [index, name] of [␊
1313+
2 | function () {␊
1314+
3 | function index() {}␊
1315+
4 | }␊
1316+
5 | ].entries()) process(name, index)␊
1317+
`
1318+
1319+
> Error 1/1
1320+
1321+
`␊
1322+
1 | [␊
1323+
2 | function () {␊
1324+
3 | function index() {}␊
1325+
4 | }␊
1326+
> 5 | ].forEach((name, index) => process(name, index))␊
1327+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1328+
`
1329+
1330+
## Invalid #73
1331+
1 | [
1332+
2 | function () {
1333+
3 | class index {}
1334+
4 | }
1335+
5 | ].forEach((name, index) => process(name, index))
1336+
1337+
> Output
1338+
1339+
`␊
1340+
1 | for (const [index, name] of [␊
1341+
2 | function () {␊
1342+
3 | class index {}␊
1343+
4 | }␊
1344+
5 | ].entries()) process(name, index)␊
1345+
`
1346+
1347+
> Error 1/1
1348+
1349+
`␊
1350+
1 | [␊
1351+
2 | function () {␊
1352+
3 | class index {}␊
1353+
4 | }␊
1354+
> 5 | ].forEach((name, index) => process(name, index))␊
1355+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1356+
`
1357+
1358+
## Invalid #74
1359+
1 | [class Foo{}].forEach((Foo, index) => process(Foo, index))
1360+
1361+
> Output
1362+
1363+
`␊
1364+
1 | for (const [index, Foo] of [class Foo{}].entries()) process(Foo, index)␊
1365+
`
1366+
1367+
> Error 1/1
1368+
1369+
`␊
1370+
> 1 | [class Foo{}].forEach((Foo, index) => process(Foo, index))␊
1371+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1372+
`
1373+
1374+
## Invalid #75
1375+
1 | [class Foo{}].forEach((X, Foo) => process(X, Foo))
1376+
1377+
> Output
1378+
1379+
`␊
1380+
1 | for (const [Foo, X] of [class Foo{}].entries()) process(X, Foo)␊
1381+
`
1382+
1383+
> Error 1/1
1384+
1385+
`␊
1386+
> 1 | [class Foo{}].forEach((X, Foo) => process(X, Foo))␊
1387+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1388+
`
1389+
1390+
## Invalid #76
1391+
1 | [
1392+
2 | class Foo {
1393+
3 | bar() {}
1394+
4 | }
1395+
5 | ].forEach((Foo, bar) => process(Foo, bar))
1396+
1397+
> Error 1/1
1398+
1399+
`␊
1400+
1 | [␊
1401+
2 | class Foo {␊
1402+
3 | bar() {}␊
1403+
4 | }␊
1404+
> 5 | ].forEach((Foo, bar) => process(Foo, bar))␊
1405+
| ^^^^^^^ Do not use `Array#forEach(…)`.␊
1406+
`
791 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)