@@ -1157,41 +1157,6 @@ private function specifyTypesForConstantStringBinaryExpression(
1157
1157
}
1158
1158
$ constantStringValue = $ scalarValues [0 ];
1159
1159
1160
- if (
1161
- $ context ->truthy ()
1162
- && $ exprNode instanceof FuncCall
1163
- && $ exprNode ->name instanceof Name
1164
- && in_array (strtolower ($ exprNode ->name ->toString ()), [
1165
- 'substr ' , 'strstr ' , 'stristr ' , 'strchr ' , 'strrchr ' , 'strtolower ' , 'strtoupper ' , 'ucfirst ' , 'lcfirst ' ,
1166
- 'mb_substr ' , 'mb_strstr ' , 'mb_stristr ' , 'mb_strchr ' , 'mb_strrchr ' , 'mb_strtolower ' , 'mb_strtoupper ' , 'mb_ucfirst ' , 'mb_lcfirst ' ,
1167
- 'ucwords ' , 'mb_convert_case ' , 'mb_convert_kana ' ,
1168
- ], true )
1169
- && isset ($ exprNode ->getArgs ()[0 ])
1170
- && $ constantStringValue !== ''
1171
- ) {
1172
- $ argType = $ scope ->getType ($ exprNode ->getArgs ()[0 ]->value );
1173
-
1174
- if ($ argType ->isString ()->yes ()) {
1175
- if ($ constantStringValue !== '0 ' ) {
1176
- return $ this ->create (
1177
- $ exprNode ->getArgs ()[0 ]->value ,
1178
- TypeCombinator::intersect ($ argType , new AccessoryNonFalsyStringType ()),
1179
- $ context ,
1180
- false ,
1181
- $ scope ,
1182
- );
1183
- }
1184
-
1185
- return $ this ->create (
1186
- $ exprNode ->getArgs ()[0 ]->value ,
1187
- TypeCombinator::intersect ($ argType , new AccessoryNonEmptyStringType ()),
1188
- $ context ,
1189
- false ,
1190
- $ scope ,
1191
- );
1192
- }
1193
- }
1194
-
1195
1160
if (
1196
1161
$ exprNode instanceof FuncCall
1197
1162
&& $ exprNode ->name instanceof Name
@@ -2192,6 +2157,41 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
2192
2157
}
2193
2158
}
2194
2159
2160
+ if (
2161
+ $ context ->truthy ()
2162
+ && $ unwrappedLeftExpr instanceof FuncCall
2163
+ && $ unwrappedLeftExpr ->name instanceof Name
2164
+ && in_array (strtolower ($ unwrappedLeftExpr ->name ->toString ()), [
2165
+ 'substr ' , 'strstr ' , 'stristr ' , 'strchr ' , 'strrchr ' , 'strtolower ' , 'strtoupper ' , 'ucfirst ' , 'lcfirst ' ,
2166
+ 'mb_substr ' , 'mb_strstr ' , 'mb_stristr ' , 'mb_strchr ' , 'mb_strrchr ' , 'mb_strtolower ' , 'mb_strtoupper ' , 'mb_ucfirst ' , 'mb_lcfirst ' ,
2167
+ 'ucwords ' , 'mb_convert_case ' , 'mb_convert_kana ' ,
2168
+ ], true )
2169
+ && isset ($ unwrappedLeftExpr ->getArgs ()[0 ])
2170
+ && $ rightType ->isNonEmptyString ()->yes ()
2171
+ ) {
2172
+ $ argType = $ scope ->getType ($ unwrappedLeftExpr ->getArgs ()[0 ]->value );
2173
+
2174
+ if ($ argType ->isString ()->yes ()) {
2175
+ if ($ rightType ->isNonFalsyString ()->yes ()) {
2176
+ return $ this ->create (
2177
+ $ unwrappedLeftExpr ->getArgs ()[0 ]->value ,
2178
+ TypeCombinator::intersect ($ argType , new AccessoryNonFalsyStringType ()),
2179
+ $ context ,
2180
+ false ,
2181
+ $ scope ,
2182
+ );
2183
+ }
2184
+
2185
+ return $ this ->create (
2186
+ $ unwrappedLeftExpr ->getArgs ()[0 ]->value ,
2187
+ TypeCombinator::intersect ($ argType , new AccessoryNonEmptyStringType ()),
2188
+ $ context ,
2189
+ false ,
2190
+ $ scope ,
2191
+ );
2192
+ }
2193
+ }
2194
+
2195
2195
if ($ rightType ->isInteger ()->yes () || $ rightType ->isString ()->yes ()) {
2196
2196
$ types = null ;
2197
2197
foreach ($ rightType ->getFiniteTypes () as $ finiteType ) {
0 commit comments