Skip to content

Commit

Permalink
Fix scope limit for stateless component detection (fixes #268)
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickcr committed Nov 4, 2015
1 parent 1a5143a commit a98fa94
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
5 changes: 4 additions & 1 deletion lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,13 @@ module.exports = Components.detect(function(context, components) {
if (Object.prototype[name]) {
break;
}

var isDirectProp = /^props\./.test(context.getSource(node));

usedPropTypes.push({
name: name,
allNames: allNames,
node: node.object.name !== 'props' && !inConstructor() ? node.parent.property : node.property
node: !isDirectProp && !inConstructor(node) ? node.parent.property : node.property
});
break;
case 'destructuring':
Expand Down
17 changes: 10 additions & 7 deletions lib/util/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,17 @@ function componentRule(rule, context) {
*/
getParentStatelessComponent: function() {
var scope = context.getScope();
var node = scope.block;
var isNotAFunction = !/Function/.test(node.type); // Ignore non functions
var isMethod = node.parent && node.parent.type === 'MethodDefinition'; // Ignore classes methods
var isArgument = node.parent && node.parent.type === 'CallExpression'; // Ignore arguments (map, callback, etc.)
if (isNotAFunction || isMethod || isArgument) {
return null;
while (scope) {
var node = scope.block;
var isFunction = /Function/.test(node.type); // Ignore non functions
var isNotMethod = !node.parent || node.parent.type !== 'MethodDefinition'; // Ignore classes methods
var isNotArgument = !node.parent || node.parent.type !== 'CallExpression'; // Ignore arguments (callback, etc.)
if (isFunction && isNotMethod && isNotArgument) {
return node;
}
scope = scope.upper;
}
return node;
return null;
},

/**
Expand Down
29 changes: 29 additions & 0 deletions tests/lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,20 @@ ruleTester.run('prop-types', rule, {
'};'
].join('\n'),
parser: 'babel-eslint'
}, {
code: [
'const Hello = (props) => {',
' let team = props.names.map((name) => {',
' return <li>{name}, {props.company}</li>;',
' });',
' return <ul>{team}</ul>;',
'};',
'Hello.propTypes = {',
' names: React.PropTypes.array,',
' company: React.PropTypes.string',
'};'
].join('\n'),
parser: 'babel-eslint'
}
],

Expand Down Expand Up @@ -1430,6 +1444,21 @@ ruleTester.run('prop-types', rule, {
{message: '\'firstname\' is missing in props validation'},
{message: '\'name\' is missing in props validation'}
]
}, {
code: [
'const Hello = (props) => {',
' let team = props.names.map((name) => {',
' return <li>{name}, {props.company}</li>;',
' });',
' return <ul>{team}</ul>;',
'};'
].join('\n'),
parser: 'babel-eslint',
errors: [
{message: '\'names\' is missing in props validation'},
{message: '\'names.map\' is missing in props validation'},
{message: '\'company\' is missing in props validation'}
]
}
]
});

0 comments on commit a98fa94

Please sign in to comment.