Skip to content

Commit 5aab962

Browse files
Try
1 parent b37f439 commit 5aab962

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/Type/Php/IsAFunctionTypeSpecifyingHelper.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Php;
44

55
use PHPStan\DependencyInjection\AutowiredService;
6+
use PHPStan\Reflection\ReflectionProvider;
67
use PHPStan\Type\ClassStringType;
78
use PHPStan\Type\Constant\ConstantStringType;
89
use PHPStan\Type\Generic\GenericClassStringType;
@@ -22,6 +23,12 @@
2223
final class IsAFunctionTypeSpecifyingHelper
2324
{
2425

26+
public function __construct(
27+
private ReflectionProvider $reflectionProvider,
28+
)
29+
{
30+
}
31+
2532
public function determineType(
2633
Type $objectOrClassType,
2734
Type $classType,
@@ -38,16 +45,18 @@ public function determineType(
3845
}
3946

4047
$isUncertain = $classType->getConstantStrings() === [];
48+
$reflectionProvider = $this->reflectionProvider;
4149

4250
$resultType = TypeTraverser::map(
4351
$classType,
44-
static function (Type $type, callable $traverse) use ($objectOrClassType, $objectOrClassTypeClassNames, $allowString, $allowSameClass, &$isUncertain): Type {
52+
static function (Type $type, callable $traverse) use ($reflectionProvider, $objectOrClassType, $objectOrClassTypeClassNames, $allowString, $allowSameClass, &$isUncertain): Type {
4553
if ($type instanceof UnionType || $type instanceof IntersectionType) {
4654
return $traverse($type);
4755
}
4856
if ($type instanceof ConstantStringType) {
57+
$typeValue = $type->getValue();
4958
if (!$allowSameClass) {
50-
if ($objectOrClassTypeClassNames === [$type->getValue()]) {
59+
if ($objectOrClassTypeClassNames === [$typeValue]) {
5160
$isSameClass = true;
5261
foreach ($objectOrClassType->getObjectClassReflections() as $classReflection) {
5362
if (!$classReflection->isFinal()) {
@@ -63,10 +72,20 @@ static function (Type $type, callable $traverse) use ($objectOrClassType, $objec
6372

6473
if (
6574
// For object, as soon as the exact same type is provided
66-
// in the list we cannot be sure of the result
67-
in_array($type->getValue(), $objectOrClassTypeClassNames, true)
75+
// in the list we cannot be sure of the result except for interfaces
76+
(
77+
in_array($typeValue, $objectOrClassTypeClassNames, true)
78+
&& (
79+
!$reflectionProvider->hasClass($typeValue)
80+
|| !$reflectionProvider->getClass($typeValue)->isInterface()
81+
)
82+
)
6883
// This also occurs for generic class string
69-
|| ($allowString && $objectOrClassTypeClassNames === [] && $objectOrClassType->isSuperTypeOf($type)->yes())
84+
|| (
85+
$allowString
86+
&& $objectOrClassTypeClassNames === []
87+
&& $objectOrClassType->isSuperTypeOf($type)->yes()
88+
)
7089
) {
7190
$isUncertain = true;
7291
}

0 commit comments

Comments
 (0)