@@ -48,18 +48,19 @@ public function getTypeFromFunctionCall(
48
48
return null ;
49
49
}
50
50
51
- $ formatType = $ scope -> getType ($ args[ 0 ]-> value );
52
- if (count ( $ args ) === 1 ) {
53
- return $ this -> getConstantType ( $ args , null , $ functionReflection , $ scope ) ;
51
+ $ constantType = $ this -> getConstantType ($ args, $ functionReflection , $ scope );
52
+ if ($ constantType !== null ) {
53
+ return $ constantType ;
54
54
}
55
55
56
+ $ formatType = $ scope ->getType ($ args [0 ]->value );
56
57
$ formatStrings = $ formatType ->getConstantStrings ();
57
58
if (count ($ formatStrings ) === 0 ) {
58
59
return null ;
59
60
}
60
61
61
62
$ singlePlaceholderEarlyReturn = null ;
62
- foreach ($ formatType -> getConstantStrings () as $ constantString ) {
63
+ foreach ($ formatStrings as $ constantString ) {
63
64
// The printf format is %[argnum$][flags][width][.precision]
64
65
if (preg_match ('/^%([0-9]*\$)?[0-9]*\.?[0-9]*([sbdeEfFgGhHouxX])$/ ' , $ constantString ->getValue (), $ matches ) === 1 ) {
65
66
if ($ matches [1 ] !== '' ) {
@@ -80,9 +81,10 @@ public function getTypeFromFunctionCall(
80
81
// if the format string is just a placeholder and specified an argument
81
82
// of stringy type, then the return value will be of the same type
82
83
$ checkArgType = $ scope ->getType ($ args [$ checkArg ]->value );
83
-
84
- if ($ matches [2 ] === 's ' && $ checkArgType ->isString ()->yes ()) {
85
- $ singlePlaceholderEarlyReturn = $ checkArgType ;
84
+ if ($ matches [2 ] === 's '
85
+ && ($ checkArgType ->isString ()->yes () || $ checkArgType ->isInteger ()->yes ())
86
+ ) {
87
+ $ singlePlaceholderEarlyReturn = $ checkArgType ->toString ();
86
88
} elseif ($ matches [2 ] !== 's ' ) {
87
89
$ singlePlaceholderEarlyReturn = new IntersectionType ([
88
90
new StringType (),
@@ -115,19 +117,19 @@ public function getTypeFromFunctionCall(
115
117
$ returnType = new StringType ();
116
118
}
117
119
118
- return $ this -> getConstantType ( $ args , $ returnType, $ functionReflection , $ scope ) ;
120
+ return $ returnType ;
119
121
}
120
122
121
123
/**
122
124
* @param Arg[] $args
123
125
*/
124
- private function getConstantType (array $ args , ? Type $ fallbackReturnType , FunctionReflection $ functionReflection , Scope $ scope ): ?Type
126
+ private function getConstantType (array $ args , FunctionReflection $ functionReflection , Scope $ scope ): ?Type
125
127
{
126
128
$ values = [];
127
129
$ combinationsCount = 1 ;
128
130
foreach ($ args as $ arg ) {
129
131
if ($ arg ->unpack ) {
130
- return $ fallbackReturnType ;
132
+ return null ;
131
133
}
132
134
133
135
$ argType = $ scope ->getType ($ arg ->value );
@@ -142,23 +144,23 @@ private function getConstantType(array $args, ?Type $fallbackReturnType, Functio
142
144
}
143
145
144
146
if (count ($ constantScalarValues ) === 0 ) {
145
- return $ fallbackReturnType ;
147
+ return null ;
146
148
}
147
149
148
150
$ values [] = $ constantScalarValues ;
149
151
$ combinationsCount *= count ($ constantScalarValues );
150
152
}
151
153
152
154
if ($ combinationsCount > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT ) {
153
- return $ fallbackReturnType ;
155
+ return null ;
154
156
}
155
157
156
158
$ combinations = CombinationsHelper::combinations ($ values );
157
159
$ returnTypes = [];
158
160
foreach ($ combinations as $ combination ) {
159
161
$ format = array_shift ($ combination );
160
162
if (!is_string ($ format )) {
161
- return $ fallbackReturnType ;
163
+ return null ;
162
164
}
163
165
164
166
try {
@@ -168,12 +170,12 @@ private function getConstantType(array $args, ?Type $fallbackReturnType, Functio
168
170
$ returnTypes [] = $ scope ->getTypeFromValue (@vsprintf ($ format , $ combination ));
169
171
}
170
172
} catch (Throwable ) {
171
- return $ fallbackReturnType ;
173
+ return null ;
172
174
}
173
175
}
174
176
175
177
if (count ($ returnTypes ) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT ) {
176
- return $ fallbackReturnType ;
178
+ return null ;
177
179
}
178
180
179
181
return TypeCombinator::union (...$ returnTypes );
0 commit comments