Skip to content

Commit 31f74fe

Browse files
committed
Revert "Improve QueryResultDynamicReturnTypeExtension"
This reverts commit 5a3bbc1.
1 parent 5a3bbc1 commit 31f74fe

File tree

2 files changed

+31
-476
lines changed

2 files changed

+31
-476
lines changed

Diff for: src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php

+21-120
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,17 @@
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;
1514
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1615
use PHPStan\Type\GenericTypeVariableResolver;
1716
use PHPStan\Type\IntegerType;
1817
use PHPStan\Type\IterableType;
1918
use PHPStan\Type\MixedType;
2019
use PHPStan\Type\NullType;
21-
use PHPStan\Type\ObjectWithoutClassType;
2220
use PHPStan\Type\Type;
2321
use PHPStan\Type\TypeCombinator;
24-
use PHPStan\Type\TypeTraverser;
2522
use PHPStan\Type\TypeWithClassName;
2623
use PHPStan\Type\VoidType;
27-
use function count;
2824

2925
final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
3026
{
@@ -39,22 +35,14 @@ final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturn
3935
'getSingleResult' => 0,
4036
];
4137

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-
4938
public function getClass(): string
5039
{
5140
return AbstractQuery::class;
5241
}
5342

5443
public function isMethodSupported(MethodReflection $methodReflection): bool
5544
{
56-
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()])
57-
|| isset(self::METHOD_HYDRATION_MODE[$methodReflection->getName()]);
45+
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()]);
5846
}
5947

6048
public function getTypeFromMethodCall(
@@ -65,23 +53,21 @@ public function getTypeFromMethodCall(
6553
{
6654
$methodName = $methodReflection->getName();
6755

68-
if (isset(self::METHOD_HYDRATION_MODE[$methodName])) {
69-
$hydrationMode = new ConstantIntegerType(self::METHOD_HYDRATION_MODE[$methodName]);
70-
} elseif (isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
71-
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
72-
$args = $methodCall->getArgs();
56+
if (!isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
57+
throw new ShouldNotHappenException();
58+
}
59+
60+
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
61+
$args = $methodCall->getArgs();
7362

74-
if (isset($args[$argIndex])) {
75-
$hydrationMode = $scope->getType($args[$argIndex]->value);
76-
} else {
77-
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
78-
$methodReflection->getVariants()
79-
);
80-
$parameter = $parametersAcceptor->getParameters()[$argIndex];
81-
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
82-
}
63+
if (isset($args[$argIndex])) {
64+
$hydrationMode = $scope->getType($args[$argIndex]->value);
8365
} else {
84-
throw new ShouldNotHappenException();
66+
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
67+
$methodReflection->getVariants()
68+
);
69+
$parameter = $parametersAcceptor->getParameters()[$argIndex];
70+
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
8571
}
8672

8773
$queryType = $scope->getType($methodCall->var);
@@ -145,32 +131,12 @@ private function getMethodReturnTypeForHydrationMode(
145131
return $this->originalReturnType($methodReflection);
146132
}
147133

148-
if (!$hydrationMode instanceof ConstantIntegerType) {
134+
if (!$this->isObjectHydrationMode($hydrationMode)) {
135+
// We support only HYDRATE_OBJECT. For other hydration modes, we
136+
// return the declared return type of the method.
149137
return $this->originalReturnType($methodReflection);
150138
}
151139

152-
switch ($hydrationMode->getValue()) {
153-
case AbstractQuery::HYDRATE_OBJECT:
154-
break;
155-
case AbstractQuery::HYDRATE_ARRAY:
156-
$queryResultType = $this->getArrayHydratedReturnType($queryResultType);
157-
break;
158-
case AbstractQuery::HYDRATE_SCALAR:
159-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
160-
break;
161-
case AbstractQuery::HYDRATE_SINGLE_SCALAR:
162-
$queryResultType = $this->getSingleScalarHydratedReturnType($queryResultType);
163-
break;
164-
case AbstractQuery::HYDRATE_SIMPLEOBJECT:
165-
$queryResultType = $this->getSimpleObjectHydratedReturnType($queryResultType);
166-
break;
167-
case AbstractQuery::HYDRATE_SCALAR_COLUMN:
168-
$queryResultType = $this->getScalarColumnHydratedReturnType($queryResultType);
169-
break;
170-
default:
171-
return $this->originalReturnType($methodReflection);
172-
}
173-
174140
switch ($methodReflection->getName()) {
175141
case 'getSingleResult':
176142
return $queryResultType;
@@ -195,78 +161,13 @@ private function getMethodReturnTypeForHydrationMode(
195161
}
196162
}
197163

198-
private function getArrayHydratedReturnType(Type $queryResultType): Type
164+
private function isObjectHydrationMode(Type $type): bool
199165
{
200-
return TypeTraverser::map(
201-
$queryResultType,
202-
static function (Type $type, callable $traverse): Type {
203-
$isObject = (new ObjectWithoutClassType())->isSuperTypeOf($type);
204-
if ($isObject->yes()) {
205-
return new ArrayType(new MixedType(), new MixedType());
206-
}
207-
if ($isObject->maybe()) {
208-
return new MixedType();
209-
}
210-
211-
return $traverse($type);
212-
}
213-
);
214-
}
215-
216-
private function getScalarHydratedReturnType(Type $queryResultType): Type
217-
{
218-
if (!$queryResultType instanceof ArrayType) {
219-
return new ArrayType(new MixedType(), new MixedType());
220-
}
221-
222-
$itemType = $queryResultType->getItemType();
223-
$hasNoObject = (new ObjectWithoutClassType())->isSuperTypeOf($itemType)->no();
224-
$hasNoArray = $itemType->isArray()->no();
225-
226-
if ($hasNoArray && $hasNoObject) {
227-
return $queryResultType;
228-
}
229-
230-
return new ArrayType(new MixedType(), new MixedType());
231-
}
232-
233-
private function getSimpleObjectHydratedReturnType(Type $queryResultType): Type
234-
{
235-
if ((new ObjectWithoutClassType())->isSuperTypeOf($queryResultType)->yes()) {
236-
return $queryResultType;
237-
}
238-
239-
return new MixedType();
240-
}
241-
242-
private function getSingleScalarHydratedReturnType(Type $queryResultType): Type
243-
{
244-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
245-
if (!$queryResultType instanceof ConstantArrayType) {
246-
return new ArrayType(new MixedType(), new MixedType());
247-
}
248-
249-
$values = $queryResultType->getValueTypes();
250-
if (count($values) !== 1) {
251-
return new ArrayType(new MixedType(), new MixedType());
252-
}
253-
254-
return $queryResultType;
255-
}
256-
257-
private function getScalarColumnHydratedReturnType(Type $queryResultType): Type
258-
{
259-
$queryResultType = $this->getScalarHydratedReturnType($queryResultType);
260-
if (!$queryResultType instanceof ConstantArrayType) {
261-
return new MixedType();
262-
}
263-
264-
$values = $queryResultType->getValueTypes();
265-
if (count($values) !== 1) {
266-
return new MixedType();
166+
if (!$type instanceof ConstantIntegerType) {
167+
return false;
267168
}
268169

269-
return $queryResultType->getFirstIterableValueType();
170+
return $type->getValue() === AbstractQuery::HYDRATE_OBJECT;
270171
}
271172

272173
private function originalReturnType(MethodReflection $methodReflection): Type

0 commit comments

Comments
 (0)