Skip to content

Commit f9f5254

Browse files
authored
Merge pull request #14 from ervaude/queryExecute
[FEATURE] Provide dynamic return types for Query->execute() calls
2 parents e51a237 + 9868d23 commit f9f5254

4 files changed

+124
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ This extension provides the following features:
88
* Provides correct return type for `\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance()`.
99
* Provides correct return type for `\TYPO3\CMS\Extbase\Object\ObjectManagerInterface->get()`.
1010
* Provides correct return type for `\TYPO3\CMS\Extbase\Object\ObjectManager->get()`.
11+
* Provides correct return type for `\TYPO3\CMS\Extbase\Persistence\Generic\Query->execute()`.
12+
* Provides correct return type for `\TYPO3\CMS\Extbase\Persistence\QueryInterface->execute()`.
1113

1214
<details>
1315
<summary>Details on GeneralUtility::makeInstance()</summary>

extension.neon

+8
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ services:
1919
class: FriendsOfTYPO3\PHPStan\TYPO3\Type\ObjectManagerInterfaceGetDynamicReturnTypeExtension
2020
tags:
2121
- phpstan.broker.dynamicMethodReturnTypeExtension
22+
-
23+
class: FriendsOfTYPO3\PHPStan\TYPO3\Type\QueryExecuteReturnTypeExtension
24+
tags:
25+
- phpstan.broker.dynamicMethodReturnTypeExtension
26+
-
27+
class: FriendsOfTYPO3\PHPStan\TYPO3\Type\QueryInterfaceExecuteReturnTypeExtension
28+
tags:
29+
- phpstan.broker.dynamicMethodReturnTypeExtension
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace FriendsOfTYPO3\PHPStan\TYPO3\Type;
5+
6+
use PhpParser\Node\Expr\ClassConstFetch;
7+
use PhpParser\Node\Expr\MethodCall;
8+
use PhpParser\Node\Scalar\String_ as StringNode;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Type\ArrayType;
12+
use PHPStan\Type\Constant\ConstantBooleanType;
13+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
14+
use PHPStan\Type\MixedType;
15+
use PHPStan\Type\ObjectType;
16+
use PHPStan\Type\StringType;
17+
use TYPO3\CMS\Extbase\Persistence\Generic\Query;
18+
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
19+
20+
class QueryExecuteReturnTypeExtension implements DynamicMethodReturnTypeExtension
21+
{
22+
public function getClass(): string
23+
{
24+
return Query::class;
25+
}
26+
27+
public function isMethodSupported(MethodReflection $methodReflection): bool
28+
{
29+
return $methodReflection->getName() === 'execute';
30+
}
31+
32+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): \PHPStan\Type\Type
33+
{
34+
if (empty($methodCall->args)) {
35+
return new ObjectType(QueryResultInterface::class);
36+
}
37+
38+
$firstArgument = $scope->getType($methodCall->args[0]->value);
39+
if (!$firstArgument instanceof ConstantBooleanType) {
40+
throw new \InvalidArgumentException(
41+
'Argument $returnRawQueryResult is not a boolean.',
42+
1584879250
43+
);
44+
}
45+
46+
$returnRawQueryResult = $firstArgument->getValue();
47+
if ($returnRawQueryResult) {
48+
return new ArrayType(
49+
new StringType(),
50+
new MixedType()
51+
);
52+
}
53+
54+
return new ObjectType(QueryResultInterface::class);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace FriendsOfTYPO3\PHPStan\TYPO3\Type;
5+
6+
7+
use PhpParser\Node\Expr\ClassConstFetch;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PhpParser\Node\Scalar\String_ as StringNode;
10+
use PHPStan\Analyser\Scope;
11+
use PHPStan\Reflection\MethodReflection;
12+
use PHPStan\Type\ArrayType;
13+
use PHPStan\Type\Constant\ConstantBooleanType;
14+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
15+
use PHPStan\Type\MixedType;
16+
use PHPStan\Type\ObjectType;
17+
use PHPStan\Type\StringType;
18+
use TYPO3\CMS\Extbase\Persistence\Generic\Query;
19+
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
20+
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
21+
22+
class QueryInterfaceExecuteReturnTypeExtension implements DynamicMethodReturnTypeExtension
23+
{
24+
public function getClass(): string
25+
{
26+
return QueryInterface::class;
27+
}
28+
29+
public function isMethodSupported(MethodReflection $methodReflection): bool
30+
{
31+
return $methodReflection->getName() === 'execute';
32+
}
33+
34+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): \PHPStan\Type\Type
35+
{
36+
if (empty($methodCall->args)) {
37+
return new ObjectType(QueryResultInterface::class);
38+
}
39+
40+
$firstArgument = $scope->getType($methodCall->args[0]->value);
41+
if (!$firstArgument instanceof ConstantBooleanType) {
42+
throw new \InvalidArgumentException(
43+
'Argument $returnRawQueryResult is not a boolean.',
44+
1584879250
45+
);
46+
}
47+
48+
$returnRawQueryResult = $firstArgument->getValue();
49+
if ($returnRawQueryResult) {
50+
return new ArrayType(
51+
new StringType(),
52+
new MixedType()
53+
);
54+
}
55+
56+
return new ObjectType(QueryResultInterface::class);
57+
}
58+
}

0 commit comments

Comments
 (0)