Skip to content

Commit 5ab6870

Browse files
committed
[BUGFIX] Make QueryResultToArrayDynamicReturnTypeExtension work with CompoundType
Resolves #103
1 parent 5f72c48 commit 5ab6870

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

src/Type/QueryResultToArrayDynamicReturnTypeExtension.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1010
use PHPStan\Type\ErrorType;
1111
use PHPStan\Type\Generic\GenericObjectType;
12+
use PHPStan\Type\Generic\TemplateType;
1213
use PHPStan\Type\IntegerType;
1314
use PHPStan\Type\ObjectType;
1415
use PHPStan\Type\Type;
16+
use PHPStan\Type\TypeTraverser;
1517
use SaschaEgerer\PhpstanTypo3\Helpers\Typo3ClassNamingUtilityTrait;
1618
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
1719

@@ -38,12 +40,14 @@ public function getTypeFromMethodCall(
3840
Scope $scope
3941
): Type
4042
{
41-
$classReflection = $scope->getClassReflection();
43+
$resultType = $this->getGenericTypes(
44+
$scope->getType($methodCall->var)
45+
)[0] ?? null;
4246

43-
$resultType = $scope->getType($methodCall->var);
4447
if ($resultType instanceof GenericObjectType) {
4548
$modelType = $resultType->getTypes();
4649
} else {
50+
$classReflection = $scope->getClassReflection();
4751
if ($classReflection === null) {
4852
return new ErrorType();
4953
}
@@ -58,4 +62,32 @@ public function getTypeFromMethodCall(
5862
return new ArrayType(new IntegerType(), $modelType[0]);
5963
}
6064

65+
/**
66+
* @return GenericObjectType[]
67+
*/
68+
private function getGenericTypes(Type $baseType): array
69+
{
70+
$genericObjectTypes = [];
71+
TypeTraverser::map($baseType, static function (Type $type, callable $traverse) use (&$genericObjectTypes): Type {
72+
if ($type instanceof GenericObjectType) {
73+
$resolvedType = TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
74+
if ($type instanceof TemplateType) {
75+
return $traverse($type->getBound());
76+
}
77+
return $traverse($type);
78+
});
79+
if (!$resolvedType instanceof GenericObjectType) {
80+
throw new \PHPStan\ShouldNotHappenException();
81+
}
82+
$genericObjectTypes[] = $resolvedType;
83+
$traverse($type);
84+
return $type;
85+
}
86+
$traverse($type);
87+
return $type;
88+
});
89+
90+
return $genericObjectTypes;
91+
}
92+
6193
}

0 commit comments

Comments
 (0)