Skip to content

Commit b68824a

Browse files
authored
[DeadCode] Skip used by Array callable on RemoveEmptyClassMethodRector (#6908)
1 parent 7db2d51 commit b68824a

3 files changed

Lines changed: 49 additions & 4 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector\Fixture;
4+
5+
use Rector\Tests\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector\Source\MyDIContainer;
6+
7+
final class SkipUsedByArrayCallable
8+
{
9+
public function run()
10+
{
11+
$container = new MyDIContainer();
12+
$container->call([$this, 'doFoo']);
13+
}
14+
15+
public function doFoo() {
16+
}
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector\Source;
6+
7+
class MyDIContainer
8+
{
9+
public function call(callable $callback, array $parameters = []): mixed
10+
{
11+
}
12+
}

rules/DeadCode/Rector/ClassMethod/RemoveEmptyClassMethodRector.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Rector\DeadCode\Rector\ClassMethod;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Expr\Array_;
89
use PhpParser\Node\Expr\MethodCall;
910
use PhpParser\Node\Expr\Variable;
1011
use PhpParser\Node\Name\FullyQualified;
@@ -15,8 +16,10 @@
1516
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
1617
use Rector\DeadCode\NodeManipulator\ControllerClassMethodManipulator;
1718
use Rector\NodeAnalyzer\ParamAnalyzer;
19+
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
1820
use Rector\NodeManipulator\ClassMethodManipulator;
1921
use Rector\PhpParser\Node\BetterNodeFinder;
22+
use Rector\PHPStan\ScopeFetcher;
2023
use Rector\Rector\AbstractRector;
2124
use Rector\ValueObject\MethodName;
2225
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -32,7 +35,8 @@ public function __construct(
3235
private readonly ControllerClassMethodManipulator $controllerClassMethodManipulator,
3336
private readonly ParamAnalyzer $paramAnalyzer,
3437
private readonly PhpDocInfoFactory $phpDocInfoFactory,
35-
private readonly BetterNodeFinder $betterNodeFinder
38+
private readonly BetterNodeFinder $betterNodeFinder,
39+
private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher
3640
) {
3741
}
3842

@@ -132,14 +136,15 @@ private function shouldSkipNonFinalNonPrivateClassMethod(Class_ $class, ClassMet
132136
private function shouldSkipClassMethod(Class_ $class, ClassMethod $classMethod): bool
133137
{
134138
$desiredClassMethodName = $this->getName($classMethod);
139+
$className = (string) $this->getName($class);
135140

136141
// is method called somewhere else in the class?
137142
foreach ($class->getMethods() as $anotherClassMethod) {
138143
if ($anotherClassMethod === $classMethod) {
139144
continue;
140145
}
141146

142-
if ($this->containsMethodCall($anotherClassMethod, $desiredClassMethodName)) {
147+
if ($this->containsMethodCallOrArrayCallable($anotherClassMethod, $desiredClassMethodName, $className)) {
143148
return true;
144149
}
145150
}
@@ -182,11 +187,22 @@ private function hasDeprecatedAnnotation(ClassMethod $classMethod): bool
182187
return $phpDocInfo->hasByType(DeprecatedTagValueNode::class);
183188
}
184189

185-
private function containsMethodCall(ClassMethod $anotherClassMethod, string $desiredClassMethodName): bool
190+
private function containsMethodCallOrArrayCallable(ClassMethod $anotherClassMethod, string $desiredClassMethodName, string $className): bool
186191
{
192+
$scope = ScopeFetcher::fetch($anotherClassMethod);
187193
return (bool) $this->betterNodeFinder->findFirst($anotherClassMethod, function (Node $node) use (
188-
$desiredClassMethodName
194+
$desiredClassMethodName,
195+
$className,
196+
$scope
189197
): bool {
198+
if ($node instanceof Array_) {
199+
return (bool) $this->arrayCallableMethodMatcher->match(
200+
$node,
201+
$scope,
202+
$className
203+
);
204+
}
205+
190206
if (! $node instanceof MethodCall) {
191207
return false;
192208
}

0 commit comments

Comments
 (0)