[Defluent] Skip clone uses trait on DefluentReturnMethodCallRector (#558)

* [Defluent] Skip clone uses trait on DefluentReturnMethodCallRector

* debug

* Fixed 🎉

* phpstan

* final touch

* revert return null on parseFileNameToDecoratedNodes()

* phpstan

* phpstan

* phpstan

* phpstan
This commit is contained in:
Abdul Malik Ikhsan 2021-08-01 23:50:05 +07:00 committed by GitHub
parent 0a30f6f7ee
commit b34ff8ca13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 1 deletions

View File

@ -0,0 +1,13 @@
<?php
namespace Rector\Tests\Defluent\Rector\Return_\DefluentReturnMethodCallRector\Fixture;
use Rector\Tests\Defluent\Rector\Return_\DefluentReturnMethodCallRector\Source\UsesTrait;
final class SkipCloneObjectAssignUseTrait
{
public function run(UsesTrait $usesTrait)
{
return $usesTrait->withStatus(500);
}
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Defluent\Rector\Return_\DefluentReturnMethodCallRector\Source;
trait SelfButCloneAssignVersionTrait
{
public $status;
public function withStatus($status): self
{
$self = clone $this;
$self->status = $status;
return $self;
}
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Defluent\Rector\Return_\DefluentReturnMethodCallRector\Source;
class UsesTrait
{
use SelfButCloneAssignVersionTrait;
}

View File

@ -199,7 +199,13 @@ final class AstResolver
return null;
}
return $this->resolveClassMethodFromMethodReflection($methodReflection);
$classMethod = $this->resolveClassMethodFromMethodReflection($methodReflection);
if (! $classMethod instanceof ClassMethod) {
return $this->locateClassMethodInTrait($methodName, $methodReflection);
}
return $classMethod;
}
public function resolveClassMethodFromMethodCall(MethodCall $methodCall): ?ClassMethod
@ -340,6 +346,21 @@ final class AstResolver
return $this->findPromotedPropertyByName($nodes, $desiredPropertyName);
}
private function locateClassMethodInTrait(string $methodName, MethodReflection $methodReflection): ?ClassMethod
{
$classReflection = $methodReflection->getDeclaringClass();
$traits = $this->parseClassReflectionTraits($classReflection);
/** @var ClassMethod|null $classMethod */
$classMethod = $this->betterNodeFinder->findFirst(
$traits,
fn (Node $node): bool => $node instanceof ClassMethod && $this->nodeNameResolver->isName($node, $methodName)
);
$this->classMethodsByClassAndMethod[$classReflection->getName()][$methodName] = $classMethod;
return $classMethod;
}
/**
* @return Stmt[]|null
*/