3
3
4
4
namespace TheCodingMachine \Safe \PHPStan \Type \Php ;
5
5
6
+ use PhpParser \Node \Arg ;
6
7
use PhpParser \Node \Expr \FuncCall ;
7
8
use PHPStan \Analyser \Scope ;
8
9
use PHPStan \Reflection \FunctionReflection ;
@@ -35,7 +36,12 @@ public function getTypeFromFunctionCall(
35
36
): Type {
36
37
$ type = $ this ->getPreliminarilyResolvedTypeFromFunctionCall ($ functionReflection , $ functionCall , $ scope );
37
38
38
- $ possibleTypes = ParametersAcceptorSelector::selectSingle ($ functionReflection ->getVariants ())->getReturnType ();
39
+ $ possibleTypes = ParametersAcceptorSelector::selectFromArgs (
40
+ $ scope ,
41
+ $ functionCall ->getArgs (),
42
+ $ functionReflection ->getVariants ()
43
+ )
44
+ ->getReturnType ();
39
45
40
46
if (TypeCombinator::containsNull ($ possibleTypes )) {
41
47
$ type = TypeCombinator::addNull ($ type );
@@ -50,28 +56,36 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
50
56
Scope $ scope
51
57
): Type {
52
58
$ argumentPosition = $ this ->functions [$ functionReflection ->getName ()];
59
+ $ defaultReturnType = ParametersAcceptorSelector::selectFromArgs (
60
+ $ scope ,
61
+ $ functionCall ->getArgs (),
62
+ $ functionReflection ->getVariants ()
63
+ )
64
+ ->getReturnType ();
65
+
53
66
if (count ($ functionCall ->args ) <= $ argumentPosition ) {
54
- return ParametersAcceptorSelector:: selectSingle ( $ functionReflection -> getVariants ())-> getReturnType () ;
67
+ return $ defaultReturnType ;
55
68
}
56
69
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 ()) {
60
78
return TypeUtils::toBenevolentUnion ($ defaultReturnType );
61
79
}
62
- $ stringType = new StringType ();
63
- $ arrayType = new ArrayType (new MixedType (), new MixedType ());
64
80
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 ()) {
69
83
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 ;
75
89
}
76
90
77
91
return $ defaultReturnType ;
0 commit comments