rector/src/PhpDoc/PhpDocClassRenamer.php

124 lines
3.9 KiB
PHP
Raw Normal View History

2019-08-30 18:21:21 +00:00
<?php declare(strict_types=1);
namespace Rector\PhpDoc;
use PhpParser\Comment\Doc;
use PhpParser\Node;
2019-09-26 14:26:44 +00:00
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
2019-08-30 19:41:21 +00:00
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
2019-09-26 14:26:44 +00:00
use Rector\BetterPhpDocParser\PhpDocNode\JMS\SerializerTypeTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Symfony\Validator\Constraints\AssertChoiceTagValueNode;
2019-08-30 19:41:21 +00:00
use Rector\BetterPhpDocParser\Printer\PhpDocInfoPrinter;
2019-08-30 18:21:21 +00:00
final class PhpDocClassRenamer
{
2019-08-30 19:41:21 +00:00
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @var PhpDocInfoPrinter
*/
private $phpDocInfoPrinter;
/**
* @var bool
*/
private $shouldUpdate = false;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory, PhpDocInfoPrinter $phpDocInfoPrinter)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->phpDocInfoPrinter = $phpDocInfoPrinter;
}
2019-08-30 18:21:21 +00:00
/**
* Covers annotations like @ORM, @Serializer, @Assert etc
* See https://github.com/rectorphp/rector/issues/1872
*
* @param string[] $oldToNewClasses
*/
public function changeTypeInAnnotationTypes(Node $node, array $oldToNewClasses): void
{
$docComment = $node->getDocComment();
if ($docComment === null) {
return;
}
2019-08-30 19:41:21 +00:00
$this->shouldUpdate = false;
2019-08-30 18:21:21 +00:00
2019-08-30 19:41:21 +00:00
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
$this->procesAssertChoiceTagValueNode($oldToNewClasses, $phpDocInfo);
$this->procesDoctrineRelationTagValueNode($oldToNewClasses, $phpDocInfo);
$this->processSerializerTypeTagValueNode($oldToNewClasses, $phpDocInfo);
2019-08-30 18:21:21 +00:00
2019-09-25 09:00:21 +00:00
if ($this->shouldUpdate === false) {
2019-08-30 19:41:21 +00:00
return;
2019-08-30 18:21:21 +00:00
}
2019-08-30 19:41:21 +00:00
$textDocComment = $this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
$node->setDocComment(new Doc($textDocComment));
}
2019-08-30 18:21:21 +00:00
2019-08-30 19:41:21 +00:00
/**
* @param string[] $oldToNewClasses
*/
private function procesAssertChoiceTagValueNode(array $oldToNewClasses, PhpDocInfo $phpDocInfo): void
{
$choiceTagValueNode = $phpDocInfo->getByType(AssertChoiceTagValueNode::class);
if (! $choiceTagValueNode instanceof AssertChoiceTagValueNode) {
2019-08-30 18:21:21 +00:00
return;
}
2019-08-30 19:41:21 +00:00
foreach ($oldToNewClasses as $oldClass => $newClass) {
if (! $choiceTagValueNode->isCallbackClass($oldClass)) {
continue;
}
$choiceTagValueNode->changeCallbackClass($newClass);
$this->shouldUpdate = true;
break;
2019-08-30 18:21:21 +00:00
}
2019-08-30 19:41:21 +00:00
}
2019-08-30 18:21:21 +00:00
2019-08-30 19:41:21 +00:00
/**
* @param string[] $oldToNewClasses
*/
private function procesDoctrineRelationTagValueNode(array $oldToNewClasses, PhpDocInfo $phpDocInfo): void
{
$relationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
if (! $relationTagValueNode instanceof DoctrineRelationTagValueNodeInterface) {
return;
}
foreach ($oldToNewClasses as $oldClass => $newClass) {
if ($relationTagValueNode->getFqnTargetEntity() !== $oldClass) {
continue;
}
$relationTagValueNode->changeTargetEntity($newClass);
$this->shouldUpdate = true;
break;
}
}
/**
* @param string[] $oldToNewClasses
*/
private function processSerializerTypeTagValueNode(array $oldToNewClasses, PhpDocInfo $phpDocInfo): void
{
$serializerTypeTagValueNode = $phpDocInfo->getByType(SerializerTypeTagValueNode::class);
if (! $serializerTypeTagValueNode instanceof SerializerTypeTagValueNode) {
return;
}
foreach ($oldToNewClasses as $oldClass => $newClass) {
if ($serializerTypeTagValueNode->replaceName($oldClass, $newClass)) {
$this->shouldUpdate = true;
}
}
2019-08-30 18:21:21 +00:00
}
}