@@ -246,44 +246,17 @@ public function specifyTypesInCondition(
246
246
) {
247
247
$ argType = $ scope ->getType ($ expr ->right ->getArgs ()[0 ]->value );
248
248
249
- if (count ($ expr ->right ->getArgs ()) === 1 ) {
250
- $ isNormalCount = TrinaryLogic::createYes ();
251
- } else {
252
- $ mode = $ scope ->getType ($ expr ->right ->getArgs ()[1 ]->value );
253
- $ isNormalCount = (new ConstantIntegerType (COUNT_NORMAL ))->isSuperTypeOf ($ mode )->or ($ argType ->getIterableValueType ()->isArray ()->negate ());
254
- }
255
-
256
- if (
257
- $ isNormalCount ->yes ()
258
- && $ argType instanceof UnionType
259
- && $ argType ->isConstantArray ()->yes ()
260
- && $ leftType instanceof ConstantIntegerType
261
- ) {
249
+ if ($ argType instanceof UnionType && $ leftType instanceof ConstantIntegerType) {
262
250
if ($ orEqual ) {
263
- $ constantType = IntegerRangeType::createAllGreaterThanOrEqualTo ($ leftType ->getValue ());
251
+ $ sizeType = IntegerRangeType::createAllGreaterThanOrEqualTo ($ leftType ->getValue ());
264
252
} else {
265
- $ constantType = IntegerRangeType::createAllGreaterThan ($ leftType ->getValue ());
253
+ $ sizeType = IntegerRangeType::createAllGreaterThan ($ leftType ->getValue ());
266
254
}
267
255
268
- $ result = [];
269
- foreach ($ argType ->getTypes () as $ innerType ) {
270
- $ arraySize = $ innerType ->getArraySize ();
271
- $ isSize = $ constantType ->isSuperTypeOf ($ arraySize );
272
- if ($ context ->truthy ()) {
273
- if ($ isSize ->no ()) {
274
- continue ;
275
- }
276
- }
277
- if ($ context ->falsey ()) {
278
- if (!$ isSize ->yes ()) {
279
- continue ;
280
- }
281
- }
282
-
283
- $ result [] = $ innerType ;
256
+ $ narrowed = $ this ->narrowUnionBySize ($ expr ->right , $ argType , $ sizeType , $ context , $ scope , $ rootExpr );
257
+ if ($ narrowed !== null ) {
258
+ return $ narrowed ;
284
259
}
285
-
286
- return $ this ->create ($ expr ->right ->getArgs ()[0 ]->value , TypeCombinator::union (...$ result ), $ context , false , $ scope , $ rootExpr );
287
260
}
288
261
289
262
if (
@@ -976,6 +949,47 @@ public function specifyTypesInCondition(
976
949
return new SpecifiedTypes ([], [], false , [], $ rootExpr );
977
950
}
978
951
952
+ private function narrowUnionBySize (FuncCall $ countFuncCall , UnionType $ argType , Type $ sizeType , TypeSpecifierContext $ context , Scope $ scope , ?Expr $ rootExpr ): ?SpecifiedTypes
953
+ {
954
+ if (!$ sizeType ->isInteger ()->yes ()) {
955
+ return null ;
956
+ }
957
+
958
+ if (count ($ countFuncCall ->getArgs ()) === 1 ) {
959
+ $ isNormalCount = TrinaryLogic::createYes ();
960
+ } else {
961
+ $ mode = $ scope ->getType ($ countFuncCall ->getArgs ()[1 ]->value );
962
+ $ isNormalCount = (new ConstantIntegerType (COUNT_NORMAL ))->isSuperTypeOf ($ mode )->or ($ argType ->getIterableValueType ()->isArray ()->negate ());
963
+ }
964
+
965
+ if (
966
+ $ isNormalCount ->yes ()
967
+ && $ argType ->isConstantArray ()->yes ()
968
+ ) {
969
+ $ result = [];
970
+ foreach ($ argType ->getTypes () as $ innerType ) {
971
+ $ arraySize = $ innerType ->getArraySize ();
972
+ $ isSize = $ sizeType ->isSuperTypeOf ($ arraySize );
973
+ if ($ context ->truthy ()) {
974
+ if ($ isSize ->no ()) {
975
+ continue ;
976
+ }
977
+ }
978
+ if ($ context ->falsey ()) {
979
+ if (!$ isSize ->yes ()) {
980
+ continue ;
981
+ }
982
+ }
983
+
984
+ $ result [] = $ innerType ;
985
+ }
986
+
987
+ return $ this ->create ($ countFuncCall ->getArgs ()[0 ]->value , TypeCombinator::union (...$ result ), $ context , false , $ scope , $ rootExpr );
988
+ }
989
+
990
+ return null ;
991
+ }
992
+
979
993
private function specifyTypesForConstantBinaryExpression (
980
994
Expr $ exprNode ,
981
995
ConstantScalarType $ constantType ,
0 commit comments