Skip to content

Commit

Permalink
Fix alias object conflict with existing type (#2486)
Browse files Browse the repository at this point in the history
Fix alias object conflict with existing type
  • Loading branch information
TomasVotruba authored Dec 26, 2019
2 parents b9a5f8e + 4407860 commit cb70714
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use Rector\NodeTypeResolver\Exception\MissingTagException;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\StaticTypeMapper;
use Rector\PHPStan\Type\AliasedObjectType;
use Rector\PHPStan\Type\ShortenedObjectType;

/**
Expand Down Expand Up @@ -311,7 +312,9 @@ public function getVarType(Node $node): Type
return new MixedType();
}

return $this->createPhpDocInfoFromNode($node)->getVarType();
$phpDocInfo = $this->createPhpDocInfoFromNode($node);

return $phpDocInfo->getVarType();
}

public function removeTagByName(PhpDocInfo $phpDocInfo, string $tagName): void
Expand Down Expand Up @@ -539,6 +542,19 @@ public function getParamTypeByName(FunctionLike $functionLike, string $paramName
*/
private function areTypesEquals(Type $firstType, Type $secondType): bool
{
// aliases and types
if ($firstType instanceof AliasedObjectType && $secondType instanceof ObjectType) {
if ($firstType->getFullyQualifiedClass() === $secondType->getClassName()) {
return true;
}
}

if ($secondType instanceof AliasedObjectType && $firstType instanceof ObjectType) {
if ($secondType->getFullyQualifiedClass() === $firstType->getClassName()) {
return true;
}
}

$firstTypeHash = $this->staticTypeMapper->createTypeHash($firstType);
$secondTypeHash = $this->staticTypeMapper->createTypeHash($secondType);

Expand Down
15 changes: 15 additions & 0 deletions packages/PHPStan/src/Type/AliasedObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,19 @@

final class AliasedObjectType extends ObjectType
{
/**
* @var string
*/
private $fullyQualifiedClass;

public function __construct(string $alias, string $fullyQualifiedClass)
{
parent::__construct($alias);
$this->fullyQualifiedClass = $fullyQualifiedClass;
}

public function getFullyQualifiedClass(): string
{
return $this->fullyQualifiedClass;
}
}
14 changes: 11 additions & 3 deletions packages/TypeDeclaration/src/PHPStan/Type/ObjectTypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function narrowToFullyQualifiedOrAlaisedObjectType(Node $node, ObjectType
}

$aliasedObjectType = $this->matchAliasedObjectType($node, $objectType);

if ($aliasedObjectType !== null) {
return $aliasedObjectType;
}
Expand Down Expand Up @@ -68,11 +69,18 @@ private function matchAliasedObjectType(Node $node, ObjectType $objectType): ?Al
}

$useName = $useUse->name->toString();
if ($useName !== $objectType->getClassName()) {
continue;
$alias = $useUse->alias->toString();
$fullyQualifiedName = $useUse->name->toString();

// A. is alias in use statement matching this class alias
if ($useUse->alias->toString() === $objectType->getClassName()) {
return new AliasedObjectType($alias, $fullyQualifiedName);
}

return new AliasedObjectType($useUse->alias->toString());
// B. is aliased classes matching the class name
if ($useName === $objectType->getClassName()) {
return new AliasedObjectType($alias, $fullyQualifiedName);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private function resolveParamTypeToPHPStanType(Param $param): Type

// special case for alias
if ($param->type instanceof FullyQualified) {
$type = $this->resolveFullyQualifiedOrAlaisedObjectType($param);
$type = $this->resolveFullyQualifiedOrAliasedObjectType($param);
if ($type !== null) {
return $type;
}
Expand Down Expand Up @@ -192,7 +192,7 @@ private function isParamNullable(Param $param): bool
return false;
}

private function resolveFullyQualifiedOrAlaisedObjectType(Param $param): ?Type
private function resolveFullyQualifiedOrAliasedObjectType(Param $param): ?Type
{
if ($param->type === null) {
return null;
Expand All @@ -216,7 +216,8 @@ private function resolveFullyQualifiedOrAlaisedObjectType(Param $param): ?Type
return new FullyQualifiedObjectType($className);
}

return new AliasedObjectType($originalName->toString());
// @note: $fullyQualifiedName is a guess, needs real life test
return new AliasedObjectType($originalName->toString(), $fullyQualifiedName);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Rector\TypeDeclaration\Tests\Rector\Property\CompleteVarDocTypePropertyRector\Fixture;

use Rector\TypeDeclaration\Tests\Rector\Property\CompleteVarDocTypePropertyRector\Source\SomeService as SignalSlotDispatcher;

class SlotReplacement
{
/**
* @var SignalSlotDispatcher
*/
protected $signalSlotDispatcher;

public function __construct(SignalSlotDispatcher $signalSlotDispatcher)
{
$this->signalSlotDispatcher = $signalSlotDispatcher;
}
}

0 comments on commit cb70714

Please sign in to comment.