Skip to content

Commit 33a2248

Browse files
committed
extract narrowUnionBySize
1 parent 406203b commit 33a2248

File tree

1 file changed

+47
-33
lines changed

1 file changed

+47
-33
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -246,44 +246,17 @@ public function specifyTypesInCondition(
246246
) {
247247
$argType = $scope->getType($expr->right->getArgs()[0]->value);
248248

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) {
262250
if ($orEqual) {
263-
$constantType = IntegerRangeType::createAllGreaterThanOrEqualTo($leftType->getValue());
251+
$sizeType = IntegerRangeType::createAllGreaterThanOrEqualTo($leftType->getValue());
264252
} else {
265-
$constantType = IntegerRangeType::createAllGreaterThan($leftType->getValue());
253+
$sizeType = IntegerRangeType::createAllGreaterThan($leftType->getValue());
266254
}
267255

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;
284259
}
285-
286-
return $this->create($expr->right->getArgs()[0]->value, TypeCombinator::union(...$result), $context, false, $scope, $rootExpr);
287260
}
288261

289262
if (
@@ -976,6 +949,47 @@ public function specifyTypesInCondition(
976949
return new SpecifiedTypes([], [], false, [], $rootExpr);
977950
}
978951

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+
979993
private function specifyTypesForConstantBinaryExpression(
980994
Expr $exprNode,
981995
ConstantScalarType $constantType,

0 commit comments

Comments
 (0)