59
59
use function count ;
60
60
use function implode ;
61
61
use function in_array ;
62
+ use function is_bool ;
62
63
use function is_int ;
63
64
use function is_string ;
64
65
use function min ;
@@ -76,6 +77,8 @@ class ConstantArrayType extends ArrayType implements ConstantType
76
77
77
78
private const DESCRIBE_LIMIT = 8 ;
78
79
80
+ private TrinaryLogic $ isList ;
81
+
79
82
/** @var self[]|null */
80
83
private ?array $ allArrays = null ;
81
84
@@ -94,7 +97,7 @@ public function __construct(
94
97
private array $ valueTypes ,
95
98
int |array $ nextAutoIndexes = [0 ],
96
99
private array $ optionalKeys = [],
97
- private bool $ isList = false ,
100
+ bool | TrinaryLogic $ isList = false ,
98
101
)
99
102
{
100
103
assert (count ($ keyTypes ) === count ($ valueTypes ));
@@ -108,13 +111,18 @@ public function __construct(
108
111
$ keyTypesCount = count ($ this ->keyTypes );
109
112
if ($ keyTypesCount === 0 ) {
110
113
$ keyType = new NeverType (true );
111
- $ this -> isList = true ;
114
+ $ isList = TrinaryLogic:: createYes () ;
112
115
} elseif ($ keyTypesCount === 1 ) {
113
116
$ keyType = $ this ->keyTypes [0 ];
114
117
} else {
115
118
$ keyType = new UnionType ($ this ->keyTypes );
116
119
}
117
120
121
+ if (is_bool ($ isList )) {
122
+ $ isList = TrinaryLogic::createFromBoolean ($ isList );
123
+ }
124
+ $ this ->isList = $ isList ;
125
+
118
126
parent ::__construct (
119
127
$ keyType ,
120
128
count ($ valueTypes ) > 0 ? TypeCombinator::union (...$ valueTypes ) : new NeverType (true ),
@@ -192,7 +200,7 @@ public function getAllArrays(): array
192
200
$ keys = array_merge ($ requiredKeys , $ combination );
193
201
sort ($ keys );
194
202
195
- if ($ this ->isList && array_keys ($ keys ) !== array_values ($ keys )) {
203
+ if ($ this ->isList -> yes () && array_keys ($ keys ) !== array_values ($ keys )) {
196
204
continue ;
197
205
}
198
206
@@ -841,7 +849,7 @@ public function shuffleArray(): Type
841
849
if ($ isIterableAtLeastOnce ->yes ()) {
842
850
$ generalizedArray = TypeCombinator::intersect ($ generalizedArray , new NonEmptyArrayType ());
843
851
}
844
- if ($ valuesArray ->isList ) {
852
+ if ($ valuesArray ->isList -> yes () ) {
845
853
$ generalizedArray = AccessoryArrayListType::intersectWith ($ generalizedArray );
846
854
}
847
855
@@ -933,7 +941,7 @@ public function isConstantArray(): TrinaryLogic
933
941
934
942
public function isList (): TrinaryLogic
935
943
{
936
- return TrinaryLogic:: createFromBoolean ( $ this ->isList ) ;
944
+ return $ this ->isList ;
937
945
}
938
946
939
947
/** @deprecated Use popArray() instead */
@@ -1122,7 +1130,7 @@ public function reverse(bool $preserveKeys = false): self
1122
1130
$ keyTypesReversedKeys = array_keys ($ keyTypesReversed );
1123
1131
$ optionalKeys = array_map (static fn (int $ optionalKey ): int => $ keyTypesReversedKeys [$ optionalKey ], $ this ->optionalKeys );
1124
1132
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 () );
1126
1134
1127
1135
return $ preserveKeys ? $ reversed : $ reversed ->reindex ();
1128
1136
}
@@ -1161,7 +1169,7 @@ private function reindex(): self
1161
1169
$ autoIndex ++;
1162
1170
}
1163
1171
1164
- return new self ($ keyTypes , $ this ->valueTypes , [$ autoIndex ], $ this ->optionalKeys , true );
1172
+ return new self ($ keyTypes , $ this ->valueTypes , [$ autoIndex ], $ this ->optionalKeys , TrinaryLogic:: createYes () );
1165
1173
}
1166
1174
1167
1175
public function toBoolean (): BooleanType
@@ -1247,7 +1255,7 @@ public function generalizeToArray(): Type
1247
1255
if ($ isIterableAtLeastOnce ->yes ()) {
1248
1256
$ arrayType = TypeCombinator::intersect ($ arrayType , new NonEmptyArrayType ());
1249
1257
}
1250
- if ($ this ->isList ) {
1258
+ if ($ this ->isList -> yes () ) {
1251
1259
$ arrayType = AccessoryArrayListType::intersectWith ($ arrayType );
1252
1260
}
1253
1261
@@ -1279,13 +1287,13 @@ private function getKeysOrValuesArray(array $types): self
1279
1287
$ autoIndexes = range ($ count - count ($ this ->optionalKeys ), $ count );
1280
1288
assert ($ autoIndexes !== []);
1281
1289
1282
- if ($ this ->isList ) {
1290
+ if ($ this ->isList -> yes () ) {
1283
1291
// Optimized version for lists: Assume that if a later key exists, then earlier keys also exist.
1284
1292
$ keyTypes = array_map (
1285
1293
static fn (int $ i ): ConstantIntegerType => new ConstantIntegerType ($ i ),
1286
1294
array_keys ($ types ),
1287
1295
);
1288
- return new self ($ keyTypes , $ types , $ autoIndexes , $ this ->optionalKeys , true );
1296
+ return new self ($ keyTypes , $ types , $ autoIndexes , $ this ->optionalKeys , TrinaryLogic:: createYes () );
1289
1297
}
1290
1298
1291
1299
$ keyTypes = [];
@@ -1314,7 +1322,7 @@ private function getKeysOrValuesArray(array $types): self
1314
1322
$ maxIndex ++;
1315
1323
}
1316
1324
1317
- return new self ($ keyTypes , $ valueTypes , $ autoIndexes , $ optionalKeys , true );
1325
+ return new self ($ keyTypes , $ valueTypes , $ autoIndexes , $ optionalKeys , TrinaryLogic:: createYes () );
1318
1326
}
1319
1327
1320
1328
/** @deprecated Use getArraySize() instead */
@@ -1539,7 +1547,7 @@ public function mergeWith(self $otherArray): self
1539
1547
$ nextAutoIndexes = array_values (array_unique (array_merge ($ this ->nextAutoIndexes , $ otherArray ->nextAutoIndexes )));
1540
1548
sort ($ nextAutoIndexes );
1541
1549
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 ) );
1543
1551
}
1544
1552
1545
1553
/**
@@ -1680,7 +1688,7 @@ public function getFiniteTypes(): array
1680
1688
*/
1681
1689
public static function __set_state (array $ properties ): Type
1682
1690
{
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 () );
1684
1692
}
1685
1693
1686
1694
}
0 commit comments