Skip to content

Commit

Permalink
Merge pull request #1106 from Kerumen/master
Browse files Browse the repository at this point in the history
Fix nextProps false positive in no-unused-prop-types
  • Loading branch information
ljharb committed Mar 31, 2017
2 parents bfdd722 + 557322a commit 9a5303d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
31 changes: 28 additions & 3 deletions lib/rules/no-unused-prop-types.js
Expand Up @@ -18,6 +18,7 @@ var annotations = require('../util/annotations');
// ------------------------------------------------------------------------------

var DIRECT_PROPS_REGEX = /^props\s*(\.|\[)/;
var DIRECT_NEXT_PROPS_REGEX = /^nextProps\s*(\.|\[)/;

// ------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -77,6 +78,24 @@ module.exports = {
return value;
}

/**
* Check if we are in a class constructor
* @return {boolean} true if we are in a class constructor, false if not
**/
function inComponentWillReceiveProps() {
var scope = context.getScope();
while (scope) {
if (
scope.block && scope.block.parent &&
scope.block.parent.key && scope.block.parent.key.name === 'componentWillReceiveProps'
) {
return true;
}
scope = scope.upper;
}
return false;
}

/**
* Checks if we are using a prop
* @param {ASTNode} node The AST node being checked.
Expand All @@ -88,7 +107,8 @@ module.exports = {
node.object.type === 'ThisExpression' && node.property.name === 'props'
);
var isStatelessFunctionUsage = node.object.name === 'props';
return isClassUsage || isStatelessFunctionUsage;
var isNextPropsUsage = node.object.name === 'nextProps' && inComponentWillReceiveProps();
return isClassUsage || isStatelessFunctionUsage || isNextPropsUsage;
}

/**
Expand Down Expand Up @@ -491,12 +511,17 @@ module.exports = {
*/
function getPropertyName(node) {
var isDirectProp = DIRECT_PROPS_REGEX.test(sourceCode.getText(node));
var isDirectNextProp = DIRECT_NEXT_PROPS_REGEX.test(sourceCode.getText(node));
var isInClassComponent = utils.getParentES6Component() || utils.getParentES5Component();
var isNotInConstructor = !inConstructor(node);
if (isDirectProp && isInClassComponent && isNotInConstructor) {
var isNotInComponentWillReceiveProps = !inComponentWillReceiveProps();
if ((isDirectProp || isDirectNextProp)
&& isInClassComponent
&& isNotInConstructor
&& isNotInComponentWillReceiveProps) {
return void 0;
}
if (!isDirectProp) {
if (!isDirectProp && !isDirectNextProp) {
node = node.parent;
}
var property = node.property;
Expand Down
16 changes: 16 additions & 0 deletions tests/lib/rules/no-unused-prop-types.js
Expand Up @@ -1461,6 +1461,22 @@ ruleTester.run('no-unused-prop-types', rule, {
'};'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'class Hello extends Component {',
' componentWillReceiveProps (nextProps) {',
' if (nextProps.foo) {',
' doSomething(this.props.bar);',
' }',
' }',
'}',

'Hello.propTypes = {',
' foo: PropTypes.bool,',
' bar: PropTypes.bool',
'};'
].join('\n'),
parserOptions: parserOptions
}
],

Expand Down

0 comments on commit 9a5303d

Please sign in to comment.