@@ -49,50 +49,56 @@ public function getTypeFromFunctionCall(
49
49
}
50
50
51
51
$ formatType = $ scope ->getType ($ args [0 ]->value );
52
+ if (count ($ args ) === 1 ) {
53
+ return $ this ->getConstantType ($ args , null , $ functionReflection , $ scope );
54
+ }
52
55
53
- if (count ($ formatType ->getConstantStrings ()) > 0 ) {
54
- $ singlePlaceholderEarlyReturn = null ;
55
- foreach ($ formatType ->getConstantStrings () as $ constantString ) {
56
- // The printf format is %[argnum$][flags][width][.precision]
57
- if (preg_match ('/^%([0-9]*\$)?[0-9]*\.?[0-9]*([sbdeEfFgGhHouxX])$/ ' , $ constantString ->getValue (), $ matches ) === 1 ) {
58
- if ($ matches [1 ] !== '' ) {
59
- // invalid positional argument
60
- if ($ matches [1 ] === '0$ ' ) {
61
- return null ;
62
- }
63
- $ checkArg = intval (substr ($ matches [1 ], 0 , -1 ));
64
- } else {
65
- $ checkArg = 1 ;
66
- }
56
+ $ formatStrings = $ formatType ->getConstantStrings ();
57
+ if (count ($ formatStrings ) === 0 ) {
58
+ return null ;
59
+ }
67
60
68
- // constant string specifies a numbered argument that does not exist
69
- if (!array_key_exists ($ checkArg , $ args )) {
61
+ $ singlePlaceholderEarlyReturn = null ;
62
+ foreach ($ formatType ->getConstantStrings () as $ constantString ) {
63
+ // The printf format is %[argnum$][flags][width][.precision]
64
+ if (preg_match ('/^%([0-9]*\$)?[0-9]*\.?[0-9]*([sbdeEfFgGhHouxX])$/ ' , $ constantString ->getValue (), $ matches ) === 1 ) {
65
+ if ($ matches [1 ] !== '' ) {
66
+ // invalid positional argument
67
+ if ($ matches [1 ] === '0$ ' ) {
70
68
return null ;
71
69
}
70
+ $ checkArg = intval (substr ($ matches [1 ], 0 , -1 ));
71
+ } else {
72
+ $ checkArg = 1 ;
73
+ }
72
74
73
- // if the format string is just a placeholder and specified an argument
74
- // of stringy type, then the return value will be of the same type
75
- $ checkArgType = $ scope ->getType ($ args [$ checkArg ]->value );
76
-
77
- if ($ matches [2 ] === 's ' && $ checkArgType ->isString ()->yes ()) {
78
- $ singlePlaceholderEarlyReturn = $ checkArgType ;
79
- } elseif ($ matches [2 ] !== 's ' ) {
80
- $ singlePlaceholderEarlyReturn = new IntersectionType ([
81
- new StringType (),
82
- new AccessoryNumericStringType (),
83
- ]);
84
- }
75
+ // constant string specifies a numbered argument that does not exist
76
+ if (!array_key_exists ($ checkArg , $ args )) {
77
+ return null ;
78
+ }
85
79
86
- continue ;
80
+ // if the format string is just a placeholder and specified an argument
81
+ // of stringy type, then the return value will be of the same type
82
+ $ checkArgType = $ scope ->getType ($ args [$ checkArg ]->value );
83
+
84
+ if ($ matches [2 ] === 's ' && $ checkArgType ->isString ()->yes ()) {
85
+ $ singlePlaceholderEarlyReturn = $ checkArgType ;
86
+ } elseif ($ matches [2 ] !== 's ' ) {
87
+ $ singlePlaceholderEarlyReturn = new IntersectionType ([
88
+ new StringType (),
89
+ new AccessoryNumericStringType (),
90
+ ]);
87
91
}
88
92
89
- $ singlePlaceholderEarlyReturn = null ;
90
- break ;
93
+ continue ;
91
94
}
92
95
93
- if ($ singlePlaceholderEarlyReturn !== null ) {
94
- return $ singlePlaceholderEarlyReturn ;
95
- }
96
+ $ singlePlaceholderEarlyReturn = null ;
97
+ break ;
98
+ }
99
+
100
+ if ($ singlePlaceholderEarlyReturn !== null ) {
101
+ return $ singlePlaceholderEarlyReturn ;
96
102
}
97
103
98
104
if ($ formatType ->isNonFalsyString ()->yes ()) {
@@ -115,11 +121,15 @@ public function getTypeFromFunctionCall(
115
121
/**
116
122
* @param Arg[] $args
117
123
*/
118
- private function getConstantType (array $ args , Type $ fallbackReturnType , FunctionReflection $ functionReflection , Scope $ scope ): Type
124
+ private function getConstantType (array $ args , ? Type $ fallbackReturnType , FunctionReflection $ functionReflection , Scope $ scope ): ? Type
119
125
{
120
126
$ values = [];
121
127
$ combinationsCount = 1 ;
122
128
foreach ($ args as $ arg ) {
129
+ if ($ arg ->unpack ) {
130
+ return $ fallbackReturnType ;
131
+ }
132
+
123
133
$ argType = $ scope ->getType ($ arg ->value );
124
134
$ constantScalarValues = $ argType ->getConstantScalarValues ();
125
135
0 commit comments