Skip to content

Commit f647fc8

Browse files
herndlmondrejmirtes
authored andcommitted
Simplify by not using TypeTraverser
1 parent 6866fd4 commit f647fc8

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
@@ -1065,71 +1065,74 @@ private function specifyTypesForCountFuncCall(
10651065
return null;
10661066
}
10671067

1068-
$resultType = TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($sizeType, $context) {
1069-
if ($type instanceof UnionType) {
1070-
return $traverse($type);
1071-
}
1072-
1073-
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($type->getArraySize());
1068+
$resultTypes = [];
1069+
$innerTypes = $type instanceof UnionType ? $type->getTypes() : [$type];
1070+
foreach ($innerTypes as $innerType) {
1071+
$isSizeSuperTypeOfArraySize = $sizeType->isSuperTypeOf($innerType->getArraySize());
10741072
if ($isSizeSuperTypeOfArraySize->no()) {
1075-
return new NeverType();
1073+
continue;
10761074
}
10771075
if ($context->falsey() && $isSizeSuperTypeOfArraySize->maybe()) {
1078-
return new NeverType();
1076+
continue;
10791077
}
10801078

1081-
if ($type->isList()->yes()) {
1082-
if (
1083-
$sizeType instanceof ConstantIntegerType
1084-
&& $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1085-
) {
1086-
// turn optional offsets non-optional
1087-
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1088-
for ($i = 0; $i < $sizeType->getValue(); $i++) {
1089-
$offsetType = new ConstantIntegerType($i);
1090-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType));
1091-
}
1092-
return $valueTypesBuilder->getArray();
1079+
if (
1080+
$innerType->isList()->yes()
1081+
&& $sizeType instanceof ConstantIntegerType
1082+
&& $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1083+
) {
1084+
// turn optional offsets non-optional
1085+
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1086+
for ($i = 0; $i < $sizeType->getValue(); $i++) {
1087+
$offsetType = new ConstantIntegerType($i);
1088+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
10931089
}
1090+
$resultTypes[] = $valueTypesBuilder->getArray();
1091+
continue;
1092+
}
10941093

1095-
if (
1096-
$sizeType instanceof IntegerRangeType
1097-
&& $sizeType->getMin() !== null
1098-
) {
1099-
// turn optional offsets non-optional
1100-
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1101-
for ($i = 0; $i < $sizeType->getMin(); $i++) {
1094+
if (
1095+
$innerType->isList()->yes()
1096+
&& $sizeType instanceof IntegerRangeType
1097+
&& $sizeType->getMin() !== null
1098+
) {
1099+
// turn optional offsets non-optional
1100+
$valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty();
1101+
for ($i = 0; $i < $sizeType->getMin(); $i++) {
1102+
$offsetType = new ConstantIntegerType($i);
1103+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType));
1104+
}
1105+
if ($sizeType->getMax() !== null) {
1106+
for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) {
11021107
$offsetType = new ConstantIntegerType($i);
1103-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType));
1108+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), true);
11041109
}
1105-
if ($sizeType->getMax() !== null) {
1106-
for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) {
1107-
$offsetType = new ConstantIntegerType($i);
1108-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), true);
1109-
}
1110-
} elseif ($type->isConstantArray()->yes()) {
1111-
for ($i = $sizeType->getMin();; $i++) {
1112-
$offsetType = new ConstantIntegerType($i);
1113-
$hasOffset = $type->hasOffsetValueType($offsetType);
1114-
if ($hasOffset->no()) {
1115-
break;
1116-
}
1117-
$valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), !$hasOffset->yes());
1110+
} elseif ($innerType->isConstantArray()->yes()) {
1111+
for ($i = $sizeType->getMin();; $i++) {
1112+
$offsetType = new ConstantIntegerType($i);
1113+
$hasOffset = $innerType->hasOffsetValueType($offsetType);
1114+
if ($hasOffset->no()) {
1115+
break;
11181116
}
1119-
} else {
1120-
return TypeCombinator::intersect($type, new NonEmptyArrayType());
1117+
$valueTypesBuilder->setOffsetValueType($offsetType, $innerType->getOffsetValueType($offsetType), !$hasOffset->yes());
11211118
}
1122-
1123-
return $valueTypesBuilder->getArray();
1119+
} else {
1120+
$resultTypes[] = TypeCombinator::intersect($innerType, new NonEmptyArrayType());
1121+
continue;
11241122
}
11251123

1126-
return $context->truthy() ? $type : new NeverType();
1124+
$resultTypes[] = $valueTypesBuilder->getArray();
1125+
continue;
11271126
}
11281127

1129-
return $context->truthy() ? TypeCombinator::intersect($type, new NonEmptyArrayType()) : new NeverType();
1130-
});
1128+
if (!$context->truthy()) {
1129+
continue;
1130+
}
1131+
1132+
$resultTypes[] = $innerType;
1133+
}
11311134

1132-
return $this->create($countFuncCall->getArgs()[0]->value, $resultType, $context, $scope)->setRootExpr($rootExpr);
1135+
return $this->create($countFuncCall->getArgs()[0]->value, TypeCombinator::union(...$resultTypes), $context, $scope)->setRootExpr($rootExpr);
11331136
}
11341137

11351138
private function specifyTypesForConstantBinaryExpression(

0 commit comments

Comments
 (0)