88use PHPStan \Type \Constant \ConstantArrayType ;
99use PHPStan \Type \Constant \ConstantArrayTypeBuilder ;
1010use PHPStan \Type \DynamicFunctionReturnTypeExtension ;
11+ use PHPStan \Type \ErrorType ;
1112use PHPStan \Type \Generic \GenericObjectType ;
1213use PHPStan \Type \Type ;
1314use PHPStan \Type \TypeCombinator ;
1415use PHPStan \Type \TypeUtils ;
15- use PHPStan \Type \TypeWithClassName ;
1616use Psl \Type \Internal \OptionalType ;
1717use Psl \Type \TypeInterface ;
1818use function count ;
@@ -40,12 +40,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
4040
4141 $ results = [];
4242 foreach ($ arrays as $ array ) {
43- $ result = $ this ->createResult ($ array );
44- if ($ result === null ) {
45- return null ;
46- }
47-
48- $ results [] = $ result ;
43+ $ results [] = $ this ->createResult ($ array );
4944 }
5045
5146 return new GenericObjectType (
@@ -56,32 +51,12 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
5651 );
5752 }
5853
59- private function createResult (ConstantArrayType $ arrayType ): ? Type
54+ private function createResult (ConstantArrayType $ arrayType ): Type
6055 {
6156 $ builder = ConstantArrayTypeBuilder::createEmpty ();
6257 foreach ($ arrayType ->getKeyTypes () as $ key ) {
6358 $ valueType = $ arrayType ->getOffsetValueType ($ key );
64- if (!$ valueType instanceof TypeWithClassName) {
65- return null ;
66- }
67-
68- $ valueClassReflection = $ valueType ->getClassReflection ();
69- if ($ valueClassReflection === null ) {
70- return null ;
71- }
72-
73- $ typeInterfaceAncestor = $ valueClassReflection ->getAncestorWithClassName (TypeInterface::class);
74- if ($ typeInterfaceAncestor === null ) {
75- return null ;
76- }
77-
78- $ typeMap = $ typeInterfaceAncestor ->getActiveTemplateTypeMap ();
79- $ t = $ typeMap ->getType ('T ' );
80- if ($ t === null ) {
81- return null ;
82- }
83-
84- [$ type , $ optional ] = $ this ->extractOptional ($ t );
59+ [$ type , $ optional ] = $ this ->extractOptional ($ valueType ->getTemplateType (TypeInterface::class, 'T ' ));
8560
8661 $ builder ->setOffsetValueType ($ key , $ type , $ optional );
8762 }
@@ -94,26 +69,12 @@ private function createResult(ConstantArrayType $arrayType): ?Type
9469 */
9570 private function extractOptional (Type $ type ): array
9671 {
97- if (!$ type instanceof TypeWithClassName) {
98- return [$ type , false ];
99- }
100-
101- $ classReflection = $ type ->getClassReflection ();
102- if ($ classReflection === null ) {
103- return [$ type , false ];
104- }
105- $ optionalTypeAncestor = $ classReflection ->getAncestorWithClassName (OptionalType::class);
106- if ($ optionalTypeAncestor === null ) {
107- return [$ type , false ];
108- }
109-
110- $ typeMap = $ optionalTypeAncestor ->getActiveTemplateTypeMap ();
111- $ t = $ typeMap ->getType ('T ' );
112- if ($ t === null ) {
72+ $ optionalType = $ type ->getTemplateType (OptionalType::class, 'T ' );
73+ if ($ optionalType instanceof ErrorType) {
11374 return [$ type , false ];
11475 }
11576
116- return [$ t , true ];
77+ return [$ optionalType , true ];
11778 }
11879
11980}
0 commit comments