Skip to content

Commit 8355ee0

Browse files
committed
Simplify by not using TypeTraverser
1 parent 187596f commit 8355ee0

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
@@ -991,71 +991,74 @@ private function specifyTypesForCountFuncCall(
991991
return null;
992992
}
993993

994-
$resultType = TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($sizeType, $context) {
995-
if ($type instanceof UnionType) {
996-
return $traverse($type);
997-
}
998-
999-
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($type->getArraySize());
994+
$resultTypes = [];
995+
$innerTypes = $type instanceof UnionType ? $type->getTypes() : [$type];
996+
foreach ($innerTypes as $innerType) {
997+
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($innerType->getArraySize());
1000998
if ($isSizeSuperTypeOfArraySize->no()) {
1001-
return new NeverType();
999+
continue;
10021000
}
10031001
if ($context->falsey() && $isSizeSuperTypeOfArraySize->maybe()) {
1004-
return new NeverType();
1002+
continue;
10051003
}
10061004

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

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

1052-
return $context->truthy() ? $type : new NeverType();
1050+
$resultTypes[] = $valueTypesBuilder->getArray();
1051+
continue;
10531052
}
10541053

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

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

10611064
private function specifyTypesForConstantBinaryExpression(

0 commit comments

Comments
 (0)