Skip to content

Commit

Permalink
[Fix] forbid-prop-types: warn on destructured values as well
Browse files Browse the repository at this point in the history
Fixes #2662.

Co-authored-by: Alex Kovar <ajkovar@gmail.com>
Co-authored-by: Jordan Harband <ljharb@gmail.com>
  • Loading branch information
ajkovar and ljharb committed Jun 16, 2020
1 parent a4025bd commit 319722f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 24 deletions.
32 changes: 22 additions & 10 deletions lib/rules/forbid-prop-types.js
Expand Up @@ -59,6 +59,15 @@ module.exports = {
return forbid.indexOf(type) >= 0;
}

function reportIfForbidden(type, declaration, target) {
if (isForbidden(type)) {
context.report({
node: declaration,
message: `Prop type \`${target}\` is forbidden`
});
}
}

function shouldCheckContextTypes(node) {
if (checkContextTypes && propsUtil.isContextTypesDeclaration(node)) {
return true;
Expand Down Expand Up @@ -93,23 +102,18 @@ module.exports = {
) {
value = value.object;
}
if (
value.type === 'CallExpression'
&& value.callee.type === 'MemberExpression'
) {
if (value.type === 'CallExpression') {
value.arguments.forEach((arg) => {
reportIfForbidden(arg.name, declaration, target);
});
value = value.callee;
}
if (value.property) {
target = value.property.name;
} else if (value.type === 'Identifier') {
target = value.name;
}
if (isForbidden(target)) {
context.report({
node: declaration,
message: `Prop type \`${target}\` is forbidden`
});
}
reportIfForbidden(target, declaration, target);
});
}

Expand Down Expand Up @@ -161,6 +165,14 @@ module.exports = {
checkNode(node.parent.right);
},

CallExpression(node) {
if ((node.callee.name === 'shape'
|| astUtil.getPropertyName(node.callee) === 'shape')
&& node.arguments.length > 0) {
checkProperties(node.arguments[0].properties);
}
},

MethodDefinition(node) {
if (
!propsUtil.isPropTypesDeclaration(node)
Expand Down
95 changes: 81 additions & 14 deletions tests/lib/rules/forbid-prop-types.js
Expand Up @@ -572,20 +572,6 @@ ruleTester.run('forbid-prop-types', rule, {
' preview: PropTypes.bool,',
'}, componentApi, teaserListProps);'
].join('\n')
}, {
code: [
'var First = createReactClass({',
' propTypes: {',
' s: PropTypes.shape({',
' o: PropTypes.object',
' })',
' },',
' render: function() {',
' return <div />;',
' }',
'});'
].join('\n'),
errors: 0 // TODO: fix #1673 and move this to "invalid"
}],

invalid: [{
Expand Down Expand Up @@ -1460,5 +1446,86 @@ ruleTester.run('forbid-prop-types', rule, {
checkChildContextTypes: true
}],
errors: 1
}, {
code: [
'import { object, string } from "prop-types";',
'function C({ a, b }) { return [a, b]; }',
'C.propTypes = {',
' a: object,',
' b: string',
'};'
].join('\n'),
options: [{
forbid: ['object']
}],
errors: 1
}, {
code: [
'import { objectOf, any } from "prop-types";',
'function C({ a }) { return a; }',
'C.propTypes = {',
' a: objectOf(any)',
'};'
].join('\n'),
options: [{
forbid: ['any']
}],
errors: 1
}, {
code: [
'import { objectOf, any } from "prop-types";',
'function C({ a }) { return a; }',
'C.propTypes = {',
' a: objectOf(any)',
'};'
].join('\n'),
options: [{
forbid: ['objectOf']
}],
errors: 1
},
{
code: [
'import { shape, any } from "prop-types";',
'function C({ a }) { return a; }',
'C.propTypes = {',
' a: shape({',
' b: any',
' })',
'};'
].join('\n'),
options: [{
forbid: ['any']
}],
errors: 1
},
{
code: [
'import { any } from "prop-types";',
'function C({ a }) { return a; }',
'C.propTypes = {',
' a: PropTypes.shape({',
' b: any',
' })',
'};'
].join('\n'),
options: [{
forbid: ['any']
}],
errors: 1
}, {
code: [
'var First = createReactClass({',
' propTypes: {',
' s: PropTypes.shape({',
' o: PropTypes.object',
' })',
' },',
' render: function() {',
' return <div />;',
' }',
'});'
].join('\n'),
errors: 1
}]
});

0 comments on commit 319722f

Please sign in to comment.