44
55namespace staabm \PHPStanDba \Extensions ;
66
7- use Doctrine \DBAL \Driver \ Connection ;
7+ use Doctrine \DBAL \Connection ;
88use Doctrine \DBAL \Result ;
9+ use Doctrine \DBAL \Statement ;
910use PhpParser \Node \Expr ;
1011use PhpParser \Node \Expr \MethodCall ;
1112use PHPStan \Analyser \Scope ;
1920
2021final 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 ;
0 commit comments