@@ -1124,39 +1124,6 @@ private function specifyTypesForConstantBinaryExpression(
11241124 ));
11251125 }
11261126
1127- if (
1128- !$ context ->null ()
1129- && $ exprNode instanceof FuncCall
1130- && count ($ exprNode ->getArgs ()) === 1
1131- && $ exprNode ->name instanceof Name
1132- && in_array (strtolower ((string ) $ exprNode ->name ), ['strlen ' , 'mb_strlen ' ], true )
1133- && $ constantType instanceof ConstantIntegerType
1134- ) {
1135- if ($ constantType ->getValue () < 0 ) {
1136- return $ this ->create ($ exprNode ->getArgs ()[0 ]->value , new NeverType (), $ context , false , $ scope , $ rootExpr );
1137- }
1138-
1139- if ($ context ->truthy () || $ constantType ->getValue () === 0 ) {
1140- $ newContext = $ context ;
1141- if ($ constantType ->getValue () === 0 ) {
1142- $ newContext = $ newContext ->negate ();
1143- }
1144- $ argType = $ scope ->getType ($ exprNode ->getArgs ()[0 ]->value );
1145- if ($ argType ->isString ()->yes ()) {
1146- $ funcTypes = $ this ->create ($ exprNode , $ constantType , $ context , false , $ scope , $ rootExpr );
1147-
1148- $ accessory = new AccessoryNonEmptyStringType ();
1149- if ($ constantType ->getValue () >= 2 ) {
1150- $ accessory = new AccessoryNonFalsyStringType ();
1151- }
1152- $ valueTypes = $ this ->create ($ exprNode ->getArgs ()[0 ]->value , $ accessory , $ newContext , false , $ scope , $ rootExpr );
1153-
1154- return $ funcTypes ->unionWith ($ valueTypes );
1155- }
1156- }
1157-
1158- }
1159-
11601127 return null ;
11611128 }
11621129
@@ -2140,6 +2107,42 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
21402107 }
21412108 }
21422109
2110+ if (
2111+ !$ context ->null ()
2112+ && $ unwrappedLeftExpr instanceof FuncCall
2113+ && count ($ unwrappedLeftExpr ->getArgs ()) === 1
2114+ && $ unwrappedLeftExpr ->name instanceof Name
2115+ && in_array (strtolower ((string ) $ unwrappedLeftExpr ->name ), ['strlen ' , 'mb_strlen ' ], true )
2116+ && $ rightType ->isInteger ()->yes ()
2117+ ) {
2118+ if (IntegerRangeType::fromInterval (null , -1 )->isSuperTypeOf ($ rightType )->yes ()) {
2119+ return $ this ->create ($ unwrappedLeftExpr ->getArgs ()[0 ]->value , new NeverType (), $ context , false , $ scope , $ rootExpr );
2120+ }
2121+
2122+ $ isZero = (new ConstantIntegerType (0 ))->isSuperTypeOf ($ rightType );
2123+ if ($ isZero ->yes ()) {
2124+ $ funcTypes = $ this ->create ($ unwrappedLeftExpr , $ rightType , $ context , false , $ scope , $ rootExpr );
2125+ return $ funcTypes ->unionWith (
2126+ $ this ->create ($ unwrappedLeftExpr ->getArgs ()[0 ]->value , new ConstantStringType ('' ), $ context , false , $ scope , $ rootExpr ),
2127+ );
2128+ }
2129+
2130+ if ($ context ->truthy () && IntegerRangeType::fromInterval (1 , null )->isSuperTypeOf ($ rightType )->yes ()) {
2131+ $ argType = $ scope ->getType ($ unwrappedLeftExpr ->getArgs ()[0 ]->value );
2132+ if ($ argType ->isString ()->yes ()) {
2133+ $ funcTypes = $ this ->create ($ unwrappedLeftExpr , $ rightType , $ context , false , $ scope , $ rootExpr );
2134+
2135+ $ accessory = new AccessoryNonEmptyStringType ();
2136+ if (IntegerRangeType::fromInterval (2 , null )->isSuperTypeOf ($ rightType )->yes ()) {
2137+ $ accessory = new AccessoryNonFalsyStringType ();
2138+ }
2139+ $ valueTypes = $ this ->create ($ unwrappedLeftExpr ->getArgs ()[0 ]->value , $ accessory , $ context , false , $ scope , $ rootExpr );
2140+
2141+ return $ funcTypes ->unionWith ($ valueTypes );
2142+ }
2143+ }
2144+ }
2145+
21432146 if (
21442147 $ context ->true ()
21452148 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2209,14 +2212,11 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
22092212 }
22102213 }
22112214
2212- if ($ rightType ->isInteger ()-> yes () || $ rightType -> isString ()->yes ()) {
2215+ if ($ rightType ->isString ()->yes ()) {
22132216 $ types = null ;
2214- foreach ($ rightType ->getFiniteTypes () as $ finiteType ) {
2215- if ($ finiteType ->isString ()->yes ()) {
2216- $ specifiedType = $ this ->specifyTypesForConstantStringBinaryExpression ($ unwrappedLeftExpr , $ finiteType , $ context , $ scope , $ rootExpr );
2217- } else {
2218- $ specifiedType = $ this ->specifyTypesForConstantBinaryExpression ($ unwrappedLeftExpr , $ finiteType , $ context , $ scope , $ rootExpr );
2219- }
2217+ foreach ($ rightType ->getConstantStrings () as $ constantString ) {
2218+ $ specifiedType = $ this ->specifyTypesForConstantStringBinaryExpression ($ unwrappedLeftExpr , $ constantString , $ context , $ scope , $ rootExpr );
2219+
22202220 if ($ specifiedType === null ) {
22212221 continue ;
22222222 }
0 commit comments