Skip to content

Commit fc54113

Browse files
committed
Simplify by not using TypeTraverser
1 parent b8309fd commit fc54113

File tree

1 file changed

+55
-51
lines changed

1 file changed

+55
-51
lines changed

src/Analyser/TypeSpecifier.php

+55-51
Original file line numberDiff line numberDiff line change
@@ -988,71 +988,75 @@ private function specifyTypesForCountFuncCall(
988988
return null;
989989
}
990990

991-
$resultType = TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($sizeType, $context) {
992-
if ($type instanceof UnionType) {
993-
return $traverse($type);
994-
}
995-
996-
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($type->getArraySize());
997-
if ($isSizeSuperTypeOfArraySize->no()) {
998-
return new NeverType();
991+
$resultTypes = [];
992+
$innerTypes = $type instanceof UnionType ? $type->getTypes() : [$type];
993+
foreach ($innerTypes as $innerType) {
994+
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($innerType->getArraySize());
995+
if ($context->truthy() && $isSizeSuperTypeOfArraySize->no()) {
996+
$resultTypes[] = new ConstantArrayType([], []);
997+
continue;
999998
}
1000-
if ($context->falsey() && $isSizeSuperTypeOfArraySize->maybe()) {
1001-
return new NeverType();
999+
if ($context->falsey() && !$isSizeSuperTypeOfArraySize->yes()) {
1000+
continue;
10021001
}
10031002

1004-
if ($type->isList()->yes()) {
1005-
if (
1006-
$sizeType instanceof ConstantIntegerType
1007-
&& $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1008-
) {
1009-
// turn optional offsets non-optional
1010-
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1011-
for ($i = 0; $i < $sizeType->getValue(); $i++) {
1012-
$offsetType = new ConstantIntegerType($i);
1013-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType));
1014-
}
1015-
return $valueTypesBuilder->getArray();
1003+
if (
1004+
$innerType->isList()->yes()
1005+
&& $sizeType instanceof ConstantIntegerType
1006+
&& $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1007+
) {
1008+
// turn optional offsets non-optional
1009+
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1010+
for ($i = 0; $i < $sizeType->getValue(); $i++) {
1011+
$offsetType = new ConstantIntegerType($i);
1012+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
10161013
}
1014+
$resultTypes[] = $valueTypesBuilder->getArray();
1015+
continue;
1016+
}
10171017

1018-
if (
1019-
$sizeType instanceof IntegerRangeType
1020-
&& $sizeType->getMin() !== null
1021-
) {
1022-
// turn optional offsets non-optional
1023-
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1024-
for ($i = 0; $i < $sizeType->getMin(); $i++) {
1018+
if (
1019+
$innerType->isList()->yes()
1020+
&& $sizeType instanceof IntegerRangeType
1021+
&& $sizeType->getMin() !== null
1022+
) {
1023+
// turn optional offsets non-optional
1024+
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1025+
for ($i = 0; $i < $sizeType->getMin(); $i++) {
1026+
$offsetType = new ConstantIntegerType($i);
1027+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
1028+
}
1029+
if ($sizeType->getMax() !== null) {
1030+
for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) {
10251031
$offsetType = new ConstantIntegerType($i);
1026-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType));
1032+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), true);
10271033
}
1028-
if ($sizeType->getMax() !== null) {
1029-
for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) {
1030-
$offsetType = new ConstantIntegerType($i);
1031-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), true);
1032-
}
1033-
} elseif ($type->isConstantArray()->yes()) {
1034-
for ($i = $sizeType->getMin();; $i++) {
1035-
$offsetType = new ConstantIntegerType($i);
1036-
$hasOffset = $type->hasOffsetValueType($offsetType);
1037-
if ($hasOffset->no()) {
1038-
break;
1039-
}
1040-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), !$hasOffset->yes());
1034+
} elseif ($innerType->isConstantArray()->yes()) {
1035+
for ($i = $sizeType->getMin();; $i++) {
1036+
$offsetType = new ConstantIntegerType($i);
1037+
$hasOffset = $innerType->hasOffsetValueType($offsetType);
1038+
if ($hasOffset->no()) {
1039+
break;
10411040
}
1042-
} else {
1043-
return TypeCombinator::intersect($type, new NonEmptyArrayType());
1041+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), !$hasOffset->yes());
10441042
}
1045-
1046-
return $valueTypesBuilder->getArray();
1043+
} else {
1044+
$resultTypes[] = TypeCombinator::intersect($innerType, new NonEmptyArrayType());
1045+
continue;
10471046
}
10481047

1049-
return $context->truthy() ? $type : new NeverType();
1048+
$resultTypes[] = $valueTypesBuilder->getArray();
1049+
continue;
10501050
}
10511051

1052-
return $context->truthy() ? TypeCombinator::intersect($type, new NonEmptyArrayType()) : new NeverType();
1053-
});
1052+
if (!$context->truthy()) {
1053+
continue;
1054+
}
1055+
1056+
$resultTypes[] = $innerType;
1057+
}
10541058

1055-
return $this->create($countFuncCall->getArgs()[0]->value, $resultType, $context, $scope)->setRootExpr($rootExpr);
1059+
return $this->create($countFuncCall->getArgs()[0]->value, TypeCombinator::union(...$resultTypes), $context, $scope)->setRootExpr($rootExpr);
10561060
}
10571061

10581062
private function specifyTypesForConstantBinaryExpression(

0 commit comments

Comments
 (0)