mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-25 04:12:36 +00:00
Failing test: Node type is not updated after executing rector (#6255)
Co-authored-by: Michal Lulco <lulco@efabrica.sk>
This commit is contained in:
parent
a5a99317b7
commit
cf9d8c202d
|
@ -38,6 +38,7 @@ use PHPStan\Type\Type;
|
|||
use PHPStan\Type\TypeCombinator;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Configuration\RenamedClassesDataCollector;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
|
||||
|
@ -91,6 +92,11 @@ final class NodeTypeResolver
|
|||
*/
|
||||
private $identifierTypeResolver;
|
||||
|
||||
/**
|
||||
* @var RenamedClassesDataCollector
|
||||
*/
|
||||
private $renamedClassesDataCollector;
|
||||
|
||||
/**
|
||||
* @param NodeTypeResolverInterface[] $nodeTypeResolvers
|
||||
*/
|
||||
|
@ -101,6 +107,7 @@ final class NodeTypeResolver
|
|||
ReflectionProvider $reflectionProvider,
|
||||
HasOffsetTypeCorrector $hasOffsetTypeCorrector,
|
||||
IdentifierTypeResolver $identifierTypeResolver,
|
||||
RenamedClassesDataCollector $renamedClassesDataCollector,
|
||||
array $nodeTypeResolvers
|
||||
) {
|
||||
foreach ($nodeTypeResolvers as $nodeTypeResolver) {
|
||||
|
@ -113,6 +120,7 @@ final class NodeTypeResolver
|
|||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->hasOffsetTypeCorrector = $hasOffsetTypeCorrector;
|
||||
$this->identifierTypeResolver = $identifierTypeResolver;
|
||||
$this->renamedClassesDataCollector = $renamedClassesDataCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,7 +154,6 @@ final class NodeTypeResolver
|
|||
}
|
||||
|
||||
$resolvedType = $this->resolve($node);
|
||||
|
||||
if ($resolvedType instanceof MixedType) {
|
||||
return false;
|
||||
}
|
||||
|
@ -156,7 +163,7 @@ final class NodeTypeResolver
|
|||
}
|
||||
|
||||
if ($resolvedType instanceof ObjectType) {
|
||||
return $this->isObjectTypeOfObjectType($resolvedType, $requiredObjectType);
|
||||
return $this->resolveObjectType($resolvedType, $requiredObjectType);
|
||||
}
|
||||
|
||||
return $this->isMatchingUnionType($resolvedType, $requiredObjectType);
|
||||
|
@ -438,7 +445,7 @@ final class NodeTypeResolver
|
|||
private function resolveByNodeTypeResolvers(Node $node): ?Type
|
||||
{
|
||||
foreach ($this->nodeTypeResolvers as $nodeClass => $nodeTypeResolver) {
|
||||
if (! is_a($node, $nodeClass)) {
|
||||
if (! is_a($node, $nodeClass, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -502,4 +509,16 @@ final class NodeTypeResolver
|
|||
|
||||
return $classReflection->isSubclassOf($requiredObjectType->getClassName());
|
||||
}
|
||||
|
||||
private function resolveObjectType(ObjectType $resolvedObjectType, ObjectType $requiredObjectType): bool
|
||||
{
|
||||
$renamedObjectType = $this->renamedClassesDataCollector->matchClassName($resolvedObjectType);
|
||||
if (! $renamedObjectType instanceof ObjectType) {
|
||||
return $this->isObjectTypeOfObjectType($resolvedObjectType, $requiredObjectType);
|
||||
}
|
||||
if (! $this->isObjectTypeOfObjectType($renamedObjectType, $requiredObjectType)) {
|
||||
return $this->isObjectTypeOfObjectType($resolvedObjectType, $requiredObjectType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector\ComplexFixture;
|
||||
|
||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\OldClassWithMethod;
|
||||
|
||||
$class = new OldClassWithMethod();
|
||||
$class->someMethod();
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector\ComplexFixture;
|
||||
|
||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\NewClassWithNewMethod;
|
||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\OldClassWithMethod;
|
||||
|
||||
$class = new NewClassWithNewMethod();
|
||||
$class->someNewMethod();
|
||||
|
||||
?>
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class ComplexRenameClassRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/ComplexFixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/complex_rename.php';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source;
|
||||
|
||||
class NewClassWithNewMethod
|
||||
{
|
||||
public function someNewMethod()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source;
|
||||
|
||||
class OldClassWithMethod
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\ValueObject\MethodCallRename;
|
||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\NewClassWithNewMethod;
|
||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\OldClassWithMethod;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(RenameClassRector::class)
|
||||
->call('configure', [[
|
||||
RenameClassRector::OLD_TO_NEW_CLASSES => [
|
||||
OldClassWithMethod::class => NewClassWithNewMethod::class,
|
||||
],
|
||||
]]);
|
||||
|
||||
$services->set(RenameMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameMethodRector::METHOD_CALL_RENAMES => ValueObjectInliner::inline([
|
||||
new MethodCallRename(NewClassWithNewMethod::class, 'someMethod', 'someNewMethod'),
|
||||
]),
|
||||
]]);
|
||||
};
|
|
@ -6,6 +6,9 @@ namespace Rector\PSR4\Collector;
|
|||
|
||||
use Rector\Core\Configuration\RenamedClassesDataCollector;
|
||||
|
||||
/**
|
||||
* @deprecated Merge with RenamedClassesDataCollector
|
||||
*/
|
||||
final class RenamedClassesCollector
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -11,9 +11,12 @@ final class MethodCallRenameCollector
|
|||
*/
|
||||
private $methodCallRenames = [];
|
||||
|
||||
public function addMethodCallRename(MethodCallRenameInterface $methodCallRename): void
|
||||
/**
|
||||
* @param MethodCallRenameInterface[] $methodCallRenames
|
||||
*/
|
||||
public function addMethodCallRenames(array $methodCallRenames): void
|
||||
{
|
||||
$this->methodCallRenames[] = $methodCallRename;
|
||||
$this->methodCallRenames = array_merge($this->methodCallRenames, $methodCallRenames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,10 +139,7 @@ CODE_SAMPLE
|
|||
Assert::allIsInstanceOf($methodCallRenames, MethodCallRenameInterface::class);
|
||||
|
||||
$this->methodCallRenames = $methodCallRenames;
|
||||
|
||||
foreach ($methodCallRenames as $methodCallRename) {
|
||||
$this->methodCallRenameCollector->addMethodCallRename($methodCallRename);
|
||||
}
|
||||
$this->methodCallRenameCollector->addMethodCallRenames($methodCallRenames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Core\Configuration;
|
||||
|
||||
use PHPStan\Type\ObjectType;
|
||||
|
||||
final class RenamedClassesDataCollector
|
||||
{
|
||||
/**
|
||||
|
@ -26,4 +28,16 @@ final class RenamedClassesDataCollector
|
|||
{
|
||||
return $this->oldToNewClasses;
|
||||
}
|
||||
|
||||
public function matchClassName(ObjectType $objectType): ?ObjectType
|
||||
{
|
||||
$className = $objectType->getClassName();
|
||||
|
||||
$renamedClassName = $this->oldToNewClasses[$className] ?? null;
|
||||
if ($renamedClassName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ObjectType($renamedClassName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use PhpParser\Node\Stmt\ClassLike;
|
|||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
@ -36,8 +35,8 @@ final class ClassManipulator
|
|||
|
||||
public function __construct(
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
ReflectionProvider $reflectionProvider,
|
||||
NodesToRemoveCollector $nodesToRemoveCollector
|
||||
NodesToRemoveCollector $nodesToRemoveCollector,
|
||||
ReflectionProvider $reflectionProvider
|
||||
) {
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
|
||||
|
@ -70,11 +69,12 @@ final class ClassManipulator
|
|||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($objectType->getClassName());
|
||||
foreach ($classReflection->getAncestors() as $ancestorClassReflection) {
|
||||
if ($classReflection === $ancestorClassReflection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var ClassReflection[] $parentClassReflections */
|
||||
$parentClassReflections = array_merge($classReflection->getParents(), $classReflection->getInterfaces());
|
||||
foreach ($parentClassReflections as $parentClassReflection) {
|
||||
if ($parentClassReflection->hasMethod($methodName)) {
|
||||
if ($ancestorClassReflection->hasMethod($methodName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -94,27 +94,6 @@ final class ClassManipulator
|
|||
return $this->nodeNameResolver->getNames($privateProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPublicMethodNames(Class_ $class): array
|
||||
{
|
||||
$publicMethodNames = [];
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
if ($classMethod->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($classMethod->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$publicMethodNames[] = $this->nodeNameResolver->getName($classMethod);
|
||||
}
|
||||
|
||||
return $publicMethodNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user