Skip to content

Commit f1499e5

Browse files
committed
Revert "Improve QueryResultDynamicReturnTypeExtension"
This reverts commit 03741b4.
1 parent dff01ff commit f1499e5

File tree

2 files changed

+31
-537
lines changed

2 files changed

+31
-537
lines changed

src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php

Lines changed: 21 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,14 @@
1010
use PHPStan\ShouldNotHappenException;
1111
use PHPStan\Type\Accessory\AccessoryArrayListType;
1212
use PHPStan\Type\ArrayType;
13-
use PHPStan\Type\Constant\ConstantArrayType;
1413
use PHPStan\Type\Constant\ConstantIntegerType;
15-
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
1614
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1715
use PHPStan\Type\IntegerType;
1816
use PHPStan\Type\IterableType;
19-
use PHPStan\Type\MixedType;
2017
use PHPStan\Type\NullType;
21-
use PHPStan\Type\ObjectWithoutClassType;
2218
use PHPStan\Type\Type;
2319
use PHPStan\Type\TypeCombinator;
24-
use PHPStan\Type\TypeTraverser;
25-
use PHPStan\Type\TypeWithClassName;
2620
use PHPStan\Type\VoidType;
27-
use function count;
2821

2922
final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
3023
{
@@ -39,32 +32,14 @@ final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturn
3932
'getSingleResult' => 0,
4033
];
4134

42-
private const METHOD_HYDRATION_MODE = [
43-
'getArrayResult' => AbstractQuery::HYDRATE_ARRAY,
44-
'getScalarResult' => AbstractQuery::HYDRATE_SCALAR,
45-
'getSingleColumnResult' => AbstractQuery::HYDRATE_SCALAR_COLUMN,
46-
'getSingleScalarResult' => AbstractQuery::HYDRATE_SINGLE_SCALAR,
47-
];
48-
49-
/** @var ObjectMetadataResolver */
50-
private $objectMetadataResolver;
51-
52-
public function __construct(
53-
ObjectMetadataResolver $objectMetadataResolver
54-
)
55-
{
56-
$this->objectMetadataResolver = $objectMetadataResolver;
57-
}
58-
5935
public function getClass(): string
6036
{
6137
return AbstractQuery::class;
6238
}
6339

6440
public function isMethodSupported(MethodReflection $methodReflection): bool
6541
{
66-
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()])
67-
|| isset(self::METHOD_HYDRATION_MODE[$methodReflection->getName()]);
42+
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()]);
6843
}
6944

7045
public function getTypeFromMethodCall(
@@ -75,23 +50,21 @@ public function getTypeFromMethodCall(
7550
{
7651
$methodName = $methodReflection->getName();
7752

78-
if (isset(self::METHOD_HYDRATION_MODE[$methodName])) {
79-
$hydrationMode = new ConstantIntegerType(self::METHOD_HYDRATION_MODE[$methodName]);
80-
} elseif (isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
81-
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
82-
$args = $methodCall->getArgs();
53+
if (!isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
54+
throw new ShouldNotHappenException();
55+
}
8356

84-
if (isset($args[$argIndex])) {
85-
$hydrationMode = $scope->getType($args[$argIndex]->value);
86-
} else {
87-
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
88-
$methodReflection->getVariants()
89-
);
90-
$parameter = $parametersAcceptor->getParameters()[$argIndex];
91-
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
92-
}
57+
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
58+
$args = $methodCall->getArgs();
59+
60+
if (isset($args[$argIndex])) {
61+
$hydrationMode = $scope->getType($args[$argIndex]->value);
9362
} else {
94-
throw new ShouldNotHappenException();
63+
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
64+
$methodReflection->getVariants()
65+
);
66+
$parameter = $parametersAcceptor->getParameters()[$argIndex];
67+
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
9568
}
9669

9770
$queryType = $scope->getType($methodCall->var);
@@ -125,34 +98,12 @@ private function getMethodReturnTypeForHydrationMode(
12598
return $this->originalReturnType($methodReflection);
12699
}
127100

128-
if (!$hydrationMode instanceof ConstantIntegerType) {
101+
if (!$this->isObjectHydrationMode($hydrationMode)) {
102+
// We support only HYDRATE_OBJECT. For other hydration modes, we
103+
// return the declared return type of the method.
129104
return $this->originalReturnType($methodReflection);
130105
}
131106

132-
$singleResult = false;
133-
switch ($hydrationMode->getValue()) {
134-
case AbstractQuery::HYDRATE_OBJECT:
135-
break;
136-
case AbstractQuery::HYDRATE_ARRAY:
137-
$queryResultType = $this->getArrayHydratedReturnType($queryResultType);
138-
break;
139-
case AbstractQuery::HYDRATE_SCALAR:
140-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
141-
break;
142-
case AbstractQuery::HYDRATE_SINGLE_SCALAR:
143-
$singleResult = true;
144-
$queryResultType = $this->getSingleScalarHydratedReturnType($queryResultType);
145-
break;
146-
case AbstractQuery::HYDRATE_SIMPLEOBJECT:
147-
$queryResultType = $this->getSimpleObjectHydratedReturnType($queryResultType);
148-
break;
149-
case AbstractQuery::HYDRATE_SCALAR_COLUMN:
150-
$queryResultType = $this->getScalarColumnHydratedReturnType($queryResultType);
151-
break;
152-
default:
153-
return $this->originalReturnType($methodReflection);
154-
}
155-
156107
switch ($methodReflection->getName()) {
157108
case 'getSingleResult':
158109
return $queryResultType;
@@ -164,10 +115,6 @@ private function getMethodReturnTypeForHydrationMode(
164115
$queryResultType
165116
);
166117
default:
167-
if ($singleResult) {
168-
return $queryResultType;
169-
}
170-
171118
if ($queryKeyType->isNull()->yes()) {
172119
return AccessoryArrayListType::intersectWith(new ArrayType(
173120
new IntegerType(),
@@ -181,86 +128,13 @@ private function getMethodReturnTypeForHydrationMode(
181128
}
182129
}
183130

184-
private function getArrayHydratedReturnType(Type $queryResultType): Type
185-
{
186-
$objectManager = $this->objectMetadataResolver->getObjectManager();
187-
188-
return TypeTraverser::map(
189-
$queryResultType,
190-
static function (Type $type, callable $traverse) use ($objectManager): Type {
191-
$isObject = (new ObjectWithoutClassType())->isSuperTypeOf($type);
192-
if ($isObject->no()) {
193-
return $traverse($type);
194-
}
195-
if (
196-
$isObject->maybe()
197-
|| !$type instanceof TypeWithClassName
198-
|| $objectManager === null
199-
) {
200-
return new MixedType();
201-
}
202-
203-
return $objectManager->getMetadataFactory()->hasMetadataFor($type->getClassName())
204-
? new ArrayType(new MixedType(), new MixedType())
205-
: $traverse($type);
206-
}
207-
);
208-
}
209-
210-
private function getScalarHydratedReturnType(Type $queryResultType): Type
211-
{
212-
if (!$queryResultType instanceof ArrayType) {
213-
return new ArrayType(new MixedType(), new MixedType());
214-
}
215-
216-
$itemType = $queryResultType->getItemType();
217-
$hasNoObject = (new ObjectWithoutClassType())->isSuperTypeOf($itemType)->no();
218-
$hasNoArray = $itemType->isArray()->no();
219-
220-
if ($hasNoArray && $hasNoObject) {
221-
return $queryResultType;
222-
}
223-
224-
return new ArrayType(new MixedType(), new MixedType());
225-
}
226-
227-
private function getSimpleObjectHydratedReturnType(Type $queryResultType): Type
131+
private function isObjectHydrationMode(Type $type): bool
228132
{
229-
if ((new ObjectWithoutClassType())->isSuperTypeOf($queryResultType)->yes()) {
230-
return $queryResultType;
231-
}
232-
233-
return new MixedType();
234-
}
235-
236-
private function getSingleScalarHydratedReturnType(Type $queryResultType): Type
237-
{
238-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
239-
if (!$queryResultType instanceof ConstantArrayType) {
240-
return new MixedType();
241-
}
242-
243-
$values = $queryResultType->getValueTypes();
244-
if (count($values) !== 1) {
245-
return new MixedType();
246-
}
247-
248-
return $queryResultType->getFirstIterableValueType();
249-
}
250-
251-
private function getScalarColumnHydratedReturnType(Type $queryResultType): Type
252-
{
253-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
254-
if (!$queryResultType instanceof ConstantArrayType) {
255-
return new MixedType();
256-
}
257-
258-
$values = $queryResultType->getValueTypes();
259-
if (count($values) !== 1) {
260-
return new MixedType();
133+
if (!$type instanceof ConstantIntegerType) {
134+
return false;
261135
}
262136

263-
return $queryResultType->getFirstIterableValueType();
137+
return $type->getValue() === AbstractQuery::HYDRATE_OBJECT;
264138
}
265139

266140
private function originalReturnType(MethodReflection $methodReflection): Type

0 commit comments

Comments
 (0)