@@ -52,15 +52,7 @@ public function getTypeFromFunctionCall(
5252 {
5353 $ type = $ this ->getPreliminarilyResolvedTypeFromFunctionCall ($ functionReflection , $ functionCall , $ scope );
5454
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 )) {
6456 $ type = TypeCombinator::addNull ($ type );
6557 }
6658
@@ -73,18 +65,17 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
7365 Scope $ scope ,
7466 ): Type
7567 {
76- $ argumentPosition = self :: FUNCTIONS_SUBJECT_POSITION [ $ functionReflection -> getName ()] ;
68+ $ subjectArgumentType = $ this -> getSubjectType ( $ functionReflection , $ functionCall , $ scope ) ;
7769 $ defaultReturnType = ParametersAcceptorSelector::selectFromArgs (
7870 $ scope ,
7971 $ functionCall ->getArgs (),
8072 $ functionReflection ->getVariants (),
8173 )->getReturnType ();
8274
83- if (count ( $ functionCall -> getArgs ()) <= $ argumentPosition ) {
75+ if ($ subjectArgumentType === null ) {
8476 return $ defaultReturnType ;
8577 }
8678
87- $ subjectArgumentType = $ scope ->getType ($ functionCall ->getArgs ()[$ argumentPosition ]->value );
8879 if ($ subjectArgumentType instanceof MixedType) {
8980 return TypeUtils::toBenevolentUnion ($ defaultReturnType );
9081 }
@@ -124,4 +115,35 @@ private function getPreliminarilyResolvedTypeFromFunctionCall(
124115 return $ defaultReturnType ;
125116 }
126117
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+
127149}
0 commit comments