Skip to content

Commit

Permalink
Check if SFC is returning JSX or null
Browse files Browse the repository at this point in the history
  • Loading branch information
jomasti committed Nov 20, 2017
1 parent dfa5005 commit db5a243
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 16 deletions.
67 changes: 52 additions & 15 deletions lib/util/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,7 @@ function componentRule(rule, context) {
return calledOnReact;
},

/**
* Check if the node is returning JSX
*
* @param {ASTNode} ASTnode The AST node being checked
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
* @returns {Boolean} True if the node is returning JSX, false if not
*/
isReturningJSX: function(ASTnode, strict) {
getReturnPropertyAndNode(ASTnode) {
let property;
let node = ASTnode;
switch (node.type) {
Expand All @@ -321,19 +314,34 @@ function componentRule(rule, context) {
property = 'body';
if (node[property] && node[property].type === 'BlockStatement') {
node = utils.findReturnStatement(node);
if (!node) {
return false;
}
property = 'argument';
}
break;
default:
node = utils.findReturnStatement(node);
if (!node) {
return false;
}
property = 'argument';
}
return {
node: node,
property: property
};
},

/**
* Check if the node is returning JSX
*
* @param {ASTNode} ASTnode The AST node being checked
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
* @returns {Boolean} True if the node is returning JSX, false if not
*/
isReturningJSX: function(ASTnode, strict) {
const nodeAndProperty = utils.getReturnPropertyAndNode(ASTnode);
const node = nodeAndProperty.node;
const property = nodeAndProperty.property;

if (!node) {
return false;
}

const returnsConditionalJSXConsequent =
node[property] &&
Expand Down Expand Up @@ -363,6 +371,35 @@ function componentRule(rule, context) {
);
},

/**
* Check if the node is returning null
*
* @param {ASTNode} ASTnode The AST node being checked
* @returns {Boolean} True if the node is returning null, false if not
*/
isReturningNull(ASTnode) {
const nodeAndProperty = utils.getReturnPropertyAndNode(ASTnode);
const property = nodeAndProperty.property;
const node = nodeAndProperty.node;

if (!node) {
return false;
}

return node[property] && node[property].value === null;
},

/**
* Check if the node is returning JSX or null
*
* @param {ASTNode} ASTnode The AST node being checked
* @param {Boolean} strict If true, in a ternary condition the node must return JSX in both cases
* @returns {Boolean} True if the node is returning JSX or null, false if not
*/
isReturningJSXOrNull(ASTNode, strict) {
return utils.isReturningJSX(ASTNode, strict) || utils.isReturningNull(ASTNode);
},

/**
* Find a return statment in the current node
*
Expand Down Expand Up @@ -437,7 +474,7 @@ function componentRule(rule, context) {
return null;
}
// Return the node if it is a function that is not a class method and is not inside a JSX Element
if (isFunction && !isMethod && !isJSXExpressionContainer && utils.isReturningJSX(node)) {
if (isFunction && !isMethod && !isJSXExpressionContainer && utils.isReturningJSXOrNull(node)) {
return node;
}
scope = scope.upper;
Expand Down
7 changes: 6 additions & 1 deletion tests/lib/rules/no-this-in-sfc.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ ruleTester.run('no-this-in-sfc', rule, {
const { foo } = props;
return <div bar={foo} />;
}`
}, {
code: `
function Foo({ foo }) {
return <div bar={foo} />;
}`
}, {
code: `
class Foo extends React.Component {
Expand All @@ -58,7 +63,7 @@ ruleTester.run('no-this-in-sfc', rule, {
settings: {react: {createClass: 'createClass'}}
}, {
code: `
function Foo (bar) {
function foo(bar) {
this.bar = bar;
this.props = 'baz';
this.getFoo = function() {
Expand Down

0 comments on commit db5a243

Please sign in to comment.