Skip to content

Commit

Permalink
Fix require-default-props crash with babel-eslint@5 (fixes #1029)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yannick Croissant committed Jan 18, 2017
1 parent 0f79aa3 commit a151815
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
43 changes: 31 additions & 12 deletions lib/rules/require-default-props.js
Expand Up @@ -25,13 +25,33 @@ module.exports = {
},

create: Components.detect(function(context, components, utils) {

/**
* Get properties name
* @param {Object} node - Property.
* @returns {String} Property name.
*/
function getPropertyName(node) {
if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {
return node.key.name;
} else if (node.type === 'MemberExpression') {
return node.property.name;
// Special case for class properties
// (babel-eslint@5 does not expose property name so we have to rely on tokens)
} else if (node.type === 'ClassProperty') {
var tokens = context.getFirstTokens(node, 2);
return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;
}
return '';
}

/**
* Checks if the Identifier node passed in looks like a propTypes declaration.
* @param {ASTNode} node The node to check. Must be an Identifier node.
* @returns {Boolean} `true` if the node is a propTypes declaration, `false` if not
*/
function isPropTypesDeclaration(node) {
return node.type === 'Identifier' && node.name === 'propTypes';
return getPropertyName(node) === 'propTypes';
}

/**
Expand All @@ -40,8 +60,7 @@ module.exports = {
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not
*/
function isDefaultPropsDeclaration(node) {
return node.type === 'Identifier' &&
(node.name === 'defaultProps' || node.name === 'getDefaultProps');
return (getPropertyName(node) === 'defaultProps' || getPropertyName(node) === 'getDefaultProps');
}

/**
Expand Down Expand Up @@ -289,7 +308,7 @@ module.exports = {
}

function isPropTypeAnnotation(node) {
return (node.key.name === 'props' && !!node.typeAnnotation);
return (getPropertyName(node) === 'props' && !!node.typeAnnotation);
}

/**
Expand Down Expand Up @@ -328,8 +347,8 @@ module.exports = {

return {
MemberExpression: function(node) {
var isPropType = isPropTypesDeclaration(node.property);
var isDefaultProp = isDefaultPropsDeclaration(node.property);
var isPropType = isPropTypesDeclaration(node);
var isDefaultProp = isDefaultPropsDeclaration(node);

if (!isPropType && !isDefaultProp) {
return;
Expand Down Expand Up @@ -412,8 +431,8 @@ module.exports = {
return;
}

var isPropType = isPropTypesDeclaration(node.key);
var isDefaultProp = isDefaultPropsDeclaration(node.key);
var isPropType = isPropTypesDeclaration(node);
var isDefaultProp = isDefaultPropsDeclaration(node);

if (!isPropType && !isDefaultProp) {
return;
Expand Down Expand Up @@ -468,8 +487,8 @@ module.exports = {
return;
}

var isPropType = isPropTypesDeclaration(node.key);
var isDefaultProp = isDefaultPropsDeclaration(node.key);
var isPropType = getPropertyName(node) === 'propTypes';
var isDefaultProp = getPropertyName(node) === 'defaultProps' || getPropertyName(node) === 'getDefaultProps';

if (!isPropType && !isDefaultProp) {
return;
Expand Down Expand Up @@ -520,8 +539,8 @@ module.exports = {
return;
}

var isPropType = isPropTypesDeclaration(property.key);
var isDefaultProp = isDefaultPropsDeclaration(property.key);
var isPropType = isPropTypesDeclaration(property);
var isDefaultProp = isDefaultPropsDeclaration(property);

if (!isPropType && !isDefaultProp) {
return;
Expand Down
20 changes: 20 additions & 0 deletions tests/lib/rules/require-default-props.js
Expand Up @@ -1718,6 +1718,26 @@ ruleTester.run('require-default-props', rule, {
column: 3
}
]
},
{
code: [
'class Hello extends React.Component {',
' static propTypes = {',
' foo: PropTypes.string',
' };',
' render() {',
' return <div>Hello {this.props.foo}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [
{
message: 'propType "foo" is not required, but has no corresponding defaultProp declaration.',
line: 3,
column: 5
}
]
}
]
});

0 comments on commit a151815

Please sign in to comment.