Skip to content

Commit

Permalink
Fix intersection of two identical ThisType
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 8, 2023
1 parent b510dda commit d3e3292
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
32 changes: 32 additions & 0 deletions src/Type/ThisType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
use PHPStan\TrinaryLogic;
use function get_class;
use function sprintf;

/** @api */
Expand All @@ -23,6 +24,33 @@ public function __construct(
parent::__construct($classReflection, $subtractedType);
}

public function equals(Type $type): bool
{
if (get_class($type) !== static::class) {
return false;
}

/** @var ThisType $type */
$type = $type;
$equals = $this->getStaticObjectType()->equals($type->getStaticObjectType());
if (!$equals) {
return false;
}

if ($this->getTraitReflection() === null) {
if ($type->getTraitReflection() === null) {
return true;
}

return false;
}
if ($type->getTraitReflection() === null) {
return false;
}

return $this->getTraitReflection()->getName() === $type->getTraitReflection()->getName();
}

public function changeBaseClass(ClassReflection $classReflection): StaticType
{
return new self($classReflection, $this->getSubtractedType(), $this->traitReflection);
Expand Down Expand Up @@ -50,6 +78,10 @@ function () use ($callback): string {
public function isSuperTypeOf(Type $type): TrinaryLogic
{
if ($type instanceof self) {
if ($this->equals($type)) {
return TrinaryLogic::createYes();
}

return $this->getStaticObjectType()->isSuperTypeOf($type);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/data/trait-instance-of.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function test(): string {
}

if ($this instanceof ATrait1Class) {
assertType('*NEVER*', $this);
assertType('$this(TraitInstanceOf\FinalTrait2Class~TraitInstanceOf\FinalTrait2Class)&TraitInstanceOf\ATrait1Class', $this);
return 'hello world';
}

Expand Down
11 changes: 11 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
use Test\ClassWithToString;
use Test\FirstInterface;
use Throwable;
use TraitInstanceOf\ATrait1Class;
use TraitInstanceOf\Trait1;
use Traversable;
use function array_map;
use function array_reverse;
Expand Down Expand Up @@ -3978,6 +3980,15 @@ public function dataIntersect(): iterable
IntersectionType::class,
'$this(TraitInstanceOf\FinalTrait2Class~TraitInstanceOf\FinalOther)&NonExistantClass',
];

yield [
[
new ThisType($reflectionProvider->getClass(ATrait1Class::class), null, $reflectionProvider->getClass(Trait1::class)),
new ThisType($reflectionProvider->getClass(ATrait1Class::class), null, $reflectionProvider->getClass(Trait1::class)),
],
ThisType::class,
'$this(TraitInstanceOf\ATrait1Class)',
];
}

/**
Expand Down

0 comments on commit d3e3292

Please sign in to comment.