Skip to content

Commit 545c353

Browse files
authored
[Php81] Skip Closure bindTo on FunctionLikeToFirstClassCallableRector (#7581)
1 parent a4b87e6 commit 545c353

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FunctionLike\FunctionLikeToFirstClassCallableRector\Fixture;
4+
5+
class SkipClosureBindTo
6+
{
7+
public static function close(): void
8+
{
9+
}
10+
}
11+
12+
function testClosureBindTo(callable $cb): void
13+
{
14+
if ($cb instanceof \Closure) {
15+
$testInstance = new class {
16+
public function describe() { }
17+
};
18+
19+
$cb = $cb->bindTo($testInstance, get_class($testInstance));
20+
}
21+
22+
$cb();
23+
}
24+
25+
testClosureBindTo(fn () => SkipClosureBindTo::close());

rules/CodingStyle/Rector/FunctionLike/FunctionLikeToFirstClassCallableRector.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use PHPStan\Reflection\Annotations\AnnotationMethodReflection;
2727
use PHPStan\Reflection\ResolvedFunctionVariantWithOriginal;
2828
use PHPStan\Type\CallableType;
29+
use PHPStan\Type\ObjectType;
2930
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
3031
use Rector\PhpParser\AstResolver;
3132
use Rector\PhpParser\Node\BetterNodeFinder;
@@ -157,6 +158,38 @@ public function refactor(Node $node): null|CallLike
157158
$args[$key]->value->setAttribute(self::HAS_CALLBACK_SIGNATURE_MULTI_PARAMS, true);
158159
return null;
159160
}
161+
162+
$isClosureBindTo = (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped(
163+
$classMethodOrFunction,
164+
function (Node $node) use ($parameterName): bool {
165+
if (! $node instanceof MethodCall) {
166+
return false;
167+
}
168+
169+
if (! $node->name instanceof Identifier) {
170+
return false;
171+
}
172+
173+
if (! $this->isName($node->name, 'bindTo')) {
174+
return false;
175+
}
176+
177+
if (! $node->var instanceof Variable) {
178+
return false;
179+
}
180+
181+
if (! $this->isObjectType($node->var, new ObjectType('Closure'))) {
182+
return false;
183+
}
184+
185+
return $this->isName($node->var, $parameterName);
186+
}
187+
);
188+
189+
if ($isClosureBindTo) {
190+
$args[$key]->value->setAttribute(self::HAS_CALLBACK_SIGNATURE_MULTI_PARAMS, true);
191+
return null;
192+
}
160193
}
161194
}
162195
}

0 commit comments

Comments
 (0)