Skip to content

Commit 4b53a7f

Browse files
committed
Simplify by not using TypeTraverser
1 parent d4a7715 commit 4b53a7f

File tree

1 file changed

+52
-49
lines changed

1 file changed

+52
-49
lines changed

src/Analyser/TypeSpecifier.php

+52-49
Original file line numberDiff line numberDiff line change
@@ -988,71 +988,74 @@ 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());
991+
$resultTypes = [];
992+
$innerTypes = $type instanceof UnionType ? $type->getTypes() : [$type];
993+
foreach ($innerTypes as $innerType) {
994+
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($innerType->getArraySize());
997995
if ($isSizeSuperTypeOfArraySize->no()) {
998-
return new NeverType();
996+
continue;
999997
}
1000998
if ($context->falsey() && $isSizeSuperTypeOfArraySize->maybe()) {
1001-
return new NeverType();
999+
continue;
10021000
}
10031001

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();
1002+
if (
1003+
$innerType->isList()->yes()
1004+
&& $sizeType instanceof ConstantIntegerType
1005+
&& $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1006+
) {
1007+
// turn optional offsets non-optional
1008+
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1009+
for ($i = 0; $i < $sizeType->getValue(); $i++) {
1010+
$offsetType = new ConstantIntegerType($i);
1011+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
10161012
}
1013+
$resultTypes[] = $valueTypesBuilder->getArray();
1014+
continue;
1015+
}
10171016

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++) {
1017+
if (
1018+
$innerType->isList()->yes()
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++) {
1025+
$offsetType = new ConstantIntegerType($i);
1026+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
1027+
}
1028+
if ($sizeType->getMax() !== null) {
1029+
for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) {
10251030
$offsetType = new ConstantIntegerType($i);
1026-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType));
1031+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), true);
10271032
}
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());
1033+
} elseif ($innerType->isConstantArray()->yes()) {
1034+
for ($i = $sizeType->getMin();; $i++) {
1035+
$offsetType = new ConstantIntegerType($i);
1036+
$hasOffset = $innerType->hasOffsetValueType($offsetType);
1037+
if ($hasOffset->no()) {
1038+
break;
10411039
}
1042-
} else {
1043-
return TypeCombinator::intersect($type, new NonEmptyArrayType());
1040+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), !$hasOffset->yes());
10441041
}
1045-
1046-
return $valueTypesBuilder->getArray();
1042+
} else {
1043+
$resultTypes[] = TypeCombinator::intersect($innerType, new NonEmptyArrayType());
1044+
continue;
10471045
}
10481046

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

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

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

10581061
private function specifyTypesForConstantBinaryExpression(

0 commit comments

Comments
 (0)