Skip to content

Commit 8baf0c5

Browse files
jxm-mathljharb
authored andcommitted
[Fix] display-name, component detection: fix HOF returning null as Components
Fixes #3346
1 parent b714407 commit 8baf0c5

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1717
* [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero)
1818
* [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero)
1919
* [`require-default-props`]: avoid a crash when function has no props param ([#3350][] @noahnu)
20+
* [`display-name`], component detection: fix HOF returning null as Components ([#3347][] @jxm-math)
2021

2122
### Changed
2223
* [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
@@ -28,6 +29,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
2829

2930
[#3350]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3350
3031
[#3349]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3349
32+
[#3347]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3347
3133
[#3344]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3344
3234
[#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339
3335
[#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335

lib/util/Components.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,47 @@ function componentRule(rule, context) {
517517
return undefined;
518518
}
519519

520+
// case: any = () => () => null
521+
if (node.parent.type === 'ArrowFunctionExpression' && node.parent.parent.type === 'AssignmentExpression' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {
522+
if (isFirstLetterCapitalized(node.parent.parent.left.name)) {
523+
return node;
524+
}
525+
return undefined;
526+
}
527+
528+
// case: { any: () => () => null }
529+
if (node.parent.type === 'ArrowFunctionExpression' && node.parent.parent.type === 'Property' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {
530+
if (isFirstLetterCapitalized(node.parent.parent.key.name)) {
531+
return node;
532+
}
533+
return undefined;
534+
}
535+
536+
// case: any = function() {return function() {return null;};}
537+
if (node.parent.type === 'ReturnStatement') {
538+
if (isFirstLetterCapitalized(node.id && node.id.name)) {
539+
return node;
540+
}
541+
const functionExpr = node.parent.parent.parent;
542+
if (functionExpr.parent.type === 'AssignmentExpression' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {
543+
if (isFirstLetterCapitalized(functionExpr.parent.left.name)) {
544+
return node;
545+
}
546+
return undefined;
547+
}
548+
}
549+
550+
// case: { any: function() {return function() {return null;};} }
551+
if (node.parent.type === 'ReturnStatement') {
552+
const functionExpr = node.parent.parent.parent;
553+
if (functionExpr.parent.type === 'Property' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {
554+
if (isFirstLetterCapitalized(functionExpr.parent.key.name)) {
555+
return node;
556+
}
557+
return undefined;
558+
}
559+
}
560+
520561
// for case abc = { [someobject.somekey]: props => { ... return not-jsx } }
521562
if (node.parent && node.parent.key && node.parent.key.type === 'MemberExpression' && !utils.isReturningJSX(node) && !utils.isReturningOnlyNull(node)) {
522563
return undefined;

tests/lib/rules/display-name.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,34 @@ ruleTester.run('display-name', rule, {
615615
};
616616
`,
617617
},
618+
{
619+
// issue #3346
620+
code: `
621+
demo = () => () => null;
622+
`,
623+
},
624+
{
625+
// issue #3346
626+
code: `
627+
demo = {
628+
property: () => () => null
629+
}
630+
`,
631+
},
632+
{
633+
// issue #3346
634+
code: `
635+
demo = function() {return function() {return null;};};
636+
`,
637+
},
638+
{
639+
// issue #3346
640+
code: `
641+
demo = {
642+
property: function() {return function() {return null;};}
643+
}
644+
`,
645+
},
618646
{
619647
// issue #3303
620648
code: `
@@ -1141,5 +1169,33 @@ ruleTester.run('display-name', rule, {
11411169
},
11421170
],
11431171
},
1172+
{
1173+
code: `
1174+
Demo = () => () => null;
1175+
`,
1176+
errors: [{ messageId: 'noDisplayName' }],
1177+
},
1178+
{
1179+
code: `
1180+
demo = {
1181+
Property: () => () => null
1182+
}
1183+
`,
1184+
errors: [{ messageId: 'noDisplayName' }],
1185+
},
1186+
{
1187+
code: `
1188+
Demo = function() {return function() {return null;};};
1189+
`,
1190+
errors: [{ messageId: 'noDisplayName' }],
1191+
},
1192+
{
1193+
code: `
1194+
demo = {
1195+
Property: function() {return function() {return null;};}
1196+
}
1197+
`,
1198+
errors: [{ messageId: 'noDisplayName' }],
1199+
},
11441200
]),
11451201
});

0 commit comments

Comments
 (0)