52
52
use function array_merge ;
53
53
use function array_pop ;
54
54
use function array_push ;
55
+ use function array_reverse ;
55
56
use function array_slice ;
56
57
use function array_unique ;
57
58
use function array_values ;
@@ -241,7 +242,7 @@ public function getAllArrays(): array
241
242
}
242
243
243
244
$ array = $ builder ->getArray ();
244
- if (!$ array instanceof self ) {
245
+ if (!$ array instanceof ConstantArrayType ) {
245
246
throw new ShouldNotHappenException ();
246
247
}
247
248
@@ -857,16 +858,14 @@ public function popArray(): Type
857
858
858
859
public function reverseArray (TrinaryLogic $ preserveKeys ): Type
859
860
{
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 );
861
865
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 ());
868
867
869
- return $ builder -> getArray ();
868
+ return $ preserveKeys -> yes () ? $ reversed : $ reversed -> reindex ();
870
869
}
871
870
872
871
public function searchArray (Type $ needleType ): Type
@@ -995,14 +994,15 @@ public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $pre
995
994
$ isOptional = true ;
996
995
}
997
996
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
+ }
1001
999
1002
- $ builder ->setOffsetValueType ($ offsetType , $ this ->valueTypes [$ i ], $ isOptional );
1000
+ $ slice = $ builder ->getArray ();
1001
+ if (!$ slice instanceof self) {
1002
+ throw new ShouldNotHappenException ();
1003
1003
}
1004
1004
1005
- return $ builder -> getArray ();
1005
+ return $ preserveKeys -> yes () ? $ slice : $ slice -> reindex ();
1006
1006
}
1007
1007
1008
1008
public function isIterableAtLeastOnce (): TrinaryLogic
@@ -1148,7 +1148,7 @@ private function removeLastElements(int $length): self
1148
1148
}
1149
1149
1150
1150
/** @param positive-int $length */
1151
- private function removeFirstElements (int $ length , bool $ reindex = true ): Type
1151
+ private function removeFirstElements (int $ length , bool $ reindex = true ): self
1152
1152
{
1153
1153
$ builder = ConstantArrayTypeBuilder::createEmpty ();
1154
1154
@@ -1175,7 +1175,30 @@ private function removeFirstElements(int $length, bool $reindex = true): Type
1175
1175
$ builder ->setOffsetValueType ($ keyType , $ valueType , $ isOptional );
1176
1176
}
1177
1177
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 ());
1179
1202
}
1180
1203
1181
1204
public function toBoolean (): BooleanType
0 commit comments