File tree Expand file tree Collapse file tree 4 files changed +139
-0
lines changed Expand file tree Collapse file tree 4 files changed +139
-0
lines changed Original file line number Diff line number Diff line change 1212 - PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule
1313 - PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule
1414 - PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule
15+ - PHPStan\Rules\Cast\UselessCastRule
1516 - PHPStan\Rules\DisallowedConstructs\DisallowedEmptyRule
1617 - PHPStan\Rules\DisallowedConstructs\DisallowedImplicitArrayCreationRule
1718 - PHPStan\Rules\Functions\MissingFunctionParameterTypehintRule
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types = 1 );
2+
3+ namespace PHPStan \Rules \Cast ;
4+
5+ use PhpParser \Node ;
6+ use PhpParser \Node \Expr \Cast ;
7+ use PHPStan \Analyser \Scope ;
8+ use PHPStan \Type \ErrorType ;
9+ use PHPStan \Type \TypeUtils ;
10+ use PHPStan \Type \VerbosityLevel ;
11+
12+ class UselessCastRule implements \PHPStan \Rules \Rule
13+ {
14+
15+ public function getNodeType (): string
16+ {
17+ return Cast::class;
18+ }
19+
20+ /**
21+ * @param \PhpParser\Node\Expr\Cast $node
22+ * @param \PHPStan\Analyser\Scope $scope
23+ * @return string[] errors
24+ */
25+ public function processNode (Node $ node , Scope $ scope ): array
26+ {
27+ $ castType = $ scope ->getType ($ node );
28+ if ($ castType instanceof ErrorType) {
29+ return [];
30+ }
31+ $ castType = TypeUtils::generalizeType ($ castType );
32+
33+ $ expressionType = $ scope ->getType ($ node ->expr );
34+ if ($ castType ->isSuperTypeOf ($ expressionType )->yes ()) {
35+ return [
36+ sprintf (
37+ 'Casting to %s something that \'s already %s. ' ,
38+ $ castType ->describe (VerbosityLevel::typeOnly ()),
39+ $ expressionType ->describe (VerbosityLevel::typeOnly ())
40+ ),
41+ ];
42+ }
43+
44+ return [];
45+ }
46+
47+ }
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types = 1 );
2+
3+ namespace PHPStan \Rules \Cast ;
4+
5+ class UselessCastRuleTest extends \PHPStan \Testing \RuleTestCase
6+ {
7+
8+ protected function getRule (): \PHPStan \Rules \Rule
9+ {
10+ return new UselessCastRule ();
11+ }
12+
13+ public function testUselessCast (): void
14+ {
15+ require_once __DIR__ . '/data/useless-cast.php ' ;
16+ $ this ->analyse (
17+ [__DIR__ . '/data/useless-cast.php ' ],
18+ [
19+ [
20+ 'Casting to int something that \'s already int. ' ,
21+ 7 ,
22+ ],
23+ [
24+ 'Casting to string something that \'s already string. ' ,
25+ 9 ,
26+ ],
27+ [
28+ 'Casting to stdClass something that \'s already stdClass. ' ,
29+ 10 ,
30+ ],
31+ [
32+ 'Casting to float something that \'s already float. ' ,
33+ 27 ,
34+ ],
35+ [
36+ 'Casting to string something that \'s already string. ' ,
37+ 46 ,
38+ ],
39+ ]
40+ );
41+ }
42+
43+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace UselessCast ;
4+
5+ function () {
6+ $ foo = (int ) '5 ' ;
7+ $ foo = (int ) 5 ;
8+ $ foo = (string ) 5 ;
9+ $ foo = (string ) '5 ' ;
10+ $ foo = (object ) new \stdClass ();
11+
12+ /** @var string|null $nullableString */
13+ $ nullableString = 'foo ' ;
14+ $ foo = (string ) $ nullableString ;
15+
16+ $ foo = (float ) (6 / 2 );
17+
18+ $ width = 1 ;
19+ $ scale = 2.0 ;
20+ $ width *= $ scale ;
21+ echo (int ) $ width ;
22+
23+ /** @var string|mixed $stringOrMixed */
24+ $ stringOrMixed = doFoo ();
25+ (string ) $ stringOrMixed ;
26+
27+ $ foo = (float ) (100.0 / 25.432 );
28+
29+ (int ) "blabla " ;
30+ };
31+
32+ function foo (string &$ input ) {
33+ $ input = 1 ;
34+ }
35+
36+ function () {
37+ $ s = '' ;
38+ foo ($ s );
39+ (string ) $ s ;
40+ };
41+
42+ function () {
43+ /** @var int|string $s */
44+ $ s = doFoo ();
45+ if (!is_numeric ($ s )) {
46+ (string ) $ s ;
47+ }
48+ };
You can’t perform that action at this time.
0 commit comments