5252use function array_merge ;
5353use function array_pop ;
5454use function array_push ;
55+ use function array_reverse ;
5556use function array_slice ;
5657use function array_unique ;
5758use function array_values ;
@@ -241,7 +242,7 @@ public function getAllArrays(): array
241242 }
242243
243244 $ array = $ builder ->getArray ();
244- if (!$ array instanceof self ) {
245+ if (!$ array instanceof ConstantArrayType ) {
245246 throw new ShouldNotHappenException ();
246247 }
247248
@@ -857,16 +858,14 @@ public function popArray(): Type
857858
858859 public function reverseArray (TrinaryLogic $ preserveKeys ): Type
859860 {
860- $ builder = ConstantArrayTypeBuilder::createEmpty ();
861+ $ keyTypesReversed = array_reverse ($ this ->keyTypes , true );
862+ $ keyTypes = array_values ($ keyTypesReversed );
863+ $ keyTypesReversedKeys = array_keys ($ keyTypesReversed );
864+ $ optionalKeys = array_map (static fn (int $ optionalKey ): int => $ keyTypesReversedKeys [$ optionalKey ], $ this ->optionalKeys );
861865
862- for ($ i = count ($ this ->keyTypes ) - 1 ; $ i >= 0 ; $ i --) {
863- $ offsetType = $ preserveKeys ->yes () || $ this ->keyTypes [$ i ]->isInteger ()->no ()
864- ? $ this ->keyTypes [$ i ]
865- : null ;
866- $ builder ->setOffsetValueType ($ offsetType , $ this ->valueTypes [$ i ], $ this ->isOptionalKey ($ i ));
867- }
866+ $ reversed = new self ($ keyTypes , array_reverse ($ this ->valueTypes ), $ this ->nextAutoIndexes , $ optionalKeys , TrinaryLogic::createNo ());
868867
869- return $ builder -> getArray ();
868+ return $ preserveKeys -> yes () ? $ reversed : $ reversed -> reindex ();
870869 }
871870
872871 public function searchArray (Type $ needleType ): Type
@@ -995,14 +994,15 @@ public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $pre
995994 $ isOptional = true ;
996995 }
997996
998- $ offsetType = $ preserveKeys ->yes () || $ this ->keyTypes [$ i ]->isInteger ()->no ()
999- ? $ this ->keyTypes [$ i ]
1000- : null ;
997+ $ builder ->setOffsetValueType ($ this ->keyTypes [$ i ], $ this ->valueTypes [$ i ], $ isOptional );
998+ }
1001999
1002- $ builder ->setOffsetValueType ($ offsetType , $ this ->valueTypes [$ i ], $ isOptional );
1000+ $ slice = $ builder ->getArray ();
1001+ if (!$ slice instanceof self) {
1002+ throw new ShouldNotHappenException ();
10031003 }
10041004
1005- return $ builder -> getArray ();
1005+ return $ preserveKeys -> yes () ? $ slice : $ slice -> reindex ();
10061006 }
10071007
10081008 public function isIterableAtLeastOnce (): TrinaryLogic
@@ -1148,7 +1148,7 @@ private function removeLastElements(int $length): self
11481148 }
11491149
11501150 /** @param positive-int $length */
1151- private function removeFirstElements (int $ length , bool $ reindex = true ): Type
1151+ private function removeFirstElements (int $ length , bool $ reindex = true ): self
11521152 {
11531153 $ builder = ConstantArrayTypeBuilder::createEmpty ();
11541154
@@ -1175,7 +1175,30 @@ private function removeFirstElements(int $length, bool $reindex = true): Type
11751175 $ builder ->setOffsetValueType ($ keyType , $ valueType , $ isOptional );
11761176 }
11771177
1178- return $ builder ->getArray ();
1178+ $ array = $ builder ->getArray ();
1179+ if (!$ array instanceof self) {
1180+ throw new ShouldNotHappenException ();
1181+ }
1182+
1183+ return $ array ;
1184+ }
1185+
1186+ private function reindex (): self
1187+ {
1188+ $ keyTypes = [];
1189+ $ autoIndex = 0 ;
1190+
1191+ foreach ($ this ->keyTypes as $ keyType ) {
1192+ if (!$ keyType instanceof ConstantIntegerType) {
1193+ $ keyTypes [] = $ keyType ;
1194+ continue ;
1195+ }
1196+
1197+ $ keyTypes [] = new ConstantIntegerType ($ autoIndex );
1198+ $ autoIndex ++;
1199+ }
1200+
1201+ return new self ($ keyTypes , $ this ->valueTypes , [$ autoIndex ], $ this ->optionalKeys , TrinaryLogic::createYes ());
11791202 }
11801203
11811204 public function toBoolean (): BooleanType
0 commit comments