33
44namespace TheCodingMachine \Safe \PHPStan \Type \Php ;
55
6+ use PhpParser \Node \Arg ;
67use PhpParser \Node \Expr \FuncCall ;
78use PHPStan \Analyser \Scope ;
89use PHPStan \Reflection \FunctionReflection ;
@@ -35,7 +36,12 @@ public function getTypeFromFunctionCall(
3536 ): Type {
3637 $ type = $ this ->getPreliminarilyResolvedTypeFromFunctionCall ($ functionReflection , $ functionCall , $ scope );
3738
38- $ possibleTypes = ParametersAcceptorSelector::selectSingle ($ functionReflection ->getVariants ())->getReturnType ();
39+ $ possibleTypes = ParametersAcceptorSelector::selectFromArgs (
40+ $ scope ,
41+ $ functionCall ->getArgs (),
42+ $ functionReflection ->getVariants ()
43+ )
44+ ->getReturnType ();
3945
4046 if (TypeCombinator::containsNull ($ possibleTypes )) {
4147 $ type = TypeCombinator::addNull ($ type );
@@ -50,28 +56,36 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
5056 Scope $ scope
5157 ): Type {
5258 $ argumentPosition = $ this ->functions [$ functionReflection ->getName ()];
59+ $ defaultReturnType = ParametersAcceptorSelector::selectFromArgs (
60+ $ scope ,
61+ $ functionCall ->getArgs (),
62+ $ functionReflection ->getVariants ()
63+ )
64+ ->getReturnType ();
65+
5366 if (count ($ functionCall ->args ) <= $ argumentPosition ) {
54- return ParametersAcceptorSelector:: selectSingle ( $ functionReflection -> getVariants ())-> getReturnType () ;
67+ return $ defaultReturnType ;
5568 }
5669
57- $ subjectArgumentType = $ scope ->getType ($ functionCall ->args [$ argumentPosition ]->value );
58- $ defaultReturnType = ParametersAcceptorSelector::selectSingle ($ functionReflection ->getVariants ())->getReturnType ();
59- if ($ subjectArgumentType instanceof MixedType) {
70+ $ subjectArgument = $ functionCall ->args [$ argumentPosition ];
71+ if (!$ subjectArgument instanceof Arg) {
72+ return $ defaultReturnType ;
73+ }
74+
75+ $ subjectArgumentType = $ scope ->getType ($ subjectArgument ->value );
76+ $ mixedType = new MixedType ();
77+ if ($ subjectArgumentType ->isSuperTypeOf ($ mixedType )->yes ()) {
6078 return TypeUtils::toBenevolentUnion ($ defaultReturnType );
6179 }
62- $ stringType = new StringType ();
63- $ arrayType = new ArrayType (new MixedType (), new MixedType ());
6480
65- $ isStringSuperType = $ stringType ->isSuperTypeOf ($ subjectArgumentType );
66- $ isArraySuperType = $ arrayType ->isSuperTypeOf ($ subjectArgumentType );
67- $ compareSuperTypes = $ isStringSuperType ->compareTo ($ isArraySuperType );
68- if ($ compareSuperTypes === $ isStringSuperType ) {
81+ $ stringType = new StringType ();
82+ if ($ stringType ->isSuperTypeOf ($ subjectArgumentType )->yes ()) {
6983 return $ stringType ;
70- } elseif ( $ compareSuperTypes === $ isArraySuperType ) {
71- if ( $ subjectArgumentType instanceof ArrayType) {
72- return $ subjectArgumentType -> generalizeValues ( );
73- }
74- return $ subjectArgumentType ;
84+ }
85+
86+ $ arrayType = new ArrayType ( $ mixedType , $ mixedType );
87+ if ( $ arrayType -> isSuperTypeOf ( $ subjectArgumentType )-> yes ()) {
88+ return $ arrayType ;
7589 }
7690
7791 return $ defaultReturnType ;
0 commit comments