Skip to content

Commit

Permalink
Add support for props destructuring directly on the this keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickcr committed Jun 28, 2015
1 parent 0b756b5 commit c02f952
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 19 deletions.
68 changes: 49 additions & 19 deletions lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,22 +360,46 @@ module.exports = function(context) {
function markPropTypesAsUsed(node, parentNames) {
parentNames = parentNames || [];
var type;
var name = getPropertyName(node.parent);
var name;
var allNames;
if (name) {
allNames = parentNames.concat(name);
if (node.parent.type === 'MemberExpression') {
markPropTypesAsUsed(node.parent, allNames);
}
// Do not mark computed props as used.
type = name !== '__COMPUTED_PROP__' ? 'direct' : null;
} else if (
node.parent.parent.declarations &&
node.parent.parent.declarations[0].id.properties &&
getKeyValue(node.parent.parent.declarations[0].id.properties[0])
) {
type = 'destructuring';
var properties;
switch (node.type) {
case 'MemberExpression':
name = getPropertyName(node.parent);
if (name) {
allNames = parentNames.concat(name);
if (node.parent.type === 'MemberExpression') {
markPropTypesAsUsed(node.parent, allNames);
}
// Do not mark computed props as used.
type = name !== '__COMPUTED_PROP__' ? 'direct' : null;
} else if (
node.parent.parent.declarations &&
node.parent.parent.declarations[0].id.properties &&
getKeyValue(node.parent.parent.declarations[0].id.properties[0])
) {
type = 'destructuring';
properties = node.parent.parent.declarations[0].id.properties;
}
break;
case 'VariableDeclarator':
type = 'destructuring';

for (var i = 0, j = node.id.properties.length; i < j; i++) {
if (
(node.id.properties[i].key.name !== 'props' && node.id.properties[i].key.value !== 'props') ||
node.id.properties[i].value.type !== 'ObjectPattern'
) {
continue;
}
properties = node.id.properties[i].value.properties;
break;
}
break;
default:
throw new Error(node.type + ' ASTNodes are not handled by markPropTypesAsUsed');
}

var component = componentList.getByNode(context, node);
var usedPropTypes = component && component.usedPropTypes || [];

Expand All @@ -392,17 +416,16 @@ module.exports = function(context) {
});
break;
case 'destructuring':
var properties = node.parent.parent.declarations[0].id.properties;
for (var i = 0, j = properties.length; i < j; i++) {
if (hasSpreadOperator(properties[i])) {
for (var k = 0, l = properties.length; k < l; k++) {
if (hasSpreadOperator(properties[k])) {
continue;
}
var propName = getKeyValue(properties[i]);
var propName = getKeyValue(properties[k]);
if (propName) {
usedPropTypes.push({
name: propName,
allNames: [propName],
node: properties[i]
node: properties[k]
});
}
}
Expand Down Expand Up @@ -509,6 +532,13 @@ module.exports = function(context) {
markPropTypesAsDeclared(node, node.value);
},

VariableDeclarator: function(node) {
if (node.init.type !== 'ThisExpression' || node.id.type !== 'ObjectPattern') {
return;
}
markPropTypesAsUsed(node);
},

MemberExpression: function(node) {
var type;
if (isPropTypesUsage(node)) {
Expand Down
26 changes: 26 additions & 0 deletions tests/lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,32 @@ eslintTester.addRuleTest('lib/rules/prop-types', {
errors: [
{message: '\'arr[].some.value\' is missing in props validation for Hello'}
]
}, {
code: [
'class Hello extends React.Component {',
' render() {',
' let {props: {firstname}} = this;',
' return <div>Hello {firstname}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [
{message: '\'firstname\' is missing in props validation for Hello'}
]
}, {
code: [
'class Hello extends React.Component {',
' render() {',
' var {\'props\': {firstname}} = this;',
' return <div>Hello {firstname}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [
{message: '\'firstname\' is missing in props validation for Hello'}
]
}
]
});

0 comments on commit c02f952

Please sign in to comment.