@@ -122,6 +122,23 @@ public function __construct(
122122 $ this ->isList = $ isList ;
123123 }
124124
125+ /**
126+ * @param list<ConstantIntegerType|ConstantStringType> $keyTypes
127+ * @param array<int, Type> $valueTypes
128+ * @param non-empty-list<int> $nextAutoIndexes
129+ * @param int[] $optionalKeys
130+ */
131+ protected function recreate (
132+ array $ keyTypes ,
133+ array $ valueTypes ,
134+ array $ nextAutoIndexes = [0 ],
135+ array $ optionalKeys = [],
136+ ?TrinaryLogic $ isList = null ,
137+ ): self
138+ {
139+ return new self ($ keyTypes , $ valueTypes , $ nextAutoIndexes , $ optionalKeys , $ isList );
140+ }
141+
125142 public function getConstantArrays (): array
126143 {
127144 return [$ this ];
@@ -765,7 +782,7 @@ public function unsetOffset(Type $offsetType, bool $preserveListCertainty = fals
765782 return new NeverType ();
766783 }
767784
768- return new self ($ newKeyTypes , $ newValueTypes , $ this ->nextAutoIndexes , $ newOptionalKeys , $ newIsList );
785+ return $ this -> recreate ($ newKeyTypes , $ newValueTypes , $ this ->nextAutoIndexes , $ newOptionalKeys , $ newIsList );
769786 }
770787
771788 return $ this ;
@@ -812,7 +829,7 @@ public function unsetOffset(Type $offsetType, bool $preserveListCertainty = fals
812829 return new NeverType ();
813830 }
814831
815- return new self ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ optionalKeys , $ newIsList );
832+ return $ this -> recreate ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ optionalKeys , $ newIsList );
816833 }
817834
818835 $ optionalKeys = $ this ->optionalKeys ;
@@ -842,7 +859,7 @@ public function unsetOffset(Type $offsetType, bool $preserveListCertainty = fals
842859 return new NeverType ();
843860 }
844861
845- return new self ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ optionalKeys , $ newIsList );
862+ return $ this -> recreate ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ optionalKeys , $ newIsList );
846863 }
847864
848865 /**
@@ -1066,7 +1083,7 @@ public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $pre
10661083
10671084 if ($ length === 0 || ($ offset < 0 && $ length < 0 && $ offset - $ length >= 0 )) {
10681085 // 0 / 0, 3 / 0 or e.g. -3 / -3 or -3 / -4 and so on never extract anything
1069- return new self ([], []);
1086+ return $ this -> recreate ([], []);
10701087 }
10711088
10721089 if ($ length < 0 ) {
@@ -1370,7 +1387,7 @@ private function removeLastElements(int $length): self
13701387 $ optionalKeysRemoved --;
13711388 }
13721389
1373- return new self (
1390+ return $ this -> recreate (
13741391 $ keyTypes ,
13751392 $ valueTypes ,
13761393 $ nextAutoindexes ,
@@ -1474,7 +1491,7 @@ public function generalizeValues(): self
14741491 $ valueTypes [] = $ valueType ->generalize (GeneralizePrecision::lessSpecific ());
14751492 }
14761493
1477- return new self ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
1494+ return $ this -> recreate ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
14781495 }
14791496
14801497 private function degradeToGeneralArray (): Type
@@ -1522,7 +1539,7 @@ private function getKeysOrValuesArray(array $types): self
15221539 static fn (int $ i ): ConstantIntegerType => new ConstantIntegerType ($ i ),
15231540 array_keys ($ types ),
15241541 );
1525- return new self ($ keyTypes , $ types , $ autoIndexes , $ this ->optionalKeys , TrinaryLogic::createYes ());
1542+ return $ this -> recreate ($ keyTypes , $ types , $ autoIndexes , $ this ->optionalKeys , TrinaryLogic::createYes ());
15261543 }
15271544
15281545 $ keyTypes = [];
@@ -1551,7 +1568,7 @@ private function getKeysOrValuesArray(array $types): self
15511568 $ maxIndex ++;
15521569 }
15531570
1554- return new self ($ keyTypes , $ valueTypes , $ autoIndexes , $ optionalKeys , TrinaryLogic::createYes ());
1571+ return $ this -> recreate ($ keyTypes , $ valueTypes , $ autoIndexes , $ optionalKeys , TrinaryLogic::createYes ());
15551572 }
15561573
15571574 public function describe (VerbosityLevel $ level ): string
@@ -1716,7 +1733,7 @@ public function traverse(callable $cb): Type
17161733 return $ this ;
17171734 }
17181735
1719- return new self ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
1736+ return $ this -> recreate ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
17201737 }
17211738
17221739 public function traverseSimultaneously (Type $ right , callable $ cb ): Type
@@ -1742,7 +1759,7 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
17421759 return $ this ;
17431760 }
17441761
1745- return new self ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
1762+ return $ this -> recreate ($ this ->keyTypes , $ valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , $ this ->isList );
17461763 }
17471764
17481765 public function isKeysSupersetOf (self $ otherArray ): bool
@@ -1820,7 +1837,7 @@ public function mergeWith(self $otherArray): self
18201837 $ nextAutoIndexes = array_values (array_unique (array_merge ($ this ->nextAutoIndexes , $ otherArray ->nextAutoIndexes )));
18211838 sort ($ nextAutoIndexes );
18221839
1823- return new self ($ this ->keyTypes , $ valueTypes , $ nextAutoIndexes , $ optionalKeys , $ this ->isList ->and ($ otherArray ->isList ));
1840+ return $ this -> recreate ($ this ->keyTypes , $ valueTypes , $ nextAutoIndexes , $ optionalKeys , $ this ->isList ->and ($ otherArray ->isList ));
18241841 }
18251842
18261843 /**
@@ -1874,7 +1891,7 @@ public function makeOffsetRequired(Type $offsetType): self
18741891 }
18751892
18761893 if (count ($ this ->optionalKeys ) !== count ($ optionalKeys )) {
1877- return new self ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , array_values ($ optionalKeys ), $ this ->isList );
1894+ return $ this -> recreate ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , array_values ($ optionalKeys ), $ this ->isList );
18781895 }
18791896
18801897 break ;
@@ -1893,7 +1910,7 @@ public function makeList(): Type
18931910 return new NeverType ();
18941911 }
18951912
1896- return new self ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , TrinaryLogic::createYes ());
1913+ return $ this -> recreate ($ this ->keyTypes , $ this ->valueTypes , $ this ->nextAutoIndexes , $ this ->optionalKeys , TrinaryLogic::createYes ());
18971914 }
18981915
18991916 public function toPhpDocNode (): TypeNode
0 commit comments