66
77use PHPStan \PhpDocParser \Ast \Type \GenericTypeNode ;
88use PHPStan \PhpDocParser \Ast \Type \IdentifierTypeNode ;
9- use PHPStan \Type \ArrayType ;
10- use PHPStan \Type \BooleanType ;
119use PHPStan \Type \Constant \ConstantArrayType ;
12- use PHPStan \Type \FloatType ;
1310use PHPStan \Type \IntegerType ;
14- use PHPStan \Type \IntersectionType ;
1511use PHPStan \Type \MixedType ;
1612use PHPStan \Type \NeverType ;
17- use PHPStan \Type \ObjectWithoutClassType ;
18- use PHPStan \Type \StringType ;
1913use PHPStan \Type \Type ;
20- use PHPStan \Type \UnionType ;
21- use Rector \NodeTypeResolver \PHPStan \Type \TypeFactory ;
14+ use Rector \Privatization \TypeManipulator \TypeNormalizer ;
2215use Rector \StaticTypeMapper \StaticTypeMapper ;
2316
2417final class ConstantArrayTypeGeneralizer
@@ -32,8 +25,8 @@ final class ConstantArrayTypeGeneralizer
3225 private int $ currentNesting = 0 ;
3326
3427 public function __construct (
35- private readonly TypeFactory $ typeFactory ,
3628 private readonly StaticTypeMapper $ staticTypeMapper ,
29+ private readonly TypeNormalizer $ typeNormalizer
3730 ) {
3831 }
3932
@@ -45,7 +38,7 @@ public function generalize(ConstantArrayType $constantArrayType, bool $isFresh =
4538 ++$ this ->currentNesting ;
4639 }
4740
48- $ genericKeyType = $ this ->constantToGenericType ($ constantArrayType ->getKeyType ());
41+ $ genericKeyType = $ this ->typeNormalizer -> generalizeConstantTypes ($ constantArrayType ->getKeyType ());
4942
5043 if ($ constantArrayType ->getItemType () instanceof NeverType) {
5144 $ genericKeyType = new IntegerType ();
@@ -60,7 +53,12 @@ public function generalize(ConstantArrayType $constantArrayType, bool $isFresh =
6053 $ genericItemType = $ this ->generalize ($ itemType , false );
6154 }
6255 } else {
63- $ genericItemType = $ this ->constantToGenericType ($ itemType );
56+ $ genericItemType = $ this ->typeNormalizer ->generalizeConstantTypes ($ itemType );
57+ }
58+
59+ // correct
60+ if ($ genericItemType instanceof NeverType) {
61+ $ genericItemType = new MixedType ();
6462 }
6563
6664 return $ this ->createArrayGenericTypeNode ($ genericKeyType , $ genericItemType );
@@ -78,51 +76,4 @@ private function createArrayGenericTypeNode(Type $keyType, Type|GenericTypeNode
7876
7977 return new GenericTypeNode (new IdentifierTypeNode ('array ' ), [$ keyDocTypeNode , $ itemDocTypeNode ]);
8078 }
81-
82- /**
83- * Covers constant types too and makes them more generic
84- */
85- private function constantToGenericType (Type $ type ): Type
86- {
87- if ($ type ->isString ()->yes ()) {
88- return new StringType ();
89- }
90-
91- if ($ type ->isInteger ()->yes ()) {
92- return new IntegerType ();
93- }
94-
95- if ($ type ->isBoolean ()->yes ()) {
96- return new BooleanType ();
97- }
98-
99- if ($ type ->isFloat ()->yes ()) {
100- return new FloatType ();
101- }
102-
103- if ($ type ->isObject ()->yes ()) {
104- return new ObjectWithoutClassType ();
105- }
106-
107- if ($ type instanceof UnionType || $ type instanceof IntersectionType) {
108- $ genericComplexTypes = [];
109- foreach ($ type ->getTypes () as $ splitType ) {
110- $ genericComplexTypes [] = $ this ->constantToGenericType ($ splitType );
111- }
112-
113- $ genericComplexTypes = $ this ->typeFactory ->uniquateTypes ($ genericComplexTypes );
114- if (count ($ genericComplexTypes ) > 1 ) {
115- return new UnionType ($ genericComplexTypes );
116- }
117-
118- return $ genericComplexTypes [0 ];
119- }
120-
121- if ($ type instanceof ConstantArrayType) {
122- return new ArrayType (new MixedType (), new MixedType ());
123- }
124-
125- // unclear
126- return new MixedType ();
127- }
12879}
0 commit comments