Improve token iterator usage (#6046)

* use token iterator

* add spaceless tag

* [ci-review] Rector Rectify

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
Tomas Votruba 2021-04-06 20:36:50 +02:00 committed by GitHub
parent b7af3d58f1
commit b03536c0f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 182 additions and 126 deletions

View File

@ -14,7 +14,7 @@ expectedArguments(
\PHPStan\PhpDocParser\Ast\Node::getAttribute(),
0,
PhpDocAttributeKey::START_AND_END,
PhpDocAttributeKey::LAST_TOKEN_POSITION,
PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION,
PhpDocAttributeKey::PARENT,
);
@ -22,7 +22,7 @@ expectedArguments(
\PHPStan\PhpDocParser\Ast\Node::setAttribute(),
0,
PhpDocAttributeKey::START_AND_END,
PhpDocAttributeKey::LAST_TOKEN_POSITION,
PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION,
PhpDocAttributeKey::PARENT,
);
@ -30,7 +30,7 @@ expectedArguments(
\PHPStan\PhpDocParser\Ast\Node::hasAttribute(),
0,
PhpDocAttributeKey::START_AND_END,
PhpDocAttributeKey::LAST_TOKEN_POSITION,
PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION,
PhpDocAttributeKey::PARENT,
);

View File

@ -16,12 +16,14 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\Annotation\AnnotationNaming;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocNodeVisitor\ChangedPhpDocNodeVisitor;
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
use Rector\ChangesReporting\Collector\RectorChangeCollector;
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\Core\Exception\NotImplementedYetException;
@ -45,21 +47,11 @@ final class PhpDocInfo
PropertyTagValueNode::class => '@property',
];
/**
* @var string
*/
private $originalContent;
/**
* @var bool
*/
private $isSingleLine = false;
/**
* @var mixed[]
*/
private $tokens = [];
/**
* @var PhpDocNode
*/
@ -101,12 +93,13 @@ final class PhpDocInfo
private $rectorChangeCollector;
/**
* @param mixed[] $tokens
* @var BetterTokenIterator
*/
private $betterTokenIterator;
public function __construct(
PhpDocNode $phpDocNode,
array $tokens,
string $originalContent,
BetterTokenIterator $betterTokenIterator,
StaticTypeMapper $staticTypeMapper,
\PhpParser\Node $node,
AnnotationNaming $annotationNaming,
@ -114,11 +107,10 @@ final class PhpDocInfo
RectorChangeCollector $rectorChangeCollector
) {
$this->phpDocNode = $phpDocNode;
$this->tokens = $tokens;
$this->betterTokenIterator = $betterTokenIterator;
$this->originalPhpDocNode = clone $phpDocNode;
$this->originalContent = $originalContent;
if ($this->originalContent !== null && ! Strings::match(trim($this->originalContent), "#\n#")) {
if (! $betterTokenIterator->containsTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
$this->isSingleLine = true;
}
@ -129,11 +121,6 @@ final class PhpDocInfo
$this->rectorChangeCollector = $rectorChangeCollector;
}
public function getOriginalContent(): string
{
return $this->originalContent;
}
public function addPhpDocTagNode(PhpDocChildNode $phpDocChildNode): void
{
$this->phpDocNode->children[] = $phpDocChildNode;
@ -156,12 +143,12 @@ final class PhpDocInfo
*/
public function getTokens(): array
{
return $this->tokens;
return $this->betterTokenIterator->getTokens();
}
public function getTokenCount(): int
{
return count($this->tokens);
return $this->betterTokenIterator->count();
}
public function getVarTagValueNode(): ?VarTagValueNode
@ -417,7 +404,7 @@ final class PhpDocInfo
return false;
}
return $this->tokens === [];
return $this->betterTokenIterator->count() === 0;
}
public function makeSingleLined(): void

View File

@ -115,17 +115,18 @@ final class PhpDocInfoFactory
// create empty node
$content = '';
$tokens = [];
$tokenIterator = new BetterTokenIterator([]);
$phpDocNode = new PhpDocNode([]);
} else {
$content = $docComment->getText();
$tokens = $this->lexer->tokenize($content);
$tokenIterator = new BetterTokenIterator($tokens);
$phpDocNode = $this->parseTokensToPhpDocNode($tokens);
$phpDocNode = $this->betterPhpDocParser->parse($tokenIterator);
$this->setPositionOfLastToken($phpDocNode);
}
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, $content, $tokens, $node);
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, $tokenIterator, $node);
$this->phpDocInfosByObjectHash[$objectHash] = $phpDocInfo;
return $phpDocInfo;
@ -137,7 +138,7 @@ final class PhpDocInfoFactory
$this->currentNodeProvider->setNode($node);
$phpDocNode = new PhpDocNode([]);
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, '', [], $node);
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, new BetterTokenIterator([]), $node);
// multiline by default
$phpDocInfo->makeMultiLined();
@ -145,15 +146,6 @@ final class PhpDocInfoFactory
return $phpDocInfo;
}
/**
* @param mixed[][] $tokens
*/
private function parseTokensToPhpDocNode(array $tokens): PhpDocNode
{
$tokenIterator = new BetterTokenIterator($tokens);
return $this->betterPhpDocParser->parse($tokenIterator);
}
/**
* Needed for printing
*/
@ -166,29 +158,23 @@ final class PhpDocInfoFactory
$phpDocChildNodes = $phpDocNode->children;
$lastChildNode = array_pop($phpDocChildNodes);
/** @var StartAndEnd $startAndEnd */
$startAndEnd = $lastChildNode->getAttribute(PhpDocAttributeKey::START_AND_END);
if ($startAndEnd !== null) {
$phpDocNode->setAttribute(PhpDocAttributeKey::LAST_TOKEN_POSITION, $startAndEnd->getEnd());
if ($startAndEnd instanceof StartAndEnd) {
$phpDocNode->setAttribute(PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION, $startAndEnd->getEnd());
}
}
/**
* @param mixed[] $tokens
*/
private function createFromPhpDocNode(
PhpDocNode $phpDocNode,
string $content,
array $tokens,
BetterTokenIterator $betterTokenIterator,
Node $node
): PhpDocInfo {
$this->phpDocNodeMapper->transform($phpDocNode, new BetterTokenIterator($tokens));
$this->phpDocNodeMapper->transform($phpDocNode, $betterTokenIterator);
$phpDocInfo = new PhpDocInfo(
$phpDocNode,
$tokens,
$content,
$betterTokenIterator,
$this->staticTypeMapper,
$node,
$this->annotationNaming,

View File

@ -7,10 +7,10 @@ namespace Rector\BetterPhpDocParser;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use Rector\BetterPhpDocParser\Contract\BasePhpDocNodeVisitorInterface;
use Rector\BetterPhpDocParser\DataProvider\CurrentTokenIteratorProvider;
use Rector\BetterPhpDocParser\PhpDocNodeVisitor\CloningPhpDocNodeVisitor;
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
use Symplify\SimplePhpDocParser\Contract\PhpDocNodeVisitorInterface;
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
use Symplify\SimplePhpDocParser\PhpDocNodeVisitor\CloningPhpDocNodeVisitor;
use Symplify\SimplePhpDocParser\PhpDocNodeVisitor\ParentConnectingPhpDocNodeVisitor;
/**

View File

@ -1,22 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\BetterPhpDocParser\PhpDocNodeVisitor;
use PHPStan\PhpDocParser\Ast\Node;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Symplify\SimplePhpDocParser\PhpDocNodeVisitor\AbstractPhpDocNodeVisitor;
/**
* Mirror too https://github.com/nikic/PHP-Parser/blob/d520bc9e1d6203c35a1ba20675b79a051c821a9e/lib/PhpParser/NodeVisitor/CloningVisitor.php
*/
final class CloningPhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
{
public function enterNode(Node $origNode): ?Node
{
$node = clone $origNode;
$node->setAttribute(PhpDocAttributeKey::ORIG_NODE, $origNode);
return $node;
}
}

View File

@ -6,9 +6,11 @@ namespace Rector\BetterPhpDocParser\PhpDocNodeVisitor;
use PHPStan\PhpDocParser\Ast\Node;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use Rector\BetterPhpDocParser\Attributes\AttributeMirrorer;
use Rector\BetterPhpDocParser\Contract\BasePhpDocNodeVisitorInterface;
use Rector\BetterPhpDocParser\DataProvider\CurrentTokenIteratorProvider;
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\SpacingAwareTemplateTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
@ -52,17 +54,35 @@ final class TemplatePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor implemen
throw new ShouldNotHappenException();
}
$docContent = $betterTokenIterator->printFromTo($startAndEnd->getStart(), $startAndEnd->getEnd());
$prepositions = $this->resolvePreposition($betterTokenIterator, $startAndEnd);
$spacingAwareTemplateTagValueNode = new SpacingAwareTemplateTagValueNode(
$node->name,
$node->bound,
$node->description,
$docContent
$prepositions
);
$this->attributeMirrorer->mirror($node, $spacingAwareTemplateTagValueNode);
return $spacingAwareTemplateTagValueNode;
}
private function resolvePreposition(BetterTokenIterator $betterTokenIterator, StartAndEnd $startAndEnd): string
{
$partialTokens = $betterTokenIterator->partialTokens($startAndEnd->getStart(), $startAndEnd->getEnd());
foreach ($partialTokens as $partialToken) {
if ($partialToken[1] !== Lexer::TOKEN_IDENTIFIER) {
continue;
}
if (! in_array($partialToken[0], ['as', 'of'], true)) {
continue;
}
return $partialToken[0];
}
return 'of';
}
}

View File

@ -9,7 +9,9 @@ use PhpParser\Node;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\Attributes\AttributeMirrorer;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory;
use Rector\BetterPhpDocParser\ValueObject\DoctrineAnnotation\SilentKeyMap;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
@ -45,16 +47,23 @@ final class DoctrineAnnotationDecorator
*/
private $tokenIteratorFactory;
/**
* @var AttributeMirrorer
*/
private $attributeMirrorer;
public function __construct(
CurrentNodeProvider $currentNodeProvider,
ClassAnnotationMatcher $classAnnotationMatcher,
StaticDoctrineAnnotationParser $staticDoctrineAnnotationParser,
TokenIteratorFactory $tokenIteratorFactory
TokenIteratorFactory $tokenIteratorFactory,
AttributeMirrorer $attributeMirrorer
) {
$this->currentNodeProvider = $currentNodeProvider;
$this->classAnnotationMatcher = $classAnnotationMatcher;
$this->staticDoctrineAnnotationParser = $staticDoctrineAnnotationParser;
$this->tokenIteratorFactory = $tokenIteratorFactory;
$this->attributeMirrorer = $attributeMirrorer;
}
public function decorate(PhpDocNode $phpDocNode): void
@ -67,7 +76,7 @@ final class DoctrineAnnotationDecorator
// merge split doctrine nested tags
$this->mergeNestedDoctrineAnnotations($phpDocNode);
foreach ($phpDocNode->children as $phpDocChildNode) {
foreach ($phpDocNode->children as $key => $phpDocChildNode) {
if (! $phpDocChildNode instanceof PhpDocTagNode) {
continue;
}
@ -104,7 +113,13 @@ final class DoctrineAnnotationDecorator
);
$doctrineAnnotationTagValueNode->setAttribute(PhpDocAttributeKey::START_AND_END, $formerStartEnd);
$phpDocChildNode->value = $doctrineAnnotationTagValueNode;
$spacelessPhpDocTagNode = new SpacelessPhpDocTagNode(
$phpDocChildNode->name,
$doctrineAnnotationTagValueNode
);
$this->attributeMirrorer->mirror($phpDocChildNode, $spacelessPhpDocTagNode);
$phpDocNode->children[$key] = $spacelessPhpDocTagNode;
}
}

View File

@ -237,7 +237,7 @@ final class PhpDocInfoPrinter
}
if ($phpDocChildNode->value instanceof DoctrineAnnotationTagValueNode && $shouldReprintChildNode) {
$printedNode = $phpDocChildNode->name . $phpDocChildNode->value;
$printedNode = (string) $phpDocChildNode;
// remove extra space between tags
$printedNode = Strings::replace($printedNode, self::TAG_AND_SPACE_REGEX, '$1(');
@ -277,7 +277,7 @@ final class PhpDocInfoPrinter
private function printEnd(string $output): string
{
$lastTokenPosition = $this->phpDocNode->getAttribute(
PhpDocAttributeKey::LAST_TOKEN_POSITION
PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION
) ?: $this->currentTokenPosition;
if ($lastTokenPosition === 0) {
$lastTokenPosition = 1;
@ -345,8 +345,8 @@ final class PhpDocInfoPrinter
}
$startTokenPosition = $startAndEnd->getStart();
$tokens = $this->phpDocInfo->getTokens();
$tokens = $this->phpDocInfo->getTokens();
if (! isset($tokens[$startTokenPosition - 1])) {
return;
}

View File

@ -56,7 +56,7 @@ final class BetterTokenIterator extends TokenIterator
public function isTokenTypeOnPosition(int $tokenType, int $position): bool
{
$tokens = $this->privatesAccessor->getPrivateProperty($this, self::TOKENS);
$tokens = $this->getTokens();
$token = $tokens[$position] ?? null;
if ($token === null) {
@ -81,7 +81,7 @@ final class BetterTokenIterator extends TokenIterator
throw new ShouldNotHappenException('Arguments are flipped');
}
$tokens = $this->privatesAccessor->getPrivateProperty($this, self::TOKENS);
$tokens = $this->getTokens();
$content = '';
@ -102,10 +102,8 @@ final class BetterTokenIterator extends TokenIterator
public function print(): string
{
$tokens = $this->privatesAccessor->getPrivateProperty($this, self::TOKENS);
$content = '';
foreach ($tokens as $token) {
foreach ($this->getTokens() as $token) {
$content .= $token[0];
}
@ -116,7 +114,7 @@ final class BetterTokenIterator extends TokenIterator
{
$this->pushSavePoint();
$tokens = $this->privatesAccessor->getPrivateProperty($this, self::TOKENS);
$tokens = $this->getTokens();
$index = $this->privatesAccessor->getPrivateProperty($this, self::INDEX);
// does next token exist?
@ -136,4 +134,43 @@ final class BetterTokenIterator extends TokenIterator
{
return $this->privatesAccessor->getPrivateProperty($this, self::INDEX);
}
/**
* @return mixed[]
*/
public function getTokens(): array
{
return $this->privatesAccessor->getPrivateProperty($this, self::TOKENS);
}
public function count(): int
{
return count($this->getTokens());
}
/**
* @return mixed[]
*/
public function partialTokens(int $start, int $end): array
{
$tokens = $this->getTokens();
$chunkTokens = [];
for ($i = $start; $i <= $end; ++$i) {
$chunkTokens[$i] = $tokens[$i];
}
return $chunkTokens;
}
public function containsTokenType(int $type): bool
{
foreach ($this->getTokens() as $token) {
if ($token[1] === $type) {
return true;
}
}
return false;
}
}

View File

@ -4,29 +4,20 @@ declare(strict_types=1);
namespace Rector\BetterPhpDocParser\ValueObject\PhpDoc;
use Nette\Utils\Strings;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
final class SpacingAwareTemplateTagValueNode extends TemplateTagValueNode
{
/**
* @var string
* @see https://regex101.com/r/4WtsUS/1
*/
private const AS_OF_PREPOSITOIN_REGEX = '#\s+(?<preposition>as|of)\s+#';
/**
* @var string
*/
private $preposition;
public function __construct(string $name, ?TypeNode $typeNode, string $description, string $originalContent)
public function __construct(string $name, ?TypeNode $typeNode, string $description, string $preposition)
{
parent::__construct($name, $typeNode, $description);
$matches = Strings::match($originalContent, self::AS_OF_PREPOSITOIN_REGEX);
$this->preposition = $matches['preposition'] ?? 'of';
$this->preposition = $preposition;
}
public function __toString(): string

View File

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Rector\BetterPhpDocParser\ValueObject;
use Symplify\SimplePhpDocParser\ValueObject\PhpDocAttributeKey as NativePhpDocAttributeKey;
final class PhpDocAttributeKey
{
/**
@ -14,15 +16,15 @@ final class PhpDocAttributeKey
/**
* @var string
*/
public const PARENT = 'parent';
public const PARENT = NativePhpDocAttributeKey::PARENT;
/**
* @var string
*/
public const LAST_TOKEN_POSITION = 'last_token_position';
public const LAST_PHP_DOC_TOKEN_POSITION = 'last_token_position';
/**
* @var string
*/
public const ORIG_NODE = 'orig_node';
public const ORIG_NODE = NativePhpDocAttributeKey::ORIG_NODE;
}

View File

@ -6,6 +6,7 @@ namespace Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\NodeTypeResolver\PhpDocNodeVisitor\ClassRenamePhpDocNodeVisitor;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
final class DocBlockClassRenamer
@ -21,17 +22,17 @@ final class DocBlockClassRenamer
}
/**
* @param array<string, string> $oldToNewClasses
* @param OldToNewType[] $oldToNewTypes
*/
public function renamePhpDocType(PhpDocInfo $phpDocInfo, array $oldToNewClasses): void
public function renamePhpDocType(PhpDocInfo $phpDocInfo, array $oldToNewTypes): void
{
if ($oldToNewClasses === []) {
if ($oldToNewTypes === []) {
return;
}
$phpDocNodeTraverser = new PhpDocNodeTraverser();
$this->classRenamePhpDocNodeVisitor->setOldToNewClasses($oldToNewClasses);
$this->classRenamePhpDocNodeVisitor->setOldToNewTypes($oldToNewTypes);
$phpDocNodeTraverser->addPhpDocNodeVisitor($this->classRenamePhpDocNodeVisitor);
$phpDocNodeTraverser->traverse($phpDocInfo->getPhpDocNode());
}

View File

@ -11,8 +11,8 @@ use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
use Symplify\SimplePhpDocParser\PhpDocNodeVisitor\AbstractPhpDocNodeVisitor;
@ -29,9 +29,9 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
private $currentNodeProvider;
/**
* @var array<string, string>
* @var OldToNewType[]
*/
private $oldToNewClasses = [];
private $oldToNewTypes = [];
public function __construct(StaticTypeMapper $staticTypeMapper, CurrentNodeProvider $currentNodeProvider)
{
@ -41,7 +41,7 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
public function beforeTraverse(Node $node): void
{
if ($this->oldToNewClasses === []) {
if ($this->oldToNewTypes === []) {
throw new ShouldNotHappenException('Configure "$oldToNewClasses" first');
}
}
@ -64,15 +64,12 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
$staticType = new ObjectType($staticType->getFullyQualifiedName());
}
foreach ($this->oldToNewClasses as $oldClass => $newClass) {
$oldType = new ObjectType($oldClass);
$newType = new FullyQualifiedObjectType($newClass);
if (! $staticType->equals($oldType)) {
foreach ($this->oldToNewTypes as $oldToNewType) {
if (! $staticType->equals($oldToNewType->getOldType())) {
continue;
}
$newTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
$newTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($oldToNewType->getNewType());
$parentType = $node->getAttribute(PhpDocAttributeKey::PARENT);
if ($parentType instanceof TypeNode) {
@ -87,10 +84,10 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
}
/**
* @param array<string, string> $oldToNewClasses
* @param OldToNewType[] $oldToNewTypes
*/
public function setOldToNewClasses(array $oldToNewClasses): void
public function setOldToNewTypes(array $oldToNewTypes): void
{
$this->oldToNewClasses = $oldToNewClasses;
$this->oldToNewTypes = $oldToNewTypes;
}
}

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Rector\NodeTypeResolver\ValueObject;
use PHPStan\Type\Type;
final class OldToNewType
{
/**
* @var Type
*/
private $oldType;
/**
* @var Type
*/
private $newType;
public function __construct(Type $oldType, Type $newType)
{
$this->oldType = $oldType;
$this->newType = $newType;
}
public function getOldType(): Type
{
return $this->oldType;
}
public function getNewType(): Type
{
return $this->newType;
}
}

View File

@ -17,6 +17,7 @@ use PhpParser\Node\Stmt\UseUse;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocClassRenamer;
use Rector\BetterPhpDocParser\ValueObject\NodeTypes;
@ -27,6 +28,8 @@ use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeRemoval\NodeRemover;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockClassRenamer;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
use Symplify\PackageBuilder\Parameter\ParameterProvider;
@ -116,7 +119,12 @@ final class ClassRenamer
*/
public function renameNode(Node $node, array $oldToNewClasses): ?Node
{
$this->refactorPhpDoc($node, $oldToNewClasses);
$oldToNewTypes = [];
foreach ($oldToNewClasses as $oldClass => $newClass) {
$oldToNewTypes[] = new OldToNewType(new ObjectType($oldClass), new FullyQualifiedObjectType($newClass));
}
$this->refactorPhpDoc($node, $oldToNewTypes, $oldToNewClasses);
if ($node instanceof Name) {
return $this->refactorName($node, $oldToNewClasses);
@ -134,12 +142,10 @@ final class ClassRenamer
}
/**
* Replace types in @var/@param/@return/@throws,
* Doctrine @ORM entity targetClass, Serialize, Assert etc.
*
* @param OldToNewType[] $oldToNewTypes
* @param array<string, string> $oldToNewClasses
*/
private function refactorPhpDoc(Node $node, array $oldToNewClasses): void
private function refactorPhpDoc(Node $node, array $oldToNewTypes, array $oldToNewClasses): void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
if (! $phpDocInfo->hasByTypes(NodeTypes::TYPE_AWARE_NODES) && ! $phpDocInfo->hasByAnnotationClasses(
@ -148,7 +154,7 @@ final class ClassRenamer
return;
}
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo, $oldToNewClasses);
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo, $oldToNewTypes);
$this->phpDocClassRenamer->changeTypeInAnnotationTypes($node, $phpDocInfo, $oldToNewClasses);
}