mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-21 09:42:45 +01:00
fix RenameClassRector to change only direct class names, not children [closes #1514]
This commit is contained in:
parent
a69d08bac5
commit
6854f3ef1e
@ -38,7 +38,6 @@ services:
|
||||
Psr\SimpleCache\CacheInterface: 'Symfony\Contracts\Cache\CacheInterface'
|
||||
|
||||
# EventDispatcher
|
||||
Symfony\Component\EventDispatcher\Event: 'Symfony\Contracts\EventDispatcher\Event'
|
||||
Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent: 'Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent'
|
||||
Symfony\Component\HttpKernel\Event\FilterControllerEvent: 'Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent'
|
||||
Symfony\Component\HttpKernel\Event\FilterResponseEvent: 'Symfony\Component\HttpKernel\Event\ResponseEvent'
|
||||
@ -46,6 +45,8 @@ services:
|
||||
Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent: 'Symfony\Component\HttpKernel\Event\ViewEvent'
|
||||
Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent: 'Symfony\Component\HttpKernel\Event\ExceptionEvent'
|
||||
Symfony\Component\HttpKernel\Event\PostResponseEvent: 'Symfony\Component\HttpKernel\Event\TerminateEvent'
|
||||
# has lowest priority, have to be last
|
||||
Symfony\Component\EventDispatcher\Event: 'Symfony\Contracts\EventDispatcher\Event'
|
||||
|
||||
# MimeType
|
||||
Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface: 'Symfony\Component\Mime\MimeTypesInterface'
|
||||
|
@ -87,7 +87,7 @@ CODE_SAMPLE
|
||||
|
||||
[$oldType, $newType] = $match;
|
||||
|
||||
$this->docBlockManipulator->changeType($property, $oldType, $newType);
|
||||
$this->docBlockManipulator->changeTypeIncludingChildren($property, $oldType, $newType);
|
||||
}
|
||||
|
||||
private function refactorNullableType(NullableType $nullableType): void
|
||||
@ -123,7 +123,7 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->docBlockManipulator->changeType($node, $oldType, $newType);
|
||||
$this->docBlockManipulator->changeTypeIncludingChildren($node, $oldType, $newType);
|
||||
}
|
||||
|
||||
private function processParamNode(NullableType $nullableType, Param $param, string $newType): void
|
||||
@ -135,6 +135,6 @@ CODE_SAMPLE
|
||||
|
||||
$oldType = $this->namespaceAnalyzer->resolveTypeToFullyQualified((string) $nullableType->type, $nullableType);
|
||||
|
||||
$this->docBlockManipulator->changeType($classMethodNode, $oldType, $newType);
|
||||
$this->docBlockManipulator->changeTypeIncludingChildren($classMethodNode, $oldType, $newType);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ namespace Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer;
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocChildNode;
|
||||
@ -158,19 +157,24 @@ final class DocBlockManipulator
|
||||
$this->updateNodeWithPhpDocInfo($node, $phpDocInfo);
|
||||
}
|
||||
|
||||
public function changeType(Node $node, string $oldType, string $newType): void
|
||||
public function changeType(Node $node, string $oldType, string $newType, bool $includeChildren = false): void
|
||||
{
|
||||
if ($node->getDocComment() === null) {
|
||||
if (! $this->hasNodeTypeChangeableTags($node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->createPhpDocInfoFromNode($node);
|
||||
|
||||
$this->replacePhpDocTypeByAnother($phpDocInfo->getPhpDocNode(), $oldType, $newType, $node);
|
||||
$this->replacePhpDocTypeByAnother($phpDocInfo->getPhpDocNode(), $oldType, $newType, $node, $includeChildren);
|
||||
|
||||
$this->updateNodeWithPhpDocInfo($node, $phpDocInfo);
|
||||
}
|
||||
|
||||
public function changeTypeIncludingChildren(Node $node, string $oldType, string $newType): void
|
||||
{
|
||||
$this->changeType($node, $oldType, $newType, true);
|
||||
}
|
||||
|
||||
public function replaceAnnotationInNode(Node $node, string $oldAnnotation, string $newAnnotation): void
|
||||
{
|
||||
if ($node->getDocComment() === null) {
|
||||
@ -378,7 +382,8 @@ final class DocBlockManipulator
|
||||
AttributeAwarePhpDocNode $attributeAwarePhpDocNode,
|
||||
string $oldType,
|
||||
string $newType,
|
||||
Node $node
|
||||
Node $node,
|
||||
bool $includeChildren = false
|
||||
): AttributeAwarePhpDocNode {
|
||||
foreach ($attributeAwarePhpDocNode->children as $phpDocChildNode) {
|
||||
if (! $phpDocChildNode instanceof PhpDocTagNode) {
|
||||
@ -392,7 +397,12 @@ final class DocBlockManipulator
|
||||
/** @var VarTagValueNode|ParamTagValueNode|ReturnTagValueNode $tagValueNode */
|
||||
$tagValueNode = $phpDocChildNode->value;
|
||||
|
||||
$phpDocChildNode->value->type = $this->replaceTypeNode($tagValueNode->type, $oldType, $newType);
|
||||
$phpDocChildNode->value->type = $this->replaceTypeNode(
|
||||
$tagValueNode->type,
|
||||
$oldType,
|
||||
$newType,
|
||||
$includeChildren
|
||||
);
|
||||
|
||||
$this->stringsTypePhpDocNodeDecorator->decorate($attributeAwarePhpDocNode, $node);
|
||||
}
|
||||
@ -481,6 +491,21 @@ final class DocBlockManipulator
|
||||
$this->importedNames = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* For better performance
|
||||
*/
|
||||
public function hasNodeTypeChangeableTags(Node $node): bool
|
||||
{
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$text = $docComment->getText();
|
||||
|
||||
return (bool) Strings::match($text, '#\@(param|throws|return|var)\b#');
|
||||
}
|
||||
|
||||
private function addTypeSpecificTag(Node $node, string $name, string $type): void
|
||||
{
|
||||
// there might be no phpdoc at all
|
||||
@ -504,26 +529,28 @@ final class DocBlockManipulator
|
||||
}
|
||||
}
|
||||
|
||||
private function updateNodeWithPhpDocInfo(Node $node, PhpDocInfo $phpDocInfo): void
|
||||
private function updateNodeWithPhpDocInfo(Node $node, PhpDocInfo $phpDocInfo): bool
|
||||
{
|
||||
// skip if has no doc comment
|
||||
if ($node->getDocComment() === null) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$phpDoc = $this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
|
||||
if ($phpDoc !== '') {
|
||||
// no change, don't save it
|
||||
if ($node->getDocComment()->getText() === $phpDoc) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$node->setDocComment(new Doc($phpDoc));
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// no comments, null
|
||||
$node->setAttribute('comments', null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function createPhpDocInfoFromNode(Node $node): PhpDocInfo
|
||||
@ -546,14 +573,20 @@ final class DocBlockManipulator
|
||||
$phpDocTagNode->value instanceof ThrowsTagValueNode;
|
||||
}
|
||||
|
||||
private function replaceTypeNode(TypeNode $typeNode, string $oldType, string $newType): TypeNode
|
||||
{
|
||||
private function replaceTypeNode(
|
||||
TypeNode $typeNode,
|
||||
string $oldType,
|
||||
string $newType,
|
||||
bool $includeChildren = false
|
||||
): TypeNode {
|
||||
// @todo use $this->nodeTraverser->traverseWithCallable here matching "AttributeAwareIdentifierTypeNode"
|
||||
|
||||
if ($typeNode instanceof AttributeAwareIdentifierTypeNode) {
|
||||
$nodeType = $this->resolveNodeType($typeNode);
|
||||
|
||||
if (is_a($nodeType, $oldType, true) || ltrim($nodeType, '\\') === $oldType) {
|
||||
// by default do not override subtypes, can actually use parent type (race condition), which is not desired
|
||||
// see: $includeChildren
|
||||
if (($includeChildren && is_a($nodeType, $oldType, true)) || ltrim($nodeType, '\\') === $oldType) {
|
||||
$newType = $this->forceFqnPrefix($newType);
|
||||
|
||||
return new AttributeAwareIdentifierTypeNode($newType);
|
||||
@ -562,12 +595,12 @@ final class DocBlockManipulator
|
||||
|
||||
if ($typeNode instanceof UnionTypeNode) {
|
||||
foreach ($typeNode->types as $key => $subTypeNode) {
|
||||
$typeNode->types[$key] = $this->replaceTypeNode($subTypeNode, $oldType, $newType);
|
||||
$typeNode->types[$key] = $this->replaceTypeNode($subTypeNode, $oldType, $newType, $includeChildren);
|
||||
}
|
||||
}
|
||||
|
||||
if ($typeNode instanceof ArrayTypeNode) {
|
||||
$typeNode->type = $this->replaceTypeNode($typeNode->type, $oldType, $newType);
|
||||
$typeNode->type = $this->replaceTypeNode($typeNode->type, $oldType, $newType, $includeChildren);
|
||||
|
||||
return $typeNode;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ CODE_SAMPLE
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// replace on @var/@param/@return/@throws
|
||||
if ($node->getDocComment()) {
|
||||
if ($this->docBlockManipulator->hasNodeTypeChangeableTags($node)) {
|
||||
foreach ($this->oldToNewClasses as $oldClass => $newClass) {
|
||||
$this->docBlockManipulator->changeType($node, $oldClass, $newClass);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user