mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-08 12:20:52 +00:00
Fix AnonymousFunctionFactory for class constant reference (#552)
Co-authored-by: Abdul Malik Ikhsan <samsonasik@gmail.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
59d63d6f4a
commit
057c5e6853
|
@ -28,7 +28,7 @@ final class SomeStaticCall
|
|||
public function run(array $values)
|
||||
{
|
||||
usort($values, function (int $first, $second) : bool {
|
||||
return SomeStaticCall::compareSize($first, $second);
|
||||
return \Rector\Tests\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector\Fixture\SomeStaticCall::compareSize($first, $second);
|
||||
});
|
||||
|
||||
return $values;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Php72\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector\Fixture
|
||||
{
|
||||
final class FqnClassReference
|
||||
{
|
||||
public function handle(): void {}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
doFoo([\Rector\Tests\Php72\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector\Fixture\FqnClassReference::class, 'handle']);
|
||||
|
||||
function doFoo($method): void
|
||||
{
|
||||
}
|
||||
}
|
|
@ -13,10 +13,12 @@ use PhpParser\Node\Expr\ClassConstFetch;
|
|||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\ClosureUse;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
|
@ -85,7 +87,7 @@ final class AnonymousFunctionFactory
|
|||
return $anonymousFunctionNode;
|
||||
}
|
||||
|
||||
public function createFromPhpMethodReflection(PhpMethodReflection $phpMethodReflection, Expr $expr): Closure
|
||||
public function createFromPhpMethodReflection(PhpMethodReflection $phpMethodReflection, Expr $expr): ?Closure
|
||||
{
|
||||
/** @var FunctionVariantWithPhpDocs $functionVariantWithPhpDoc */
|
||||
$functionVariantWithPhpDoc = ParametersAcceptorSelector::selectSingle($phpMethodReflection->getVariants());
|
||||
|
@ -95,20 +97,11 @@ final class AnonymousFunctionFactory
|
|||
|
||||
$anonymousFunction->params = $newParams;
|
||||
|
||||
if ($expr instanceof ClassConstFetch && $expr->name instanceof Identifier && $this->nodeNameResolver->isName(
|
||||
$expr->name,
|
||||
'class'
|
||||
)) {
|
||||
/** @var Expr $expr */
|
||||
$expr = $expr->class;
|
||||
$innerMethodCall = $this->createInnerMethodCall($phpMethodReflection, $expr, $newParams);
|
||||
if ($innerMethodCall === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$innerMethodCall = $phpMethodReflection->isStatic()
|
||||
? new StaticCall($expr, $phpMethodReflection->getName())
|
||||
: new MethodCall($expr, $phpMethodReflection->getName());
|
||||
|
||||
$innerMethodCall->args = $this->nodeFactory->createArgsFromParams($newParams);
|
||||
|
||||
if (! $functionVariantWithPhpDoc->getReturnType() instanceof MixedType) {
|
||||
$returnType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode(
|
||||
$functionVariantWithPhpDoc->getReturnType(),
|
||||
|
@ -118,7 +111,6 @@ final class AnonymousFunctionFactory
|
|||
}
|
||||
|
||||
// does method return something?
|
||||
|
||||
if (! $functionVariantWithPhpDoc->getReturnType() instanceof VoidType) {
|
||||
$anonymousFunction->stmts[] = new Return_($innerMethodCall);
|
||||
} else {
|
||||
|
@ -241,4 +233,71 @@ final class AnonymousFunctionFactory
|
|||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Param[] $params
|
||||
*/
|
||||
private function createInnerMethodCall(
|
||||
PhpMethodReflection $phpMethodReflection,
|
||||
Expr $expr,
|
||||
array $params
|
||||
): MethodCall | StaticCall | null {
|
||||
if ($phpMethodReflection->isStatic()) {
|
||||
$expr = $this->normalizeClassConstFetchForStatic($expr);
|
||||
if ($expr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$innerMethodCall = new StaticCall($expr, $phpMethodReflection->getName());
|
||||
} else {
|
||||
$expr = $this->resolveExpr($expr);
|
||||
if (! $expr instanceof Expr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$innerMethodCall = new MethodCall($expr, $phpMethodReflection->getName());
|
||||
}
|
||||
|
||||
$innerMethodCall->args = $this->nodeFactory->createArgsFromParams($params);
|
||||
|
||||
return $innerMethodCall;
|
||||
}
|
||||
|
||||
private function normalizeClassConstFetchForStatic(Expr $expr): null | FullyQualified | Expr
|
||||
{
|
||||
if (! $expr instanceof ClassConstFetch) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isName($expr->name, 'class')) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
// dynamic name, nothing we can do
|
||||
$className = $this->nodeNameResolver->getName($expr->class);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new FullyQualified($className);
|
||||
}
|
||||
|
||||
private function resolveExpr(Expr $expr): New_ | Expr | null
|
||||
{
|
||||
if (! $expr instanceof ClassConstFetch) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isName($expr->name, 'class')) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
// dynamic name, nothing we can do
|
||||
$className = $this->nodeNameResolver->getName($expr->class);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new New_(new FullyQualified($className));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user