Skip to content

Commit 6f19617

Browse files
phpstan-botclaude
andcommitted
Iterate over union inner types instead of constructing new ObjectType from class names
This preserves GenericObjectType and TemplateObjectType information that was lost when creating `new ObjectType($className)` from just the class name string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a8d4a09 commit 6f19617

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

src/Analyser/ExprHandler/Helper/MethodCallReturnTypeHelper.php

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPStan\Type\ObjectType;
1313
use PHPStan\Type\Type;
1414
use PHPStan\Type\TypeCombinator;
15+
use PHPStan\Type\UnionType;
1516
use function count;
1617

1718
#[AutowiredService]
@@ -55,43 +56,46 @@ public function methodCallReturnType(
5556
$resolvedTypes = [];
5657
$allClassNames = $typeWithMethod->getObjectClassNames();
5758
$handledClassNames = [];
58-
foreach ($allClassNames as $className) {
59-
$classType = new ObjectType($className);
60-
if (!$classType->hasMethod($methodName)->yes()) {
59+
$innerTypes = $typeWithMethod instanceof UnionType ? $typeWithMethod->getTypes() : [$typeWithMethod];
60+
foreach ($innerTypes as $innerType) {
61+
$classNames = $innerType->getObjectClassNames();
62+
if ($classNames === [] || !$innerType->hasMethod($methodName)->yes()) {
6163
continue;
6264
}
63-
$classMethodReflection = $classType->getMethod($methodName, $scope);
64-
if ($normalizedMethodCall instanceof MethodCall) {
65-
foreach ($this->dynamicReturnTypeExtensionRegistryProvider->getRegistry()->getDynamicMethodReturnTypeExtensionsForClass($className) as $dynamicMethodReturnTypeExtension) {
66-
if (!$dynamicMethodReturnTypeExtension->isMethodSupported($classMethodReflection)) {
67-
continue;
68-
}
65+
$classMethodReflection = $innerType->getMethod($methodName, $scope);
66+
foreach ($classNames as $className) {
67+
if ($normalizedMethodCall instanceof MethodCall) {
68+
foreach ($this->dynamicReturnTypeExtensionRegistryProvider->getRegistry()->getDynamicMethodReturnTypeExtensionsForClass($className) as $dynamicMethodReturnTypeExtension) {
69+
if (!$dynamicMethodReturnTypeExtension->isMethodSupported($classMethodReflection)) {
70+
continue;
71+
}
6972

70-
$resolvedType = $dynamicMethodReturnTypeExtension->getTypeFromMethodCall($classMethodReflection, $normalizedMethodCall, $scope);
71-
if ($resolvedType === null) {
72-
continue;
73-
}
73+
$resolvedType = $dynamicMethodReturnTypeExtension->getTypeFromMethodCall($classMethodReflection, $normalizedMethodCall, $scope);
74+
if ($resolvedType === null) {
75+
continue;
76+
}
7477

75-
$resolvedTypes[] = $resolvedType;
76-
$handledClassNames[] = $className;
77-
}
78-
} else {
79-
foreach ($this->dynamicReturnTypeExtensionRegistryProvider->getRegistry()->getDynamicStaticMethodReturnTypeExtensionsForClass($className) as $dynamicStaticMethodReturnTypeExtension) {
80-
if (!$dynamicStaticMethodReturnTypeExtension->isStaticMethodSupported($classMethodReflection)) {
81-
continue;
78+
$resolvedTypes[] = $resolvedType;
79+
$handledClassNames[] = $className;
8280
}
81+
} else {
82+
foreach ($this->dynamicReturnTypeExtensionRegistryProvider->getRegistry()->getDynamicStaticMethodReturnTypeExtensionsForClass($className) as $dynamicStaticMethodReturnTypeExtension) {
83+
if (!$dynamicStaticMethodReturnTypeExtension->isStaticMethodSupported($classMethodReflection)) {
84+
continue;
85+
}
8386

84-
$resolvedType = $dynamicStaticMethodReturnTypeExtension->getTypeFromStaticMethodCall(
85-
$classMethodReflection,
86-
$normalizedMethodCall,
87-
$scope,
88-
);
89-
if ($resolvedType === null) {
90-
continue;
91-
}
87+
$resolvedType = $dynamicStaticMethodReturnTypeExtension->getTypeFromStaticMethodCall(
88+
$classMethodReflection,
89+
$normalizedMethodCall,
90+
$scope,
91+
);
92+
if ($resolvedType === null) {
93+
continue;
94+
}
9295

93-
$resolvedTypes[] = $resolvedType;
94-
$handledClassNames[] = $className;
96+
$resolvedTypes[] = $resolvedType;
97+
$handledClassNames[] = $className;
98+
}
9599
}
96100
}
97101
}

0 commit comments

Comments
 (0)