Skip to content

Commit 158c61c

Browse files
committed
TrinaryLogic for isList in ConstantArrayType
1 parent 0bb1496 commit 158c61c

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
use function count;
6060
use function implode;
6161
use function in_array;
62+
use function is_bool;
6263
use function is_int;
6364
use function is_string;
6465
use function min;
@@ -76,6 +77,8 @@ class ConstantArrayType extends ArrayType implements ConstantType
7677

7778
private const DESCRIBE_LIMIT = 8;
7879

80+
private TrinaryLogic $isList;
81+
7982
/** @var self[]|null */
8083
private ?array $allArrays = null;
8184

@@ -94,7 +97,7 @@ public function __construct(
9497
private array $valueTypes,
9598
int|array $nextAutoIndexes = [0],
9699
private array $optionalKeys = [],
97-
private bool $isList = false,
100+
bool|TrinaryLogic $isList = false,
98101
)
99102
{
100103
assert(count($keyTypes) === count($valueTypes));
@@ -108,13 +111,18 @@ public function __construct(
108111
$keyTypesCount = count($this->keyTypes);
109112
if ($keyTypesCount === 0) {
110113
$keyType = new NeverType(true);
111-
$this->isList = true;
114+
$isList = TrinaryLogic::createYes();
112115
} elseif ($keyTypesCount === 1) {
113116
$keyType = $this->keyTypes[0];
114117
} else {
115118
$keyType = new UnionType($this->keyTypes);
116119
}
117120

121+
if (is_bool($isList)) {
122+
$isList = TrinaryLogic::createFromBoolean($isList);
123+
}
124+
$this->isList = $isList;
125+
118126
parent::__construct(
119127
$keyType,
120128
count($valueTypes) > 0 ? TypeCombinator::union(...$valueTypes) : new NeverType(true),
@@ -192,7 +200,7 @@ public function getAllArrays(): array
192200
$keys = array_merge($requiredKeys, $combination);
193201
sort($keys);
194202

195-
if ($this->isList && array_keys($keys) !== array_values($keys)) {
203+
if ($this->isList->yes() && array_keys($keys) !== array_values($keys)) {
196204
continue;
197205
}
198206

@@ -841,7 +849,7 @@ public function shuffleArray(): Type
841849
if ($isIterableAtLeastOnce->yes()) {
842850
$generalizedArray = TypeCombinator::intersect($generalizedArray, new NonEmptyArrayType());
843851
}
844-
if ($valuesArray->isList) {
852+
if ($valuesArray->isList->yes()) {
845853
$generalizedArray = AccessoryArrayListType::intersectWith($generalizedArray);
846854
}
847855

@@ -933,7 +941,7 @@ public function isConstantArray(): TrinaryLogic
933941

934942
public function isList(): TrinaryLogic
935943
{
936-
return TrinaryLogic::createFromBoolean($this->isList);
944+
return $this->isList;
937945
}
938946

939947
/** @deprecated Use popArray() instead */
@@ -1122,7 +1130,7 @@ public function reverse(bool $preserveKeys = false): self
11221130
$keyTypesReversedKeys = array_keys($keyTypesReversed);
11231131
$optionalKeys = array_map(static fn (int $optionalKey): int => $keyTypesReversedKeys[$optionalKey], $this->optionalKeys);
11241132

1125-
$reversed = new self($keyTypes, array_reverse($this->valueTypes), $this->nextAutoIndexes, $optionalKeys, false);
1133+
$reversed = new self($keyTypes, array_reverse($this->valueTypes), $this->nextAutoIndexes, $optionalKeys, TrinaryLogic::createNo());
11261134

11271135
return $preserveKeys ? $reversed : $reversed->reindex();
11281136
}
@@ -1161,7 +1169,7 @@ private function reindex(): self
11611169
$autoIndex++;
11621170
}
11631171

1164-
return new self($keyTypes, $this->valueTypes, [$autoIndex], $this->optionalKeys, true);
1172+
return new self($keyTypes, $this->valueTypes, [$autoIndex], $this->optionalKeys, TrinaryLogic::createYes());
11651173
}
11661174

11671175
public function toBoolean(): BooleanType
@@ -1247,7 +1255,7 @@ public function generalizeToArray(): Type
12471255
if ($isIterableAtLeastOnce->yes()) {
12481256
$arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType());
12491257
}
1250-
if ($this->isList) {
1258+
if ($this->isList->yes()) {
12511259
$arrayType = AccessoryArrayListType::intersectWith($arrayType);
12521260
}
12531261

@@ -1279,13 +1287,13 @@ private function getKeysOrValuesArray(array $types): self
12791287
$autoIndexes = range($count - count($this->optionalKeys), $count);
12801288
assert($autoIndexes !== []);
12811289

1282-
if ($this->isList) {
1290+
if ($this->isList->yes()) {
12831291
// Optimized version for lists: Assume that if a later key exists, then earlier keys also exist.
12841292
$keyTypes = array_map(
12851293
static fn (int $i): ConstantIntegerType => new ConstantIntegerType($i),
12861294
array_keys($types),
12871295
);
1288-
return new self($keyTypes, $types, $autoIndexes, $this->optionalKeys, true);
1296+
return new self($keyTypes, $types, $autoIndexes, $this->optionalKeys, TrinaryLogic::createYes());
12891297
}
12901298

12911299
$keyTypes = [];
@@ -1314,7 +1322,7 @@ private function getKeysOrValuesArray(array $types): self
13141322
$maxIndex++;
13151323
}
13161324

1317-
return new self($keyTypes, $valueTypes, $autoIndexes, $optionalKeys, true);
1325+
return new self($keyTypes, $valueTypes, $autoIndexes, $optionalKeys, TrinaryLogic::createYes());
13181326
}
13191327

13201328
/** @deprecated Use getArraySize() instead */
@@ -1539,7 +1547,7 @@ public function mergeWith(self $otherArray): self
15391547
$nextAutoIndexes = array_values(array_unique(array_merge($this->nextAutoIndexes, $otherArray->nextAutoIndexes)));
15401548
sort($nextAutoIndexes);
15411549

1542-
return new self($this->keyTypes, $valueTypes, $nextAutoIndexes, $optionalKeys, $this->isList && $otherArray->isList);
1550+
return new self($this->keyTypes, $valueTypes, $nextAutoIndexes, $optionalKeys, $this->isList->and($otherArray->isList));
15431551
}
15441552

15451553
/**
@@ -1680,7 +1688,7 @@ public function getFiniteTypes(): array
16801688
*/
16811689
public static function __set_state(array $properties): Type
16821690
{
1683-
return new self($properties['keyTypes'], $properties['valueTypes'], $properties['nextAutoIndexes'] ?? $properties['nextAutoIndex'], $properties['optionalKeys'] ?? []);
1691+
return new self($properties['keyTypes'], $properties['valueTypes'], $properties['nextAutoIndexes'] ?? $properties['nextAutoIndex'], $properties['optionalKeys'] ?? [], $properties['isList'] ?? TrinaryLogic::createNo());
16841692
}
16851693

16861694
}

0 commit comments

Comments
 (0)