Skip to content

Commit

Permalink
[Fix] no-array-index-key: support optional chaining
Browse files Browse the repository at this point in the history
Fixes #2896.

Co-authored-by: Jordan Harband <ljharb@gmail.com>
  • Loading branch information
SyMind and ljharb committed Jan 5, 2021
1 parent 2201f9d commit 4406aba
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -9,7 +9,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
* [`jsx-no-constructed-context-values`]: avoid a crash with `as X` TS code ([#2894][] @ljharb)
* [`jsx-no-constructed-context-values`]: avoid a crash with boolean shorthand ([#2895][] @ljharb)
* [`static-property-placement`]: do not report non-components ([#2893][] @golopot)
* [ `no-array-index-key`]: support optional chaining ([#2897][] @SyMind)

[#2897]: https://github.com/yannickcr/eslint-plugin-react/pull/2897
[#2895]: https://github.com/yannickcr/eslint-plugin-react/issues/2895
[#2894]: https://github.com/yannickcr/eslint-plugin-react/issues/2894
[#2893]: https://github.com/yannickcr/eslint-plugin-react/pull/2893
Expand Down
25 changes: 14 additions & 11 deletions lib/rules/no-array-index-key.js
Expand Up @@ -77,7 +77,7 @@ module.exports = {

function getMapIndexParamName(node) {
const callee = node.callee;
if (callee.type !== 'MemberExpression') {
if (callee.type !== 'MemberExpression' && callee.type !== 'OptionalMemberExpression') {
return null;
}
if (callee.property.type !== 'Identifier') {
Expand Down Expand Up @@ -153,11 +153,20 @@ module.exports = {
}
}

function popIndex(node) {
const mapIndexParamName = getMapIndexParamName(node);
if (!mapIndexParamName) {
return;
}

indexParamNames.pop();
}

return {
CallExpression(node) {
'CallExpression, OptionalCallExpression'(node) {
if (
node.callee
&& node.callee.type === 'MemberExpression'
&& (node.callee.type === 'MemberExpression' || node.callee.type === 'OptionalMemberExpression')
&& ['createElement', 'cloneElement'].indexOf(node.callee.property.name) !== -1
&& node.arguments.length > 1
) {
Expand Down Expand Up @@ -213,14 +222,8 @@ module.exports = {
checkPropValue(value.expression);
},

'CallExpression:exit'(node) {
const mapIndexParamName = getMapIndexParamName(node);
if (!mapIndexParamName) {
return;
}

indexParamNames.pop();
}
'CallExpression:exit': popIndex,
'OptionalCallExpression:exit': popIndex
};
}
};
6 changes: 6 additions & 0 deletions tests/helpers/parsers.js
Expand Up @@ -15,5 +15,11 @@ module.exports = {
return tests;
}
return [];
},
ES2020: function ES2020(tests) {
if (semver.satisfies(version, '>= 6')) {
return tests;
}
return [];
}
};
48 changes: 42 additions & 6 deletions tests/lib/rules/no-array-index-key.js
Expand Up @@ -10,6 +10,7 @@
// -----------------------------------------------------------------------------

const RuleTester = require('eslint').RuleTester;
const parsers = require('../../helpers/parsers');
const rule = require('../../../lib/rules/no-array-index-key');

const parserOptions = {
Expand All @@ -26,7 +27,7 @@ const parserOptions = {

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('no-array-index-key', rule, {
valid: [
valid: [].concat(
{code: '<Foo key="foo" />;'},
{code: '<Foo key={i} />;'},
{code: '<Foo key />;'},
Expand Down Expand Up @@ -105,10 +106,26 @@ ruleTester.run('no-array-index-key', rule, {
return React.cloneElement(child, { key: child.id });
})
`
}
],
},

invalid: [
parsers.ES2020({
code: 'foo?.map(child => <Foo key={child.i} />)',
parserOptions: {
ecmaVersion: 2020
}
}, {
code: 'foo?.map(child => <Foo key={child.i} />)',
parser: parsers.BABEL_ESLINT
}, {
code: 'foo?.map(child => <Foo key={child.i} />)',
parser: parsers.TYPESCRIPT_ESLINT
}, {
code: 'foo?.map(child => <Foo key={child.i} />)',
parser: parsers['@TYPESCRIPT_ESLINT']
})
),

invalid: [].concat(
{
code: 'foo.map((bar, i) => <Foo key={i} />)',
errors: [{message: 'Do not use Array index in keys'}]
Expand Down Expand Up @@ -279,7 +296,26 @@ ruleTester.run('no-array-index-key', rule, {
})
`,
errors: [{message: 'Do not use Array index in keys'}]
}
},

]
parsers.ES2020({
code: 'foo?.map((child, i) => <Foo key={i} />)',
errors: [{message: 'Do not use Array index in keys'}],
parserOptions: {
ecmaVersion: 2020
}
}, {
code: 'foo?.map((child, i) => <Foo key={i} />)',
errors: [{message: 'Do not use Array index in keys'}],
parser: parsers.BABEL_ESLINT
}, {
code: 'foo?.map((child, i) => <Foo key={i} />)',
errors: [{message: 'Do not use Array index in keys'}],
parser: parsers.TYPESCRIPT_ESLINT
}, {
code: 'foo?.map((child, i) => <Foo key={i} />)',
errors: [{message: 'Do not use Array index in keys'}],
parser: parsers['@TYPESCRIPT_ESLINT']
})
)
});

0 comments on commit 4406aba

Please sign in to comment.