File tree Expand file tree Collapse file tree 4 files changed +119
-0
lines changed
src/Rules/SwitchConditions
tests/Rules/SwitchConditions Expand file tree Collapse file tree 4 files changed +119
-0
lines changed Original file line number Diff line number Diff line change @@ -36,3 +36,8 @@ services:
3636 class : PHPStan\Rules\StrictCalls\StrictFunctionCallsRule
3737 tags :
3838 - phpstan.rules.rule
39+
40+ -
41+ class : PHPStan\Rules\SwitchConditions\MatchingTypeInSwitchCaseConditionRule
42+ tags :
43+ - phpstan.rules.rule
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types = 1 );
2+
3+ namespace PHPStan \Rules \SwitchConditions ;
4+
5+ class MatchingTypeInSwitchCaseConditionRule implements \PHPStan \Rules \Rule
6+ {
7+
8+ /** @var \PhpParser\PrettyPrinter\Standard */
9+ private $ printer ;
10+
11+ public function __construct (\PhpParser \PrettyPrinter \Standard $ printer )
12+ {
13+ $ this ->printer = $ printer ;
14+ }
15+
16+ public function getNodeType (): string
17+ {
18+ return \PhpParser \Node \Stmt \Switch_::class;
19+ }
20+
21+ /**
22+ * @param \PhpParser\Node\Stmt\Switch_ $node
23+ * @param \PHPStan\Analyser\Scope $scope
24+ * @return string[] errors
25+ */
26+ public function processNode (\PhpParser \Node $ node , \PHPStan \Analyser \Scope $ scope ): array
27+ {
28+ $ messages = [];
29+ $ conditionType = $ scope ->getType ($ node ->cond );
30+ foreach ($ node ->cases as $ case ) {
31+ if ($ case ->cond === null ) {
32+ continue ;
33+ }
34+
35+ $ caseType = $ scope ->getType ($ case ->cond );
36+ if ($ conditionType ->isSupersetOf ($ caseType )->no ()) {
37+ $ messages [] = sprintf (
38+ 'Switch condition type (%s) does not match case condition %s (%s). ' ,
39+ $ conditionType ->describe (),
40+ $ this ->printer ->prettyPrintExpr ($ case ->cond ),
41+ $ caseType ->describe ()
42+ );
43+ }
44+ }
45+
46+ return $ messages ;
47+ }
48+
49+ }
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types = 1 );
2+
3+ namespace PHPStan \Rules \SwitchConditions ;
4+
5+ use PHPStan \Rules \Rule ;
6+
7+ class MatchingTypeInSwitchCaseConditionRuleTest extends \PHPStan \Testing \RuleTestCase
8+ {
9+
10+ protected function getRule (): Rule
11+ {
12+ return new MatchingTypeInSwitchCaseConditionRule (new \PhpParser \PrettyPrinter \Standard ());
13+ }
14+
15+ public function testRule ()
16+ {
17+ $ this ->analyse ([__DIR__ . '/data/matching-type.php ' ], [
18+ [
19+ 'Switch condition type (int) does not match case condition \'test \' (string). ' ,
20+ 8 ,
21+ ],
22+ [
23+ 'Switch condition type (int) does not match case condition 1 > 2 (bool). ' ,
24+ 8 ,
25+ ],
26+ [
27+ 'Switch condition type (string) does not match case condition 1 (int). ' ,
28+ 19 ,
29+ ],
30+ [
31+ 'Switch condition type (string) does not match case condition 1 > 2 (bool). ' ,
32+ 19 ,
33+ ],
34+ ]);
35+ }
36+
37+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace SwitchConditions ;
4+
5+ $ int = 1 ;
6+ $ string = '1 ' ;
7+
8+ switch ($ int ) {
9+ case 1 :
10+ break ;
11+ case 'test ' :
12+ break ;
13+ case 1 > 2 :
14+ break ;
15+ default :
16+ return ;
17+ }
18+
19+ switch ($ string ) {
20+ case 1 :
21+ break ;
22+ case 'test ' :
23+ break ;
24+ case 1 > 2 :
25+ break ;
26+ default :
27+ return ;
28+ }
You can’t perform that action at this time.
0 commit comments