@@ -50,73 +50,75 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
5050
5151 public function getTypeFromMethodCall (MethodReflection $ methodReflection , MethodCall $ methodCall , Scope $ scope ): Type
5252 {
53- $ args = $ methodCall ->getArgs ();
5453 $ defaultReturn = ParametersAcceptorSelector::selectSingle ($ methodReflection ->getVariants ())->getReturnType ();
5554
5655 if (QueryReflection::getRuntimeConfiguration ()->throwsPdoExceptions ($ this ->phpVersion ) && !$ defaultReturn instanceof MixedType) {
5756 $ defaultReturn = TypeCombinator::remove ($ defaultReturn , new ConstantBooleanType (false ));
5857 }
5958
59+ $ resultType = $ this ->inferType ($ methodReflection , $ methodCall , $ scope );
60+ if (null !== $ resultType ) {
61+ return $ resultType ;
62+ }
63+
64+ return $ defaultReturn ;
65+ }
66+
67+ private function inferType (MethodReflection $ methodReflection , MethodCall $ methodCall , Scope $ scope ): ?Type
68+ {
69+ $ args = $ methodCall ->getArgs ();
6070 $ statementType = $ scope ->getType ($ methodCall ->var );
6171
62- if ($ statementType instanceof GenericObjectType) {
63- $ genericTypes = $ statementType ->getTypes ();
72+ if (!$ statementType instanceof GenericObjectType) {
73+ return null ;
74+ }
6475
65- if (1 !== \count ($ genericTypes )) {
66- return $ defaultReturn ;
67- }
76+ $ genericTypes = $ statementType ->getTypes ();
6877
69- $ fetchType = PDO ::FETCH_BOTH ;
70- if (\count ($ args ) > 0 ) {
71- $ fetchModeType = $ scope ->getType ($ args [0 ]->value );
72- if (!$ fetchModeType instanceof ConstantIntegerType) {
73- return $ defaultReturn ;
74- }
75- $ fetchType = $ fetchModeType ->getValue ();
78+ if (1 !== \count ($ genericTypes )) {
79+ return null ;
80+ }
7681
77- if (!\in_array ($ fetchType , [PDO ::FETCH_ASSOC , PDO ::FETCH_NUM , PDO ::FETCH_BOTH ])) {
78- return $ defaultReturn ;
79- }
82+ $ fetchType = PDO ::FETCH_BOTH ;
83+ if (\count ($ args ) > 0 ) {
84+ $ fetchModeType = $ scope ->getType ($ args [0 ]->value );
85+ if (!$ fetchModeType instanceof ConstantIntegerType) {
86+ return null ;
8087 }
88+ $ fetchType = $ fetchModeType ->getValue ();
8189
82- $ resultType = $ genericTypes [ 0 ];
83-
84- if (( PDO :: FETCH_NUM === $ fetchType || PDO :: FETCH_ASSOC === $ fetchType ) && $ resultType instanceof ConstantArrayType) {
85- $ builder = ConstantArrayTypeBuilder:: createEmpty ();
90+ if (! \in_array ( $ fetchType , [ PDO :: FETCH_ASSOC , PDO :: FETCH_NUM , PDO :: FETCH_BOTH ])) {
91+ return null ;
92+ }
93+ }
8694
87- $ keyTypes = $ resultType ->getKeyTypes ();
88- $ valueTypes = $ resultType ->getValueTypes ();
95+ $ resultType = $ genericTypes [0 ];
8996
90- foreach ($ keyTypes as $ i => $ keyType ) {
91- if (PDO ::FETCH_NUM === $ fetchType && $ keyType instanceof ConstantIntegerType) {
92- $ builder ->setOffsetValueType ($ keyType , $ valueTypes [$ i ]);
93- } elseif (PDO ::FETCH_ASSOC === $ fetchType && $ keyType instanceof ConstantStringType) {
94- $ builder ->setOffsetValueType ($ keyType , $ valueTypes [$ i ]);
95- }
96- }
97+ if ((PDO ::FETCH_NUM === $ fetchType || PDO ::FETCH_ASSOC === $ fetchType ) && $ resultType instanceof ConstantArrayType) {
98+ $ builder = ConstantArrayTypeBuilder::createEmpty ();
9799
98- if ('fetchAll ' === $ methodReflection ->getName ()) {
99- return new ArrayType (new IntegerType (), $ builder ->getArray ());
100- }
100+ $ keyTypes = $ resultType ->getKeyTypes ();
101+ $ valueTypes = $ resultType ->getValueTypes ();
101102
102- if (QueryReflection::getRuntimeConfiguration ()->throwsPdoExceptions ($ this ->phpVersion )) {
103- return $ builder ->getArray ();
103+ foreach ($ keyTypes as $ i => $ keyType ) {
104+ if (PDO ::FETCH_NUM === $ fetchType && $ keyType instanceof ConstantIntegerType) {
105+ $ builder ->setOffsetValueType ($ keyType , $ valueTypes [$ i ]);
106+ } elseif (PDO ::FETCH_ASSOC === $ fetchType && $ keyType instanceof ConstantStringType) {
107+ $ builder ->setOffsetValueType ($ keyType , $ valueTypes [$ i ]);
104108 }
105-
106- return new UnionType ([$ builder ->getArray (), new ConstantBooleanType (false )]);
107109 }
108110
109- if ('fetchAll ' === $ methodReflection ->getName ()) {
110- return new ArrayType (new IntegerType (), $ resultType );
111- }
111+ $ resultType = $ builder ->getArray ();
112+ }
112113
113- if (QueryReflection:: getRuntimeConfiguration ()-> throwsPdoExceptions ( $ this -> phpVersion )) {
114- return $ resultType ;
115- }
114+ if (' fetchAll ' === $ methodReflection -> getName ( )) {
115+ return new ArrayType ( new IntegerType (), $ resultType) ;
116+ }
116117
117- return new UnionType ([$ resultType , new ConstantBooleanType (false )]);
118+ if (QueryReflection::getRuntimeConfiguration ()->throwsPdoExceptions ($ this ->phpVersion )) {
119+ return $ resultType ;
118120 }
119121
120- return $ defaultReturn ;
122+ return new UnionType ([ $ resultType , new ConstantBooleanType ( false )]) ;
121123 }
122124}
0 commit comments