Add SameNamespacedTypeSpecifier (#2169)

* narrow to FQN

* add ObjectTypeSpecifier

* require Scope

* add SameNamespacedTypeSpecifier
This commit is contained in:
Tomas Votruba 2022-04-26 10:06:10 +02:00 committed by GitHub
parent 148dda778c
commit 43aa4d91f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 26 deletions

View File

@ -43,11 +43,6 @@ final class ObjectTypeSpecifier
ObjectType $objectType,
Scope|null $scope
): TypeWithClassName | NonExistingObjectType | UnionType | MixedType {
$sameNamespacedFullyQualifiedObjectType = $this->matchSameNamespacedObjectType($node, $objectType);
if ($sameNamespacedFullyQualifiedObjectType !== null) {
return $sameNamespacedFullyQualifiedObjectType;
}
if ($scope instanceof Scope) {
foreach ($this->typeWithClassTypeSpecifiers as $typeWithClassTypeSpecifier) {
if ($typeWithClassTypeSpecifier->match($objectType, $scope)) {
@ -194,27 +189,6 @@ final class ObjectTypeSpecifier
return null;
}
private function matchSameNamespacedObjectType(Node $node, ObjectType $objectType): ?FullyQualifiedObjectType
{
$scope = $node->getAttribute(AttributeKey::SCOPE);
if (! $scope instanceof Scope) {
return null;
}
$namespaceName = $scope->getNamespace();
if ($namespaceName === null) {
return null;
}
$namespacedObject = $namespaceName . '\\' . ltrim($objectType->getClassName(), '\\');
if ($this->reflectionProvider->hasClass($namespacedObject)) {
return new FullyQualifiedObjectType($namespacedObject);
}
return null;
}
private function matchPartialNamespaceObjectType(ObjectType $objectType, UseUse $useUse): ?ShortenedObjectType
{
// partial namespace

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Rector\TypeDeclaration\PHPStan\TypeSpecifier;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use PHPStan\Type\TypeWithClassName;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\TypeDeclaration\Contract\PHPStan\TypeWithClassTypeSpecifierInterface;
final class SameNamespacedTypeSpecifier implements TypeWithClassTypeSpecifierInterface
{
public function __construct(
private readonly ReflectionProvider $reflectionProvider,
) {
}
public function match(ObjectType $objectType, Scope $scope): bool
{
$namespaceName = $scope->getNamespace();
if ($namespaceName === null) {
return false;
}
$namespacedClassName = $namespaceName . '\\' . ltrim($objectType->getClassName(), '\\');
return $this->reflectionProvider->hasClass($namespacedClassName);
}
public function resolveObjectReferenceType(ObjectType $objectType, Scope $scope): TypeWithClassName
{
$namespacedClassName = $scope->getNamespace() . '\\' . ltrim($objectType->getClassName(), '\\');
return new FullyQualifiedObjectType($namespacedClassName);
}
}