Skip to content

Commit 25e9c67

Browse files
staabmclxmstaab
andauthored
doctrine-dbal: use proper interface types (#150)
Co-authored-by: Markus Staab <[email protected]>
1 parent 42678c7 commit 25e9c67

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

config/DoctrineDbal.stub

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ namespace Doctrine\DBAL;
88
class Result
99
{
1010
}
11+
12+
/**
13+
* @template TValue
14+
*/
15+
class Statement
16+
{
17+
}

src/Extensions/DoctrineConnectionDynamicReturnTypeExtension.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace staabm\PHPStanDba\Extensions;
66

7-
use Doctrine\DBAL\Driver\Connection;
7+
use Doctrine\DBAL\Connection;
88
use Doctrine\DBAL\Result;
9+
use Doctrine\DBAL\Statement;
910
use PhpParser\Node\Expr;
1011
use PhpParser\Node\Expr\MethodCall;
1112
use PHPStan\Analyser\Scope;
@@ -19,14 +20,22 @@
1920

2021
final class DoctrineConnectionDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
2122
{
23+
/**
24+
* @var array<string, class-string> return types of Connection methods in doctrine 3.x
25+
*/
26+
private $resultMap = [
27+
'query' => Result::class,
28+
//'prepare' => Statement::class,
29+
];
30+
2231
public function getClass(): string
2332
{
2433
return Connection::class;
2534
}
2635

2736
public function isMethodSupported(MethodReflection $methodReflection): bool
2837
{
29-
return 'query' === $methodReflection->getName();
38+
return \in_array(strtolower($methodReflection->getName()), ['query'/*, 'prepare'*/], true);
3039
}
3140

3241
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
@@ -42,27 +51,26 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
4251
return $defaultReturn;
4352
}
4453

45-
$resultType = $this->inferType($methodCall, $args[0]->value, $scope);
54+
$resultType = $this->inferType($methodReflection, $args[0]->value, $scope);
4655
if (null !== $resultType) {
4756
return $resultType;
4857
}
4958

5059
return $defaultReturn;
5160
}
5261

53-
private function inferType(MethodCall $methodCall, Expr $queryExpr, Scope $scope): ?Type
62+
private function inferType(MethodReflection $methodReflection, Expr $queryExpr, Scope $scope): ?Type
5463
{
55-
$args = $methodCall->getArgs();
56-
5764
$queryReflection = new QueryReflection();
5865
$queryString = $queryReflection->resolveQueryString($queryExpr, $scope);
5966
if (null === $queryString) {
6067
return null;
6168
}
6269

70+
$genericMainType = $this->resultMap[strtolower($methodReflection->getName())];
6371
$resultType = $queryReflection->getResultType($queryString, QueryReflector::FETCH_TYPE_BOTH);
6472
if ($resultType) {
65-
return new GenericObjectType(Result::class, [$resultType]);
73+
return new GenericObjectType($genericMainType, [$resultType]);
6674
}
6775

6876
return null;

tests/data/doctrine-dbal.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace DoctrineDbalTest;
44

5-
use Doctrine\DBAL\Driver\Connection;
5+
use Doctrine\DBAL\Connection;
66
use function PHPStan\Testing\assertType;
77

88
class Foo

0 commit comments

Comments
 (0)