Skip to content

Commit 712aa81

Browse files
authored
Proper nullsafe call chain support (#46)
1 parent 477bea3 commit 712aa81

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/Collector/MethodCallCollector.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PHPStan\Reflection\ClassReflection;
2222
use PHPStan\Reflection\ReflectionProvider;
2323
use PHPStan\Type\Type;
24+
use PHPStan\Type\TypeCombinator;
2425
use ShipMonk\PHPStan\DeadCode\Helper\DeadCodeHelper;
2526

2627
/**
@@ -200,7 +201,9 @@ private function getMethodName(CallLike $call): ?string
200201
*/
201202
private function getReflectionsWithMethod(Type $type, string $methodName): iterable
202203
{
203-
$classReflections = $type->getObjectTypeOrClassStringObjectType()->getObjectClassReflections();
204+
// remove null to support nullsafe calls
205+
$typeNoNull = TypeCombinator::removeNull($type);
206+
$classReflections = $typeNoNull->getObjectTypeOrClassStringObjectType()->getObjectClassReflections();
204207

205208
foreach ($classReflections as $classReflection) {
206209
if ($classReflection->hasMethod($methodName)) {

tests/Rule/DeadMethodRuleTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public static function provideFiles(): iterable
8787
yield 'trait-1' => [__DIR__ . '/data/DeadMethodRule/traits-1.php'];
8888
yield 'trait-2' => [__DIR__ . '/data/DeadMethodRule/traits-2.php'];
8989
yield 'trait-3' => [__DIR__ . '/data/DeadMethodRule/traits-3.php'];
90+
yield 'nullsafe' => [__DIR__ . '/data/DeadMethodRule/nullsafe.php'];
9091
yield 'dead-in-parent-1' => [__DIR__ . '/data/DeadMethodRule/dead-in-parent-1.php'];
9192
yield 'indirect-interface' => [__DIR__ . '/data/DeadMethodRule/indirect-interface.php'];
9293
yield 'attribute' => [__DIR__ . '/data/DeadMethodRule/attribute.php'];
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Nullsafe;
4+
5+
class A {
6+
7+
public function first(): self {
8+
return $this;
9+
}
10+
11+
public function second(): self {
12+
return $this;
13+
}
14+
15+
public static function secondStatic(): self {
16+
return new self();
17+
}
18+
}
19+
20+
class B {
21+
22+
public function test(?A $a): void
23+
{
24+
$a?->first()->second();
25+
$a?->first()::secondStatic();
26+
}
27+
}
28+
29+
(new B())->test(null);

0 commit comments

Comments
 (0)