Skip to content

Commit ba80a4c

Browse files
committed
[Fix] Detect components with return statement in switch/case
Fixes #2118
1 parent 2f5cec9 commit ba80a4c

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

lib/util/ast.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,21 @@ function findReturnStatement(node) {
1818

1919
const bodyNodes = (node.value ? node.value.body.body : node.body.body);
2020

21-
let i = bodyNodes.length - 1;
22-
for (; i >= 0; i--) {
23-
if (bodyNodes[i].type === 'ReturnStatement') {
24-
return bodyNodes[i];
21+
return (function loopNodes(nodes) {
22+
let i = nodes.length - 1;
23+
for (; i >= 0; i--) {
24+
if (nodes[i].type === 'ReturnStatement') {
25+
return nodes[i];
26+
}
27+
if (nodes[i].type === 'SwitchStatement') {
28+
let j = nodes[i].cases.length - 1;
29+
for (; j >= 0; j--) {
30+
return loopNodes(nodes[i].cases[j].consequent);
31+
}
32+
}
2533
}
26-
}
27-
return false;
34+
return false;
35+
}(bodyNodes));
2836
}
2937

3038
/**

tests/lib/rules/no-unused-prop-types.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,6 +4961,30 @@ ruleTester.run('no-unused-prop-types', rule, {
49614961
errors: [{
49624962
message: '\'person.lastname\' PropType is defined but prop is never used'
49634963
}]
4964+
}, {
4965+
code: `
4966+
import PropTypes from 'prop-types';
4967+
import React from 'react';
4968+
4969+
const MyComponent= (props) => {
4970+
switch (props.usedProp) {
4971+
case 1:
4972+
return (<div />);
4973+
default:
4974+
return <div />;
4975+
}
4976+
};
4977+
4978+
MyComponent.propTypes = {
4979+
usedProp: PropTypes.string,
4980+
unUsedProp: PropTypes.string,
4981+
};
4982+
4983+
export default MyComponent;
4984+
`,
4985+
errors: [{
4986+
message: '\'unUsedProp\' PropType is defined but prop is never used'
4987+
}]
49644988
}
49654989

49664990
/* , {

tests/lib/rules/prop-types.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4334,6 +4334,25 @@ ruleTester.run('prop-types', rule, {
43344334
errors: [{
43354335
message: '\'text\' is missing in props validation'
43364336
}]
4337+
}, {
4338+
code: `
4339+
import PropTypes from 'prop-types';
4340+
import React from 'react';
4341+
4342+
const MyComponent = (props) => {
4343+
switch (props.usedProp) {
4344+
case 1:
4345+
return (<div />);
4346+
default:
4347+
return <div />;
4348+
}
4349+
};
4350+
4351+
export default MyComponent;
4352+
`,
4353+
errors: [{
4354+
message: '\'usedProp\' is missing in props validation'
4355+
}]
43374356
}
43384357
]
43394358
});

tests/lib/rules/require-default-props.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,29 @@ ruleTester.run('require-default-props', rule, {
21992199
errors: [{
22002200
message: 'propType "name" is not required, but has no corresponding defaultProps declaration.'
22012201
}]
2202+
}, {
2203+
code: `
2204+
import PropTypes from 'prop-types';
2205+
import React from 'react';
2206+
2207+
const MyComponent= (props) => {
2208+
switch (props.usedProp) {
2209+
case 1:
2210+
return (<div />);
2211+
default:
2212+
return <div />;
2213+
}
2214+
};
2215+
2216+
MyComponent.propTypes = {
2217+
usedProp: PropTypes.string,
2218+
};
2219+
2220+
export default MyComponent;
2221+
`,
2222+
errors: [{
2223+
message: 'propType "usedProp" is not required, but has no corresponding defaultProps declaration.'
2224+
}]
22022225
}
22032226
]
22042227
});

0 commit comments

Comments
 (0)