@@ -52,15 +52,7 @@ public function getTypeFromFunctionCall(
52
52
{
53
53
$ type = $ this ->getPreliminarilyResolvedTypeFromFunctionCall ($ functionReflection , $ functionCall , $ scope );
54
54
55
- $ possibleTypes = ParametersAcceptorSelector::selectFromArgs (
56
- $ scope ,
57
- $ functionCall ->getArgs (),
58
- $ functionReflection ->getVariants (),
59
- )->getReturnType ();
60
- // resolve conditional return types
61
- $ possibleTypes = TypeUtils::resolveLateResolvableTypes ($ possibleTypes );
62
-
63
- if (TypeCombinator::containsNull ($ possibleTypes )) {
55
+ if ($ this ->canReturnNull ($ functionReflection , $ functionCall , $ scope )) {
64
56
$ type = TypeCombinator::addNull ($ type );
65
57
}
66
58
@@ -73,18 +65,17 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
73
65
Scope $ scope ,
74
66
): Type
75
67
{
76
- $ argumentPosition = self :: FUNCTIONS_SUBJECT_POSITION [ $ functionReflection -> getName ()] ;
68
+ $ subjectArgumentType = $ this -> getSubjectType ( $ functionReflection , $ functionCall , $ scope ) ;
77
69
$ defaultReturnType = ParametersAcceptorSelector::selectFromArgs (
78
70
$ scope ,
79
71
$ functionCall ->getArgs (),
80
72
$ functionReflection ->getVariants (),
81
73
)->getReturnType ();
82
74
83
- if (count ( $ functionCall -> getArgs ()) <= $ argumentPosition ) {
75
+ if ($ subjectArgumentType === null ) {
84
76
return $ defaultReturnType ;
85
77
}
86
78
87
- $ subjectArgumentType = $ scope ->getType ($ functionCall ->getArgs ()[$ argumentPosition ]->value );
88
79
if ($ subjectArgumentType instanceof MixedType) {
89
80
return TypeUtils::toBenevolentUnion ($ defaultReturnType );
90
81
}
@@ -124,4 +115,35 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
124
115
return $ defaultReturnType ;
125
116
}
126
117
118
+ private function getSubjectType (
119
+ FunctionReflection $ functionReflection ,
120
+ FuncCall $ functionCall ,
121
+ Scope $ scope ,
122
+ ): ?Type
123
+ {
124
+ $ argumentPosition = self ::FUNCTIONS_SUBJECT_POSITION [$ functionReflection ->getName ()];
125
+ if (count ($ functionCall ->getArgs ()) <= $ argumentPosition ) {
126
+ return null ;
127
+ }
128
+ return $ scope ->getType ($ functionCall ->getArgs ()[$ argumentPosition ]->value );
129
+ }
130
+
131
+ private function canReturnNull (
132
+ FunctionReflection $ functionReflection ,
133
+ FuncCall $ functionCall ,
134
+ Scope $ scope ,
135
+ ): bool
136
+ {
137
+ $ possibleTypes = ParametersAcceptorSelector::selectFromArgs (
138
+ $ scope ,
139
+ $ functionCall ->getArgs (),
140
+ $ functionReflection ->getVariants (),
141
+ )->getReturnType ();
142
+
143
+ // resolve conditional return types
144
+ $ possibleTypes = TypeUtils::resolveLateResolvableTypes ($ possibleTypes );
145
+
146
+ return TypeCombinator::containsNull ($ possibleTypes );
147
+ }
148
+
127
149
}
0 commit comments