2929use function count ;
3030use function in_array ;
3131use function intval ;
32+ use function is_array ;
3233use function is_string ;
3334use function preg_match ;
3435use function sprintf ;
@@ -69,7 +70,7 @@ public function getTypeFromFunctionCall(
6970 static fn (Type $ type ): bool => $ type ->toString ()->isLowercaseString ()->yes ()
7071 );
7172
72- $ singlePlaceholderEarlyReturn = null ;
73+ $ singlePlaceholderEarlyReturn = [] ;
7374 $ allPatternsNonEmpty = count ($ formatStrings ) !== 0 ;
7475 $ allPatternsNonFalsy = count ($ formatStrings ) !== 0 ;
7576 foreach ($ formatStrings as $ constantString ) {
@@ -93,8 +94,11 @@ public function getTypeFromFunctionCall(
9394 $ allPatternsNonFalsy = false ;
9495 }
9596
96- // The printf format is %[argnum$][flags][width][.precision]specifier.
97- if (preg_match ('/^%(?P<argnum>[0-9]*\$)?(?P<width>[0-9]*)\.?[0-9]*(?P<specifier>[sbdeEfFgGhHouxX])$/ ' , $ constantString ->getValue (), $ matches ) === 1 ) {
97+ if (
98+ is_array ($ singlePlaceholderEarlyReturn )
99+ // The printf format is %[argnum$][flags][width][.precision]specifier.
100+ && preg_match ('/^%(?P<argnum>[0-9]*\$)?(?P<width>[0-9]*)\.?[0-9]*(?P<specifier>[sbdeEfFgGhHouxX])$/ ' , $ constantString ->getValue (), $ matches ) === 1
101+ ) {
98102 if ($ matches ['argnum ' ] !== '' ) {
99103 // invalid positional argument
100104 if ($ matches ['argnum ' ] === '0$ ' ) {
@@ -122,24 +126,22 @@ public function getTypeFromFunctionCall(
122126 $ constArgTypes = $ checkArgType ->getConstantScalarTypes ();
123127 }
124128 if ($ constArgTypes !== []) {
125- $ result = [];
126129 $ printfArgs = array_fill (0 , count ($ args ) - 1 , '' );
127130 foreach ($ constArgTypes as $ constArgType ) {
128131 $ printfArgs [$ checkArg - 1 ] = $ constArgType ->getValue ();
129132 try {
130- $ result [] = new ConstantStringType (@sprintf ($ constantString ->getValue (), ...$ printfArgs ));
133+ $ singlePlaceholderEarlyReturn [] = new ConstantStringType (@sprintf ($ constantString ->getValue (), ...$ printfArgs ));
131134 } catch (Throwable ) {
132135 continue 2 ;
133136 }
134137 }
135- $ singlePlaceholderEarlyReturn = TypeCombinator::union (...$ result );
136138
137139 continue ;
138140 }
139141
140- $ singlePlaceholderEarlyReturn = $ checkArgType ->toString ();
142+ $ singlePlaceholderEarlyReturn[] = $ checkArgType ->toString ();
141143 } elseif ($ matches ['specifier ' ] !== 's ' ) {
142- $ singlePlaceholderEarlyReturn = $ this ->getStringReturnType (
144+ $ singlePlaceholderEarlyReturn[] = $ this ->getStringReturnType (
143145 new AccessoryNumericStringType (),
144146 $ isLowercase ,
145147 );
@@ -149,11 +151,10 @@ public function getTypeFromFunctionCall(
149151 }
150152
151153 $ singlePlaceholderEarlyReturn = null ;
152- break ;
153154 }
154155
155- if ($ singlePlaceholderEarlyReturn !== null ) {
156- return $ singlePlaceholderEarlyReturn ;
156+ if (is_array ( $ singlePlaceholderEarlyReturn) && count ( $ singlePlaceholderEarlyReturn ) > 0 ) {
157+ return TypeCombinator:: union (... $ singlePlaceholderEarlyReturn) ;
157158 }
158159
159160 if ($ allPatternsNonFalsy ) {
0 commit comments