Validate used import statement

This commit is contained in:
Tomas Votruba 2019-02-10 11:01:33 +01:00
parent 6ae3e80121
commit 3617b4f774
5 changed files with 92 additions and 4 deletions

View File

@ -7,6 +7,7 @@ use PhpParser\Node\Expr\New_;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\UseUse;
use Rector\NodeTypeResolver\Node\Attribute;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\ConfiguredCodeSample;
@ -111,15 +112,41 @@ CODE_SAMPLE
}
if ($parentNode instanceof Class_) {
if ($parentNode->extends === $node && interface_exists($newName)) {
return false;
}
return $this->isValidClassNameChange($node, $newName, $parentNode);
}
if (in_array($node, $parentNode->implements, true) && class_exists($newName)) {
// prevent to change to import, that already exists
if ($parentNode instanceof UseUse) {
return $this->isValidUseImportChange($newName, $parentNode);
}
return true;
}
private function isValidUseImportChange(string $newName, UseUse $useUseNode): bool
{
$useNodes = $useUseNode->getAttribute(Attribute::USE_NODES);
foreach ($useNodes as $useNode) {
if ($this->isName($useNode, $newName)) {
// name already exists
return false;
}
}
return true;
}
private function isValidClassNameChange(Node $node, string $newName, Class_ $classNode): bool
{
if ($classNode->extends === $node && interface_exists($newName)) {
return false;
}
if (in_array($node, $classNode->implements, true) && class_exists($newName)) {
return false;
}
return true;
}
}

View File

@ -2,6 +2,8 @@
namespace Rector\Tests\Rector\Class_\ClassReplacerRector;
use Manual\Twig\TwigFilter;
use Manual_Twig_Filter;
use Rector\Rector\Class_\ClassReplacerRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Tests\Rector\Class_\ClassReplacerRector\Source\NewClass;
@ -21,6 +23,7 @@ final class ClassReplacerRectorTest extends AbstractRectorTestCase
__DIR__ . '/Fixture/class_to_interface.php.inc',
__DIR__ . '/Fixture/interface_to_class.php.inc',
__DIR__ . '/Fixture/name_insensitive.php.inc',
__DIR__ . '/Fixture/twig_case.php.inc',
]);
}
@ -39,6 +42,7 @@ final class ClassReplacerRectorTest extends AbstractRectorTestCase
OldClassWithTypo::class => NewClassWithoutTypo::class,
'DateTime' => 'DateTimeInterface',
'Countable' => 'stdClass',
Manual_Twig_Filter::class => TwigFilter::class,
];
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Rector\Tests\Rector\Class_\ClassReplacerRector\Fixture;
use Manual_Twig_Filter;
use Manual\Twig\TwigFilter;
final class ShortUrlExtension
{
/**
* @return Manual_Twig_Filter[]
*/
public function getFilters(): array
{
return [
new Manual_Twig_Filter('shortUrl', [$this, 'shortUrl']),
];
}
}
?>
-----
<?php
namespace Rector\Tests\Rector\Class_\ClassReplacerRector\Fixture;
use Manual_Twig_Filter;
use Manual\Twig\TwigFilter;
final class ShortUrlExtension
{
/**
* @return Manual_Twig_Filter[]
*/
public function getFilters(): array
{
return [
new \Manual\Twig\TwigFilter('shortUrl', [$this, 'shortUrl']),
];
}
}
?>

View File

@ -0,0 +1,6 @@
<?php declare(strict_types=1);
final class Manual_Twig_Filter
{
}

View File

@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace Manual\Twig;
final class TwigFilter
{
}