Skip to content

Commit e8f9992

Browse files
committed
TypeCombinator - assume that inner types in UnionType are already normalized
1 parent ff39220 commit e8f9992

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

src/Type/TypeCombinator.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ public static function union(Type ...$types): Type
150150
return new NeverType();
151151
}
152152

153+
$alreadyNormalized = [];
154+
$alreadyNormalizedCounter = 0;
155+
153156
$benevolentTypes = [];
154157
$benevolentUnionObject = null;
155158
// transform A | (B | C) to A | B | C
@@ -176,6 +179,8 @@ public static function union(Type ...$types): Type
176179
}
177180

178181
$typesInner = $types[$i]->getTypes();
182+
$alreadyNormalized[$alreadyNormalizedCounter] = $typesInner;
183+
$alreadyNormalizedCounter++;
179184
array_splice($types, $i, 1, $typesInner);
180185
$typesCount += count($typesInner) - 1;
181186
}
@@ -302,6 +307,9 @@ public static function union(Type ...$types): Type
302307
// transform A | never to A
303308
for ($i = 0; $i < $typesCount; $i++) {
304309
for ($j = $i + 1; $j < $typesCount; $j++) {
310+
if (self::isAlreadyNormalized($alreadyNormalized, $types[$i], $types[$j])) {
311+
continue;
312+
}
305313
$compareResult = self::compareTypesInUnion($types[$i], $types[$j]);
306314
if ($compareResult === null) {
307315
continue;
@@ -388,6 +396,31 @@ public static function union(Type ...$types): Type
388396
return new UnionType($types, true);
389397
}
390398

399+
/**
400+
* @param array<int, Type[]> $alreadyNormalized
401+
*/
402+
private static function isAlreadyNormalized(array $alreadyNormalized, Type $a, Type $b): bool
403+
{
404+
foreach ($alreadyNormalized as $normalizedTypes) {
405+
foreach ($normalizedTypes as $i => $normalizedType) {
406+
if ($normalizedType !== $a) {
407+
continue;
408+
}
409+
410+
foreach ($normalizedTypes as $j => $anotherNormalizedType) {
411+
if ($i === $j) {
412+
continue;
413+
}
414+
if ($anotherNormalizedType === $b) {
415+
return true;
416+
}
417+
}
418+
}
419+
}
420+
421+
return false;
422+
}
423+
391424
/**
392425
* @return array{Type, null}|array{null, Type}|null
393426
*/

0 commit comments

Comments
 (0)