mirror of
https://github.com/rectorphp/rector.git
synced 2025-05-03 06:28:01 +02:00
Updated Rector to commit 8c20a7ed0a2eb3d26a275c0fef16b8f413e02b42
8c20a7ed0a
[NodeTypeResolver] Clean up UseImportsResolver check on ClassRenamePhpDocNodeVisitor (#6500)
This commit is contained in:
parent
57ac216872
commit
d68ed070fe
@ -50,7 +50,7 @@ final class ObjectTypeSpecifier
|
||||
/**
|
||||
* @return \PHPStan\Type\TypeWithClassName|\Rector\StaticTypeMapper\ValueObject\Type\NonExistingObjectType|\PHPStan\Type\UnionType|\PHPStan\Type\MixedType|\PHPStan\Type\Generic\TemplateType
|
||||
*/
|
||||
public function narrowToFullyQualifiedOrAliasedObjectType(Node $node, ObjectType $objectType, ?\PHPStan\Analyser\Scope $scope)
|
||||
public function narrowToFullyQualifiedOrAliasedObjectType(Node $node, ObjectType $objectType, ?\PHPStan\Analyser\Scope $scope, bool $withPreslash = \false)
|
||||
{
|
||||
$uses = $this->useImportsResolver->resolve();
|
||||
$aliasedObjectType = $this->matchAliasedObjectType($objectType, $uses);
|
||||
@ -69,6 +69,7 @@ final class ObjectTypeSpecifier
|
||||
return new FullyQualifiedObjectType($className);
|
||||
}
|
||||
// probably in same namespace
|
||||
$namespaceName = null;
|
||||
if ($scope instanceof Scope) {
|
||||
$namespaceName = $scope->getNamespace();
|
||||
if ($namespaceName !== null) {
|
||||
@ -77,8 +78,6 @@ final class ObjectTypeSpecifier
|
||||
return new FullyQualifiedObjectType($newClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($scope instanceof Scope) {
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
$templateTags = $classReflection->getTemplateTags();
|
||||
@ -86,18 +85,31 @@ final class ObjectTypeSpecifier
|
||||
$templateTypeScope = $nameScope->getTemplateTypeScope();
|
||||
if (!$templateTypeScope instanceof TemplateTypeScope) {
|
||||
// invalid type
|
||||
return new NonExistingObjectType($className);
|
||||
return $this->resolveNamespacedNonExistingObjectType($namespaceName, $className, $withPreslash);
|
||||
}
|
||||
$currentTemplateTag = $templateTags[$className] ?? null;
|
||||
if ($currentTemplateTag === null) {
|
||||
// invalid type
|
||||
return new NonExistingObjectType($className);
|
||||
return $this->resolveNamespacedNonExistingObjectType($namespaceName, $className, $withPreslash);
|
||||
}
|
||||
return TemplateTypeFactory::create($templateTypeScope, $currentTemplateTag->getName(), $currentTemplateTag->getBound(), $currentTemplateTag->getVariance());
|
||||
}
|
||||
}
|
||||
// invalid type
|
||||
return new NonExistingObjectType($className);
|
||||
return $this->resolveNamespacedNonExistingObjectType($namespaceName, $className, $withPreslash);
|
||||
}
|
||||
private function resolveNamespacedNonExistingObjectType(?string $namespacedName, string $className, bool $withPreslash) : NonExistingObjectType
|
||||
{
|
||||
if ($namespacedName === null) {
|
||||
return new NonExistingObjectType($className);
|
||||
}
|
||||
if ($withPreslash) {
|
||||
return new NonExistingObjectType($className);
|
||||
}
|
||||
if (\strpos($className, '\\') !== \false) {
|
||||
return new NonExistingObjectType($className);
|
||||
}
|
||||
return new NonExistingObjectType($namespacedName . '\\' . $className);
|
||||
}
|
||||
/**
|
||||
* @param array<Use_|GroupUse> $uses
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = 'ed6887072d32d36be5f9dbe8d911316f552da3c5';
|
||||
public const PACKAGE_VERSION = '8c20a7ed0a2eb3d26a275c0fef16b8f413e02b42';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2024-11-24 20:03:45';
|
||||
public const RELEASE_DATE = '2024-11-24 20:38:26';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -172,7 +172,7 @@ final class NodeTypeResolver
|
||||
$type = $this->genericClassStringTypeCorrector->correct($type);
|
||||
if ($type instanceof ObjectType) {
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
$type = $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType($node, $type, $scope);
|
||||
$type = $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType($node, $type, $scope, \true);
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
@ -4,19 +4,14 @@ declare (strict_types=1);
|
||||
namespace Rector\NodeTypeResolver\PhpDocNodeVisitor;
|
||||
|
||||
use PhpParser\Node as PhpNode;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\GroupUse;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\Generic\TemplateObjectType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\Naming\Naming\UseImportsResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
|
||||
use Rector\PhpDocParser\PhpDocParser\PhpDocNodeVisitor\AbstractPhpDocNodeVisitor;
|
||||
use Rector\Renaming\Collector\RenamedNameCollector;
|
||||
@ -29,10 +24,6 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
|
||||
* @readonly
|
||||
*/
|
||||
private StaticTypeMapper $staticTypeMapper;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private UseImportsResolver $useImportsResolver;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
@ -43,10 +34,9 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
|
||||
private array $oldToNewTypes = [];
|
||||
private bool $hasChanged = \false;
|
||||
private ?PhpNode $currentPhpNode = null;
|
||||
public function __construct(StaticTypeMapper $staticTypeMapper, UseImportsResolver $useImportsResolver, RenamedNameCollector $renamedNameCollector)
|
||||
public function __construct(StaticTypeMapper $staticTypeMapper, RenamedNameCollector $renamedNameCollector)
|
||||
{
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->useImportsResolver = $useImportsResolver;
|
||||
$this->renamedNameCollector = $renamedNameCollector;
|
||||
}
|
||||
public function setCurrentPhpNode(PhpNode $phpNode) : void
|
||||
@ -114,51 +104,10 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
|
||||
return $name;
|
||||
}
|
||||
$staticType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($identifierTypeNode, $phpNode);
|
||||
if (!$staticType instanceof ObjectType) {
|
||||
return $name;
|
||||
}
|
||||
if ($staticType instanceof ShortenedObjectType || $staticType instanceof AliasedObjectType) {
|
||||
return $name;
|
||||
}
|
||||
$uses = $this->useImportsResolver->resolve();
|
||||
$originalNode = $phpNode->getAttribute(AttributeKey::ORIGINAL_NODE);
|
||||
$scope = $originalNode instanceof PhpNode ? $originalNode->getAttribute(AttributeKey::SCOPE) : $phpNode->getAttribute(AttributeKey::SCOPE);
|
||||
if (!$scope instanceof Scope) {
|
||||
if (!$originalNode instanceof PhpNode) {
|
||||
return $this->resolveNamefromUse($uses, $name);
|
||||
}
|
||||
// @template is to not be renamed
|
||||
if ($staticType instanceof TemplateObjectType) {
|
||||
return '';
|
||||
}
|
||||
$namespaceName = $scope->getNamespace();
|
||||
if ($namespaceName === null) {
|
||||
return $this->resolveNamefromUse($uses, $name);
|
||||
}
|
||||
if ($uses === []) {
|
||||
return $namespaceName . '\\' . $name;
|
||||
}
|
||||
$nameFromUse = $this->resolveNamefromUse($uses, $name);
|
||||
if ($nameFromUse !== $name) {
|
||||
return $nameFromUse;
|
||||
}
|
||||
return $namespaceName . '\\' . $nameFromUse;
|
||||
}
|
||||
/**
|
||||
* @param array<Use_|GroupUse> $uses
|
||||
*/
|
||||
private function resolveNamefromUse(array $uses, string $name) : string
|
||||
{
|
||||
foreach ($uses as $use) {
|
||||
$prefix = $this->useImportsResolver->resolvePrefix($use);
|
||||
foreach ($use->uses as $useUse) {
|
||||
if ($useUse->alias instanceof Identifier) {
|
||||
continue;
|
||||
}
|
||||
$lastName = $useUse->name->getLast();
|
||||
if ($lastName === $name) {
|
||||
return $prefix . $useUse->name->toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
|
@ -90,9 +90,11 @@ final class IdentifierPhpDocTypeMapper implements PhpDocTypeMapperInterface
|
||||
if ($loweredName === 'iterable') {
|
||||
return new IterableType(new MixedType(), new MixedType());
|
||||
}
|
||||
$withPreslash = \false;
|
||||
if (\strncmp($identifierTypeNode->name, '\\', \strlen('\\')) === 0) {
|
||||
$typeWithoutPreslash = Strings::substring($identifierTypeNode->name, 1);
|
||||
$objectType = new FullyQualifiedObjectType($typeWithoutPreslash);
|
||||
$withPreslash = \true;
|
||||
} else {
|
||||
if ($identifierTypeNode->name === 'scalar') {
|
||||
// pseudo type, see https://www.php.net/manual/en/language.types.intro.php
|
||||
@ -103,7 +105,7 @@ final class IdentifierPhpDocTypeMapper implements PhpDocTypeMapperInterface
|
||||
$objectType = new ObjectType($identifierTypeNode->name);
|
||||
}
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
return $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType($node, $objectType, $scope);
|
||||
return $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType($node, $objectType, $scope, $withPreslash);
|
||||
}
|
||||
/**
|
||||
* @return \PHPStan\Type\MixedType|\Rector\StaticTypeMapper\ValueObject\Type\SelfObjectType
|
||||
|
Loading…
x
Reference in New Issue
Block a user