Skip to content

Commit

Permalink
Use early-returns in TypeCombinator
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm authored and ondrejmirtes committed Jul 1, 2024
1 parent 057a348 commit cb9978d
Showing 1 changed file with 47 additions and 47 deletions.
94 changes: 47 additions & 47 deletions src/Type/TypeCombinator.php
Original file line number Diff line number Diff line change
Expand Up @@ -765,62 +765,62 @@ private static function optimizeConstantArrays(array $types): array
{
$constantArrayValuesCount = self::countConstantArrayValueTypes($types);

if ($constantArrayValuesCount > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
$results = [];
foreach ($types as $type) {
$results[] = TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
if ($type instanceof ConstantArrayType) {
if ($type->isIterableAtLeastOnce()->no()) {
return $type;
}
if ($constantArrayValuesCount <= ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
return $types;
}

$isList = true;
$valueTypes = [];
$keyTypes = [];
$nextAutoIndex = 0;
foreach ($type->getKeyTypes() as $i => $innerKeyType) {
if (!$innerKeyType instanceof ConstantIntegerType) {
$isList = false;
} elseif ($innerKeyType->getValue() !== $nextAutoIndex) {
$isList = false;
$nextAutoIndex = $innerKeyType->getValue() + 1;
} else {
$nextAutoIndex++;
}

$generalizedKeyType = $innerKeyType->generalize(GeneralizePrecision::moreSpecific());
$keyTypes[$generalizedKeyType->describe(VerbosityLevel::precise())] = $generalizedKeyType;

$innerValueType = $type->getValueTypes()[$i];
$generalizedValueType = TypeTraverser::map($innerValueType, static function (Type $type, callable $innerTraverse) use ($traverse): Type {
if ($type instanceof ArrayType) {
return TypeCombinator::intersect($type, new OversizedArrayType());
}

return $traverse($type);
});
$valueTypes[$generalizedValueType->describe(VerbosityLevel::precise())] = $generalizedValueType;
}
$results = [];
foreach ($types as $type) {
$results[] = TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
if (!$type instanceof ConstantArrayType) {
return $traverse($type);
}

$keyType = TypeCombinator::union(...array_values($keyTypes));
$valueType = TypeCombinator::union(...array_values($valueTypes));
if ($type->isIterableAtLeastOnce()->no()) {
return $type;
}

$arrayType = new ArrayType($keyType, $valueType);
if ($isList) {
$arrayType = AccessoryArrayListType::intersectWith($arrayType);
$isList = true;
$valueTypes = [];
$keyTypes = [];
$nextAutoIndex = 0;
foreach ($type->getKeyTypes() as $i => $innerKeyType) {
if (!$innerKeyType instanceof ConstantIntegerType) {
$isList = false;
} elseif ($innerKeyType->getValue() !== $nextAutoIndex) {
$isList = false;
$nextAutoIndex = $innerKeyType->getValue() + 1;
} else {
$nextAutoIndex++;
}

$generalizedKeyType = $innerKeyType->generalize(GeneralizePrecision::moreSpecific());
$keyTypes[$generalizedKeyType->describe(VerbosityLevel::precise())] = $generalizedKeyType;

$innerValueType = $type->getValueTypes()[$i];
$generalizedValueType = TypeTraverser::map($innerValueType, static function (Type $type, callable $innerTraverse) use ($traverse): Type {
if ($type instanceof ArrayType) {
return TypeCombinator::intersect($type, new OversizedArrayType());
}

return TypeCombinator::intersect($arrayType, new NonEmptyArrayType(), new OversizedArrayType());
}
return $traverse($type);
});
$valueTypes[$generalizedValueType->describe(VerbosityLevel::precise())] = $generalizedValueType;
}

return $traverse($type);
});
}
$keyType = TypeCombinator::union(...array_values($keyTypes));
$valueType = TypeCombinator::union(...array_values($valueTypes));

$arrayType = new ArrayType($keyType, $valueType);
if ($isList) {
$arrayType = AccessoryArrayListType::intersectWith($arrayType);
}

return $results;
return TypeCombinator::intersect($arrayType, new NonEmptyArrayType(), new OversizedArrayType());
});
}

return $types;
return $results;
}

/**
Expand Down

0 comments on commit cb9978d

Please sign in to comment.