diff --git a/lib/rules/no-render-return-undefined.js b/lib/rules/no-render-return-undefined.js index 262455afe6..7f845cb691 100644 --- a/lib/rules/no-render-return-undefined.js +++ b/lib/rules/no-render-return-undefined.js @@ -28,72 +28,67 @@ module.exports = { }, create(context) { - return { - FunctionDeclaration(node) { - const fnName = node.id.name; - const isReactComponent = fnName[0] === fnName[0].toUpperCase(); - const returnStatement = astUtil.findReturnStatement(node); + const handleFunctionalComponents = (node) => { + const fnName = (node.id && node.id.name) || node.parent.id.name; + const isReactComponent = fnName[0] === fnName[0].toUpperCase(); + const returnStatement = astUtil.findReturnStatement(node); - if (!isReactComponent) return; + if (!isReactComponent) return; - const variables = variableUtil.variablesInScope(context); - const returnNode = returnStatement && returnStatement.argument; - const returnIdentifierName = returnNode && returnNode.name; - const returnIdentifierVar = variableUtil.getVariable( - variables, - returnIdentifierName - ); - const returnIdentifierValue = (() => { - if (!returnNode) return undefined; + const variables = variableUtil.variablesInScope(context); + const returnNode = returnStatement && returnStatement.argument; + const returnIdentifierName = returnNode && returnNode.name; + const returnIdentifierVar = variableUtil.getVariable( + variables, + returnIdentifierName + ); + const returnIdentifierValue = (() => { + if (!returnNode) return undefined; + if ( + returnIdentifierVar + && returnIdentifierVar.defs + && returnIdentifierVar.defs[0] + ) { + const value = returnIdentifierVar.defs[0].node.init; if ( - returnIdentifierVar - && returnIdentifierVar.defs - && returnIdentifierVar.defs[0] + returnIdentifierVar.defs[0].node.type === 'VariableDeclarator' + && value === null ) { - const value = returnIdentifierVar.defs[0].node.init; - if ( - returnIdentifierVar.defs[0].node.type === 'VariableDeclarator' - && value === null - ) { - return undefined; - } - return value; + return undefined; } + return value; + } - if (returnNode.type === 'ArrayExpression') { - return returnNode.elements; - } + if (returnNode.type === 'ArrayExpression') { + return returnNode.elements; + } - if (returnNode.type === 'JSXElement') { - return returnNode; - } + if (returnNode.type === 'JSXElement') { + return returnNode; + } - return returnNode.value; - })(); + return returnNode.value; + })(); - // console.log('DEBUG', returnIdentifierValue); + const returnsArrayHavingUndefined = Array.isArray(returnIdentifierValue) + && returnIdentifierValue.some((el) => el.type === 'Identifier' && el.name === 'undefined'); - const returnsArrayHavingUndefined = Array.isArray(returnIdentifierValue) - && returnIdentifierValue.some((el) => el.type === 'Identifier' && el.name === 'undefined'); + if ( + !returnStatement + || returnIdentifierName === 'undefined' + || returnIdentifierValue === undefined + || (returnIdentifierValue && returnIdentifierValue.name === 'undefined') + || returnsArrayHavingUndefined + ) { + report(context, messages.returnsUndefined, 'returnsUndefined', { + node, + }); + } + }; - if ( - !returnStatement - || returnIdentifierName === 'undefined' - || returnIdentifierValue === undefined - || (returnIdentifierValue && returnIdentifierValue.name === 'undefined') - || returnsArrayHavingUndefined - ) { - report(context, messages.returnsUndefined, 'returnsUndefined', { - node, - }); - } - }, - // FunctionExpression(node) { - // // console.log('DEBUG fn expression', node); - // }, - // ArrowFunctionExpression(node) { - // // console.log('DEBUG fn arrow function', node); - // }, + return { + FunctionDeclaration: handleFunctionalComponents, + ArrowFunctionExpression: handleFunctionalComponents, }; }, }; diff --git a/tests/lib/rules/no-render-return-undefined.js b/tests/lib/rules/no-render-return-undefined.js index 664a3d412f..9ac76f55f2 100644 --- a/tests/lib/rules/no-render-return-undefined.js +++ b/tests/lib/rules/no-render-return-undefined.js @@ -36,6 +36,13 @@ ruleTester.run('no-render-return-undefined', rule, { } `, }, + { + code: ` + const App = () => { + return 123; + } + `, + }, { code: ` function App() { @@ -85,6 +92,32 @@ ruleTester.run('no-render-return-undefined', rule, { } `, }, + { + code: ` + function App() { + return ; + } + `, + }, + { + code: ` + function App() { + return ( + + + + ); + } + `, + }, + { + code: ` + const ui = ; + function App() { + return ui; + } + `, + }, ]), invalid: parsers.all([ { @@ -93,6 +126,28 @@ ruleTester.run('no-render-return-undefined', rule, { `, errors: [{ messageId: 'returnsUndefined' }], }, + { + code: ` + const App = () => {} + `, + errors: [{ messageId: 'returnsUndefined' }], + }, + { + code: ` + function App() { + return; + } + `, + errors: [{ messageId: 'returnsUndefined' }], + }, + { + code: ` + const App = () => { + return; + } + `, + errors: [{ messageId: 'returnsUndefined' }], + }, { code: ` function App() { @@ -101,6 +156,14 @@ ruleTester.run('no-render-return-undefined', rule, { `, errors: [{ messageId: 'returnsUndefined' }], }, + { + code: ` + const App = () => { + return undefined; + } + `, + errors: [{ messageId: 'returnsUndefined' }], + }, { code: ` function App() { @@ -148,9 +211,27 @@ ruleTester.run('no-render-return-undefined', rule, { }, { code: ` - function App() { - return [undefined]; - } + function App() { + return [undefined]; + } + `, + errors: [{ messageId: 'returnsUndefined' }], + }, + { + code: ` + function App() { + return [undefined, undefined]; + } + `, + errors: [{ messageId: 'returnsUndefined' }], + }, + { + code: ` + function foo() {} + + function App() { + return foo(); + } `, errors: [{ messageId: 'returnsUndefined' }], },