@@ -1200,41 +1200,6 @@ private function specifyTypesForConstantStringBinaryExpression(
1200
1200
}
1201
1201
$ constantStringValue = $ scalarValues [0 ];
1202
1202
1203
- if (
1204
- $ context ->truthy ()
1205
- && $ exprNode instanceof FuncCall
1206
- && $ exprNode ->name instanceof Name
1207
- && in_array (strtolower ($ exprNode ->name ->toString ()), [
1208
- 'substr ' , 'strstr ' , 'stristr ' , 'strchr ' , 'strrchr ' , 'strtolower ' , 'strtoupper ' , 'ucfirst ' , 'lcfirst ' ,
1209
- 'mb_substr ' , 'mb_strstr ' , 'mb_stristr ' , 'mb_strchr ' , 'mb_strrchr ' , 'mb_strtolower ' , 'mb_strtoupper ' , 'mb_ucfirst ' , 'mb_lcfirst ' ,
1210
- 'ucwords ' , 'mb_convert_case ' , 'mb_convert_kana ' ,
1211
- ], true )
1212
- && isset ($ exprNode ->getArgs ()[0 ])
1213
- && $ constantStringValue !== ''
1214
- ) {
1215
- $ argType = $ scope ->getType ($ exprNode ->getArgs ()[0 ]->value );
1216
-
1217
- if ($ argType ->isString ()->yes ()) {
1218
- if ($ constantStringValue !== '0 ' ) {
1219
- return $ this ->create (
1220
- $ exprNode ->getArgs ()[0 ]->value ,
1221
- TypeCombinator::intersect ($ argType , new AccessoryNonFalsyStringType ()),
1222
- $ context ,
1223
- false ,
1224
- $ scope ,
1225
- );
1226
- }
1227
-
1228
- return $ this ->create (
1229
- $ exprNode ->getArgs ()[0 ]->value ,
1230
- TypeCombinator::intersect ($ argType , new AccessoryNonEmptyStringType ()),
1231
- $ context ,
1232
- false ,
1233
- $ scope ,
1234
- );
1235
- }
1236
- }
1237
-
1238
1203
if (
1239
1204
$ exprNode instanceof FuncCall
1240
1205
&& $ exprNode ->name instanceof Name
@@ -2171,6 +2136,41 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
2171
2136
}
2172
2137
}
2173
2138
2139
+ if (
2140
+ $ context ->truthy ()
2141
+ && $ unwrappedLeftExpr instanceof FuncCall
2142
+ && $ unwrappedLeftExpr ->name instanceof Name
2143
+ && in_array (strtolower ($ unwrappedLeftExpr ->name ->toString ()), [
2144
+ 'substr ' , 'strstr ' , 'stristr ' , 'strchr ' , 'strrchr ' , 'strtolower ' , 'strtoupper ' , 'ucfirst ' , 'lcfirst ' ,
2145
+ 'mb_substr ' , 'mb_strstr ' , 'mb_stristr ' , 'mb_strchr ' , 'mb_strrchr ' , 'mb_strtolower ' , 'mb_strtoupper ' , 'mb_ucfirst ' , 'mb_lcfirst ' ,
2146
+ 'ucwords ' , 'mb_convert_case ' , 'mb_convert_kana ' ,
2147
+ ], true )
2148
+ && isset ($ unwrappedLeftExpr ->getArgs ()[0 ])
2149
+ && $ rightType ->isNonEmptyString ()->yes ()
2150
+ ) {
2151
+ $ argType = $ scope ->getType ($ unwrappedLeftExpr ->getArgs ()[0 ]->value );
2152
+
2153
+ if ($ argType ->isString ()->yes ()) {
2154
+ if ($ rightType ->isNonFalsyString ()->yes ()) {
2155
+ return $ this ->create (
2156
+ $ unwrappedLeftExpr ->getArgs ()[0 ]->value ,
2157
+ TypeCombinator::intersect ($ argType , new AccessoryNonFalsyStringType ()),
2158
+ $ context ,
2159
+ false ,
2160
+ $ scope ,
2161
+ );
2162
+ }
2163
+
2164
+ return $ this ->create (
2165
+ $ unwrappedLeftExpr ->getArgs ()[0 ]->value ,
2166
+ TypeCombinator::intersect ($ argType , new AccessoryNonEmptyStringType ()),
2167
+ $ context ,
2168
+ false ,
2169
+ $ scope ,
2170
+ );
2171
+ }
2172
+ }
2173
+
2174
2174
if ($ rightType ->isInteger ()->yes () || $ rightType ->isString ()->yes ()) {
2175
2175
$ types = null ;
2176
2176
foreach ($ rightType ->getFiniteTypes () as $ finiteType ) {
0 commit comments