diff --git a/rules/no-array-for-each.js b/rules/no-array-for-each.js index ac5127de09..74e6cb8e02 100644 --- a/rules/no-array-for-each.js +++ b/rules/no-array-for-each.js @@ -302,6 +302,14 @@ function isFunctionParameterVariableReassigned(callbackFunction, context) { }); } +const isExpressionStatement = node => { + if (node.type === 'ChainExpression') { + node = node.parent; + } + + return node.type === 'ExpressionStatement'; +}; + function isFixable(callExpression, {scope, functionInfo, allIdentifiers, context}) { const sourceCode = context.getSourceCode(); // Check `CallExpression` @@ -313,14 +321,12 @@ function isFixable(callExpression, {scope, functionInfo, allIdentifiers, context return false; } - // Check `CallExpression.parent` - if (callExpression.parent.type !== 'ExpressionStatement') { + // Check ancestors, we only fix `ExpressionStatement` + if (!isExpressionStatement(callExpression.parent)) { return false; } // Check `CallExpression.callee` - // Because of `ChainExpression` wrapper, `foo?.forEach()` is already failed on previous check keep this just for safety - /* c8 ignore next 3 */ if (callExpression.callee.optional) { return false; } diff --git a/test/no-array-for-each.mjs b/test/no-array-for-each.mjs index 50e1c6876e..e3df34b062 100644 --- a/test/no-array-for-each.mjs +++ b/test/no-array-for-each.mjs @@ -196,6 +196,7 @@ test.snapshot({ bar(arguments) }) `, + 'a = foo?.bar.forEach((element) => bar(element));', // Auto-fix outdent` @@ -230,6 +231,7 @@ test.snapshot({ }); `, 'foo.forEach((element, index) => bar(element, index));', + 'foo?.bar.forEach((element) => bar(element));', // Array is parenthesized '(foo).forEach((element, index) => bar(element, index))', '(0, foo).forEach((element, index) => bar(element, index))', diff --git a/test/snapshots/no-array-for-each.mjs.md b/test/snapshots/no-array-for-each.mjs.md index a959a56049..e1c0d5eff6 100644 --- a/test/snapshots/no-array-for-each.mjs.md +++ b/test/snapshots/no-array-for-each.mjs.md @@ -674,6 +674,16 @@ Generated by [AVA](https://avajs.dev). ` ## Invalid #43 + 1 | a = foo?.bar.forEach((element) => bar(element)); + +> Error 1/1 + + `␊ + > 1 | a = foo?.bar.forEach((element) => bar(element));␊ + | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ + ` + +## Invalid #44 1 | foo.forEach(function (element) { 2 | bar(element); 3 | }); @@ -695,7 +705,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #44 +## Invalid #45 1 | foo.forEach(function withName(element) { 2 | bar(element); 3 | }); @@ -717,7 +727,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #45 +## Invalid #46 1 | foo.forEach((element) => { 2 | bar(element); 3 | }); @@ -739,7 +749,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #46 +## Invalid #47 1 | foo.forEach((element) => bar(element)); > Output @@ -755,7 +765,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #47 +## Invalid #48 1 | foo.forEach(function (element, index) { 2 | bar(element, index); 3 | }); @@ -777,7 +787,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #48 +## Invalid #49 1 | foo.forEach(function withName(element, index) { 2 | bar(element, index); 3 | }); @@ -799,7 +809,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #49 +## Invalid #50 1 | foo.forEach((element, index) => { 2 | bar(element, index); 3 | }); @@ -821,7 +831,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #50 +## Invalid #51 1 | foo.forEach((element, index) => bar(element, index)); > Output @@ -837,7 +847,23 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #51 +## Invalid #52 + 1 | foo?.bar.forEach((element) => bar(element)); + +> Output + + `␊ + 1 | for (const element of foo?.bar) bar(element);␊ + ` + +> Error 1/1 + + `␊ + > 1 | foo?.bar.forEach((element) => bar(element));␊ + | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ + ` + +## Invalid #53 1 | (foo).forEach((element, index) => bar(element, index)) > Output @@ -853,7 +879,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #52 +## Invalid #54 1 | (0, foo).forEach((element, index) => bar(element, index)) > Output @@ -869,7 +895,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #53 +## Invalid #55 1 | foo.forEach(function (element) { 2 | bar(element); 3 | },); @@ -891,7 +917,7 @@ Generated by [AVA](https://avajs.dev). 3 | },);␊ ` -## Invalid #54 +## Invalid #56 1 | foo.forEach(function withName(element) { 2 | bar(element); 3 | },); @@ -913,7 +939,7 @@ Generated by [AVA](https://avajs.dev). 3 | },);␊ ` -## Invalid #55 +## Invalid #57 1 | foo.forEach((element) => { 2 | bar(element); 3 | },); @@ -935,7 +961,7 @@ Generated by [AVA](https://avajs.dev). 3 | },);␊ ` -## Invalid #56 +## Invalid #58 1 | foo.forEach((element) => bar(element),); > Output @@ -951,7 +977,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #57 +## Invalid #59 1 | foo.forEach((element) => bar(element)) 2 | ;[foo].pop(); @@ -970,7 +996,7 @@ Generated by [AVA](https://avajs.dev). 2 | ;[foo].pop();␊ ` -## Invalid #58 +## Invalid #60 1 | foo.forEach((element) => { 2 | bar(element); 3 | }); @@ -1007,7 +1033,7 @@ Generated by [AVA](https://avajs.dev). 8 | }␊ ` -## Invalid #59 +## Invalid #61 1 | foo.forEach(element => ({})) > Output @@ -1023,7 +1049,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #60 +## Invalid #62 1 | foo.forEach((((((element => bar(element))))))); > Output @@ -1039,7 +1065,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #61 +## Invalid #63 1 | foo.forEach((element) => { 2 | if (1) { 3 | return; @@ -1175,7 +1201,7 @@ Generated by [AVA](https://avajs.dev). 41 | });␊ ` -## Invalid #62 +## Invalid #64 1 | node.children.index.forEach((children, index) => process(children, index)) > Output @@ -1191,7 +1217,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #63 +## Invalid #65 1 | (node?.children?.index).forEach((children, index) => process(children, index)) > Output @@ -1207,7 +1233,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #64 +## Invalid #66 1 | node[children].index.forEach((children, index) => process(children, index)) > Error 1/1 @@ -1217,7 +1243,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #65 +## Invalid #67 1 | (node.children?.[index]).forEach((children, index) => process(children, index)) > Error 1/1 @@ -1227,7 +1253,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #66 +## Invalid #68 1 | [{children: 1, index: 1}].forEach((children, index) => process(children, index)) > Output @@ -1243,7 +1269,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #67 +## Invalid #69 1 | [{[children]: 1, index: 1}].forEach((children, index) => process(children, index)) > Error 1/1 @@ -1253,7 +1279,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #68 +## Invalid #70 1 | [{[children]: 1, [index]: 1}].forEach((children, index) => process(children, index)) > Error 1/1 @@ -1263,7 +1289,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #69 +## Invalid #71 1 | [{children, index: 1}].forEach((children, index) => process(children, index)) > Error 1/1 @@ -1273,7 +1299,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #70 +## Invalid #72 1 | [{children: 1, index}].forEach((children, index) => process(children, index)) > Error 1/1 @@ -1283,7 +1309,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #71 +## Invalid #73 1 | [function name() {}].forEach((name, index) => process(name, index)) > Output @@ -1299,7 +1325,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #72 +## Invalid #74 1 | [ 2 | function () { 3 | function index() {} @@ -1327,7 +1353,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #73 +## Invalid #75 1 | [ 2 | function () { 3 | class index {} @@ -1355,7 +1381,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #74 +## Invalid #76 1 | [class Foo{}].forEach((Foo, index) => process(Foo, index)) > Output @@ -1371,7 +1397,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #75 +## Invalid #77 1 | [class Foo{}].forEach((X, Foo) => process(X, Foo)) > Output @@ -1387,7 +1413,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #76 +## Invalid #78 1 | [ 2 | class Foo { 3 | bar() {} @@ -1415,7 +1441,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #77 +## Invalid #79 1 | foo.React.Children.forEach(bar) > Error 1/1 @@ -1425,7 +1451,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #78 +## Invalid #80 1 | NotReact.Children.forEach(bar) > Error 1/1 @@ -1435,7 +1461,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #79 +## Invalid #81 1 | React.NotChildren.forEach(bar) > Error 1/1 @@ -1445,7 +1471,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #80 +## Invalid #82 1 | React?.Children.forEach(bar) > Error 1/1 @@ -1455,7 +1481,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #81 +## Invalid #83 1 | NotChildren.forEach(bar) > Error 1/1 @@ -1465,7 +1491,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #82 +## Invalid #84 1 | foo.forEach(element => { 2 | element ++; 3 | }) @@ -1487,7 +1513,7 @@ Generated by [AVA](https://avajs.dev). 3 | })␊ ` -## Invalid #83 +## Invalid #85 1 | foo.forEach(element => { 2 | const a = -- element; 3 | }) @@ -1509,7 +1535,7 @@ Generated by [AVA](https://avajs.dev). 3 | })␊ ` -## Invalid #84 +## Invalid #86 1 | foo.forEach((element, index) => { 2 | index ++; 3 | element = 2 @@ -1534,7 +1560,7 @@ Generated by [AVA](https://avajs.dev). 4 | });␊ ` -## Invalid #85 +## Invalid #87 1 | foo.forEach((element, index) => { 2 | element >>>= 2; 3 | }); @@ -1556,7 +1582,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #86 +## Invalid #88 1 | foo.forEach((element, index) => { 2 | const a = element = 1; 3 | }); @@ -1578,7 +1604,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #87 +## Invalid #89 1 | foo.forEach((element, index) => { 2 | let a; 3 | a >>>= element; @@ -1603,7 +1629,7 @@ Generated by [AVA](https://avajs.dev). 4 | });␊ ` -## Invalid #88 +## Invalid #90 1 | foo.forEach(({property}) => {bar(property)}) > Output @@ -1619,7 +1645,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #89 +## Invalid #91 1 | foo.forEach(({foo: {foo: [property]}}) => {bar(property, index)}) > Output @@ -1635,7 +1661,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #90 +## Invalid #92 1 | foo.forEach((element, {bar: {bar: [index]}}) => {bar(element, index)}) > Output @@ -1651,7 +1677,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #91 +## Invalid #93 1 | foo.forEach((element = elementDefaultValue, index = indexDefaultValue) => {}) > Output @@ -1667,7 +1693,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #92 +## Invalid #94 1 | foo.forEach(({}) => {}) > Output @@ -1683,7 +1709,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #93 +## Invalid #95 1 | foo.forEach(function foo({a, b, c, d}) {}) > Output @@ -1699,7 +1725,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #94 +## Invalid #96 1 | foo.forEach(function foo({a, b, c, d, foo}) {}) > Error 1/1 @@ -1709,7 +1735,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #95 +## Invalid #97 1 | foo.forEach(({foo: property}) => {bar(property)}) > Output @@ -1725,7 +1751,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #96 +## Invalid #98 1 | foo.forEach(({[foo]: property}) => {bar(property)}) > Output @@ -1741,7 +1767,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^ Use \`for…of\` instead of \`Array#forEach(…)\`.␊ ` -## Invalid #97 +## Invalid #99 1 | foo.forEach(({element}, index) => { 2 | element &&= 2; 3 | }); @@ -1763,7 +1789,7 @@ Generated by [AVA](https://avajs.dev). 3 | });␊ ` -## Invalid #98 +## Invalid #100 1 | foo.forEach(_ => { 2 | if (true) return {}; 3 | }) @@ -1785,7 +1811,7 @@ Generated by [AVA](https://avajs.dev). 3 | })␊ ` -## Invalid #99 +## Invalid #101 1 | foo.forEach(_ => { 2 | if (true); 3 | else return {}; @@ -1810,7 +1836,7 @@ Generated by [AVA](https://avajs.dev). 4 | })␊ ` -## Invalid #100 +## Invalid #102 1 | if (true) {} else[foo].forEach((element) => {}) > Output diff --git a/test/snapshots/no-array-for-each.mjs.snap b/test/snapshots/no-array-for-each.mjs.snap index 284f78411a..c83076f71b 100644 Binary files a/test/snapshots/no-array-for-each.mjs.snap and b/test/snapshots/no-array-for-each.mjs.snap differ