diff --git a/rules-tests/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector/Fixture/skip_closure_bind_to.php.inc b/rules-tests/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector/Fixture/skip_closure_bind_to.php.inc new file mode 100644 index 00000000000..47d35b3645f --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector/Fixture/skip_closure_bind_to.php.inc @@ -0,0 +1,25 @@ +bindTo($testInstance, get_class($testInstance)); + } + + $cb(); +} + +testClosureBindTo(fn () => SkipClosureBindTo::close()); diff --git a/rules/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector.php b/rules/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector.php index ddb2da03a16..2842325507d 100644 --- a/rules/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector.php +++ b/rules/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector.php @@ -26,6 +26,7 @@ use PHPStan\Reflection\Annotations\AnnotationMethodReflection; use PHPStan\Reflection\ResolvedFunctionVariantWithOriginal; use PHPStan\Type\CallableType; +use PHPStan\Type\ObjectType; use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\PhpParser\AstResolver; use Rector\PhpParser\Node\BetterNodeFinder; @@ -157,6 +158,38 @@ public function refactor(Node $node): null|CallLike $args[$key]->value->setAttribute(self::HAS_CALLBACK_SIGNATURE_MULTI_PARAMS, true); return null; } + + $isClosureBindTo = (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped( + $classMethodOrFunction, + function (Node $node) use ($parameterName): bool { + if (! $node instanceof MethodCall) { + return false; + } + + if (! $node->name instanceof Identifier) { + return false; + } + + if (! $this->isName($node->name, 'bindTo')) { + return false; + } + + if (! $node->var instanceof Variable) { + return false; + } + + if (! $this->isObjectType($node->var, new ObjectType('Closure'))) { + return false; + } + + return $this->isName($node->var, $parameterName); + } + ); + + if ($isClosureBindTo) { + $args[$key]->value->setAttribute(self::HAS_CALLBACK_SIGNATURE_MULTI_PARAMS, true); + return null; + } } } }