Skip to content

Commit 1d12f65

Browse files
janedbalondrejmirtes
authored andcommitted
ObjectType: fix hasConstant behaviour
1 parent fe4bf2c commit 1d12f65

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/Type/ObjectType.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -869,14 +869,20 @@ public function canAccessConstants(): TrinaryLogic
869869

870870
public function hasConstant(string $constantName): TrinaryLogic
871871
{
872-
$class = $this->getClassReflection();
873-
if ($class === null) {
872+
$classReflection = $this->getClassReflection();
873+
if ($classReflection === null) {
874+
return TrinaryLogic::createMaybe();
875+
}
876+
877+
if ($classReflection->hasConstant($constantName)) {
878+
return TrinaryLogic::createYes();
879+
}
880+
881+
if ($classReflection->isFinal()) {
874882
return TrinaryLogic::createNo();
875883
}
876884

877-
return TrinaryLogic::createFromBoolean(
878-
$class->hasConstant($constantName),
879-
);
885+
return TrinaryLogic::createMaybe();
880886
}
881887

882888
public function getConstant(string $constantName): ClassConstantReflection

tests/PHPStan/Type/ObjectTypeTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,41 @@ public function testAccepts(
557557
);
558558
}
559559

560+
public static function dataHasConstant(): Iterator
561+
{
562+
yield [
563+
new ObjectType(DateTimeImmutable::class),
564+
'ATOM',
565+
TrinaryLogic::createYes(),
566+
];
567+
yield [
568+
new ObjectType(DateTimeImmutable::class),
569+
'CUSTOM',
570+
TrinaryLogic::createMaybe(),
571+
];
572+
yield [
573+
new ObjectType(Closure::class), // is final
574+
'CUSTOM',
575+
TrinaryLogic::createNo(),
576+
];
577+
yield [
578+
new ObjectType('SomeNonExistingClass'),
579+
'CUSTOM',
580+
TrinaryLogic::createMaybe(),
581+
];
582+
}
583+
584+
#[DataProvider('dataHasConstant')]
585+
public function testHasConstant(ObjectType $type, string $constantName, TrinaryLogic $expectedResult): void
586+
{
587+
$actualResult = $type->hasConstant($constantName);
588+
$this->assertSame(
589+
$expectedResult->describe(),
590+
$actualResult->describe(),
591+
sprintf('%s -> hasConstant("%s")', $type->describe(VerbosityLevel::precise()), $constantName),
592+
);
593+
}
594+
560595
public function testGetClassReflectionOfGenericClass(): void
561596
{
562597
$objectType = new ObjectType(Traversable::class);

0 commit comments

Comments
 (0)