Skip to content

Commit 6051e97

Browse files
committed
Do not infer getArrayResult for now
1 parent 66d6943 commit 6051e97

File tree

4 files changed

+15
-175
lines changed

4 files changed

+15
-175
lines changed

src/Type/Doctrine/HydrationModeReturnTypeResolver.php

-48
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@
1010
use PHPStan\Type\IntegerRangeType;
1111
use PHPStan\Type\IntegerType;
1212
use PHPStan\Type\IterableType;
13-
use PHPStan\Type\MixedType;
1413
use PHPStan\Type\ObjectWithoutClassType;
1514
use PHPStan\Type\Type;
1615
use PHPStan\Type\TypeCombinator;
17-
use PHPStan\Type\TypeTraverser;
1816
use PHPStan\Type\TypeUtils;
19-
use PHPStan\Type\TypeWithClassName;
2017
use PHPStan\Type\VoidType;
2118

2219
class HydrationModeReturnTypeResolver
@@ -47,9 +44,6 @@ public function getMethodReturnTypeForHydrationMode(
4744
switch ($hydrationMode) {
4845
case AbstractQuery::HYDRATE_OBJECT:
4946
break;
50-
case AbstractQuery::HYDRATE_ARRAY:
51-
$queryResultType = $this->getArrayHydratedReturnType($queryResultType, $objectManager);
52-
break;
5347
case AbstractQuery::HYDRATE_SIMPLEOBJECT:
5448
$queryResultType = $this->getSimpleObjectHydratedReturnType($queryResultType);
5549
break;
@@ -90,48 +84,6 @@ public function getMethodReturnTypeForHydrationMode(
9084
}
9185
}
9286

93-
/**
94-
* When we're array-hydrating object, we're not sure of the shape of the array.
95-
* We could return `new ArrayType(new MixedType(), new MixedType())`
96-
* but the lack of precision in the array keys/values would give false positive.
97-
*
98-
* @see https://github.com/phpstan/phpstan-doctrine/pull/412#issuecomment-1497092934
99-
*/
100-
private function getArrayHydratedReturnType(Type $queryResultType, ?ObjectManager $objectManager): ?Type
101-
{
102-
$mixedFound = false;
103-
$queryResultType = TypeTraverser::map(
104-
$queryResultType,
105-
static function (Type $type, callable $traverse) use ($objectManager, &$mixedFound): Type {
106-
$isObject = (new ObjectWithoutClassType())->isSuperTypeOf($type);
107-
if ($isObject->no()) {
108-
return $traverse($type);
109-
}
110-
if (
111-
$isObject->maybe()
112-
|| !$type instanceof TypeWithClassName
113-
|| $objectManager === null
114-
) {
115-
$mixedFound = true;
116-
117-
return new MixedType();
118-
}
119-
120-
/** @var class-string $className */
121-
$className = $type->getClassName();
122-
if (!$objectManager->getMetadataFactory()->hasMetadataFor($className)) {
123-
return $traverse($type);
124-
}
125-
126-
$mixedFound = true;
127-
128-
return new MixedType();
129-
}
130-
);
131-
132-
return $mixedFound ? null : $queryResultType;
133-
}
134-
13587
private function getSimpleObjectHydratedReturnType(Type $queryResultType): ?Type
13688
{
13789
if ((new ObjectWithoutClassType())->isSuperTypeOf($queryResultType)->yes()) {

src/Type/Doctrine/Query/QueryResultDynamicReturnTypeExtension.php

+15-22
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ final class QueryResultDynamicReturnTypeExtension implements DynamicMethodReturn
2828
'getSingleResult' => 0,
2929
];
3030

31-
private const METHOD_HYDRATION_MODE = [
32-
'getArrayResult' => AbstractQuery::HYDRATE_ARRAY,
33-
];
34-
3531
/** @var ObjectMetadataResolver */
3632
private $objectMetadataResolver;
3733

@@ -54,8 +50,7 @@ public function getClass(): string
5450

5551
public function isMethodSupported(MethodReflection $methodReflection): bool
5652
{
57-
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()])
58-
|| isset(self::METHOD_HYDRATION_MODE[$methodReflection->getName()]);
53+
return isset(self::METHOD_HYDRATION_MODE_ARG[$methodReflection->getName()]);
5954
}
6055

6156
public function getTypeFromMethodCall(
@@ -66,25 +61,23 @@ public function getTypeFromMethodCall(
6661
{
6762
$methodName = $methodReflection->getName();
6863

69-
if (isset(self::METHOD_HYDRATION_MODE[$methodName])) {
70-
$hydrationMode = new ConstantIntegerType(self::METHOD_HYDRATION_MODE[$methodName]);
71-
} elseif (isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
72-
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
73-
$args = $methodCall->getArgs();
74-
75-
if (isset($args[$argIndex])) {
76-
$hydrationMode = $scope->getType($args[$argIndex]->value);
77-
} else {
78-
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
79-
$methodReflection->getVariants()
80-
);
81-
$parameter = $parametersAcceptor->getParameters()[$argIndex];
82-
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
83-
}
84-
} else {
64+
if (!isset(self::METHOD_HYDRATION_MODE_ARG[$methodName])) {
8565
throw new ShouldNotHappenException();
8666
}
8767

68+
$argIndex = self::METHOD_HYDRATION_MODE_ARG[$methodName];
69+
$args = $methodCall->getArgs();
70+
71+
if (isset($args[$argIndex])) {
72+
$hydrationMode = $scope->getType($args[$argIndex]->value);
73+
} else {
74+
$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
75+
$methodReflection->getVariants()
76+
);
77+
$parameter = $parametersAcceptor->getParameters()[$argIndex];
78+
$hydrationMode = $parameter->getDefaultValue() ?? new NullType();
79+
}
80+
8881
$queryType = $scope->getType($methodCall->var);
8982

9083
if (!$hydrationMode instanceof ConstantIntegerType) {

tests/Type/Doctrine/Query/QueryResultTypeWalkerHydrationModeTest.php

-70
Original file line numberDiff line numberDiff line change
@@ -138,42 +138,6 @@ public static function getTestData(): iterable
138138
Query::HYDRATE_SIMPLEOBJECT,
139139
];
140140

141-
yield 'getResult(array), full entity' => [
142-
new MixedType(),
143-
'
144-
SELECT s
145-
FROM QueryResult\Entities\Simple s
146-
',
147-
'getResult',
148-
Query::HYDRATE_ARRAY,
149-
];
150-
151-
yield 'getResult(array), fields' => [
152-
self::list(self::constantArray([
153-
[new ConstantStringType('decimalColumn'), self::numericString()],
154-
[new ConstantStringType('floatColumn'), new FloatType()],
155-
])),
156-
'
157-
SELECT s.decimalColumn, s.floatColumn
158-
FROM QueryResult\Entities\Simple s
159-
',
160-
'getResult',
161-
Query::HYDRATE_ARRAY,
162-
];
163-
164-
yield 'getResult(array), expressions' => [
165-
self::list(self::constantArray([
166-
[new ConstantStringType('decimalColumn'), self::floatOrIntOrStringified()],
167-
[new ConstantStringType('floatColumn'), self::floatOrStringified()],
168-
])),
169-
'
170-
SELECT -s.decimalColumn as decimalColumn, -s.floatColumn as floatColumn
171-
FROM QueryResult\Entities\Simple s
172-
',
173-
'getResult',
174-
Query::HYDRATE_ARRAY,
175-
];
176-
177141
yield 'getResult(object), fields' => [
178142
self::list(self::constantArray([
179143
[new ConstantStringType('decimalColumn'), self::numericString()],
@@ -246,16 +210,6 @@ public static function getTestData(): iterable
246210
Query::HYDRATE_SIMPLEOBJECT,
247211
];
248212

249-
yield 'toIterable(array), full entity' => [
250-
new MixedType(),
251-
'
252-
SELECT s
253-
FROM QueryResult\Entities\Simple s
254-
',
255-
'toIterable',
256-
Query::HYDRATE_ARRAY,
257-
];
258-
259213
yield 'getArrayResult(), full entity' => [
260214
new MixedType(),
261215
'
@@ -265,30 +219,6 @@ public static function getTestData(): iterable
265219
'getArrayResult',
266220
];
267221

268-
yield 'getArrayResult(), fields' => [
269-
self::list(self::constantArray([
270-
[new ConstantStringType('decimalColumn'), self::numericString()],
271-
[new ConstantStringType('floatColumn'), new FloatType()],
272-
])),
273-
'
274-
SELECT s.decimalColumn, s.floatColumn
275-
FROM QueryResult\Entities\Simple s
276-
',
277-
'getArrayResult',
278-
];
279-
280-
yield 'getArrayResult(), expressions' => [
281-
self::list(self::constantArray([
282-
[new ConstantStringType('decimalColumn'), self::floatOrIntOrStringified()],
283-
[new ConstantStringType('floatColumn'), self::floatOrStringified()],
284-
])),
285-
'
286-
SELECT -s.decimalColumn as decimalColumn, -s.floatColumn as floatColumn
287-
FROM QueryResult\Entities\Simple s
288-
',
289-
'getArrayResult',
290-
];
291-
292222
yield 'getResult(single_scalar), decimal field' => [
293223
new MixedType(),
294224
'

tests/Type/Doctrine/data/QueryResult/queryResult.php

-35
Original file line numberDiff line numberDiff line change
@@ -188,41 +188,6 @@ public function testReturnTypeOfQueryMethodsWithExplicitArrayHydrationMode(Entit
188188
'mixed',
189189
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)
190190
);
191-
192-
193-
$query = $em->createQuery('
194-
SELECT m.intColumn, m.stringNullColumn, m.datetimeColumn
195-
FROM QueryResult\Entities\Many m
196-
');
197-
198-
assertType(
199-
'list<array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}>',
200-
$query->getResult(AbstractQuery::HYDRATE_ARRAY)
201-
);
202-
assertType(
203-
'list<array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}>',
204-
$query->getArrayResult()
205-
);
206-
assertType(
207-
'list<array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}>',
208-
$query->execute(null, AbstractQuery::HYDRATE_ARRAY)
209-
);
210-
assertType(
211-
'list<array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}>',
212-
$query->executeIgnoreQueryCache(null, AbstractQuery::HYDRATE_ARRAY)
213-
);
214-
assertType(
215-
'list<array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}>',
216-
$query->executeUsingQueryCache(null, AbstractQuery::HYDRATE_ARRAY)
217-
);
218-
assertType(
219-
'array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}',
220-
$query->getSingleResult(AbstractQuery::HYDRATE_ARRAY)
221-
);
222-
assertType(
223-
'array{intColumn: int, stringNullColumn: string|null, datetimeColumn: DateTime}|null',
224-
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)
225-
);
226191
}
227192

228193

0 commit comments

Comments
 (0)