diff --git a/rules-tests/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector/Fixture/skip_used_by_array_callable.php.inc b/rules-tests/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector/Fixture/skip_used_by_array_callable.php.inc new file mode 100644 index 00000000000..0797ec21dc9 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector/Fixture/skip_used_by_array_callable.php.inc @@ -0,0 +1,19 @@ + $b; + } + + public static function foo(): void + { + $array = []; + usort($array, [self::class, 'bar']); + } +} diff --git a/rules/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector.php b/rules/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector.php index 0b68b94a1c5..25203d33154 100644 --- a/rules/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/LocallyCalledStaticMethodToNonStaticRector.php @@ -5,6 +5,7 @@ namespace Rector\CodeQuality\Rector\ClassMethod; use PhpParser\Node; +use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrowFunction; use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\MethodCall; @@ -13,7 +14,10 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\NodeVisitor; +use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; +use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher; +use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Privatization\NodeManipulator\VisibilityManipulator; use Rector\Privatization\VisibilityGuard\ClassMethodVisibilityGuard; use Rector\Rector\AbstractRector; @@ -29,7 +33,8 @@ final class LocallyCalledStaticMethodToNonStaticRector extends AbstractRector public function __construct( private readonly ClassMethodVisibilityGuard $classMethodVisibilityGuard, private readonly VisibilityManipulator $visibilityManipulator, - private readonly ReflectionResolver $reflectionResolver + private readonly ReflectionResolver $reflectionResolver, + private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher ) { } @@ -217,6 +222,18 @@ private function isClassMethodCalledInAnotherStaticClassMethod(Class_ $class, Cl $currentClassMethodName, &$isInsideStaticClassMethod ): ?int { + if ($node instanceof Array_) { + $scope = $node->getAttribute(AttributeKey::SCOPE); + if ($scope instanceof Scope && $this->arrayCallableMethodMatcher->match( + $node, + $scope, + $currentClassMethodName + )) { + $isInsideStaticClassMethod = true; + return NodeVisitor::STOP_TRAVERSAL; + } + } + if (! $node instanceof StaticCall) { return null; }