8
8
use PHPStan \Type \Constant \ConstantArrayType ;
9
9
use PHPStan \Type \Constant \ConstantArrayTypeBuilder ;
10
10
use PHPStan \Type \DynamicFunctionReturnTypeExtension ;
11
+ use PHPStan \Type \ErrorType ;
11
12
use PHPStan \Type \Generic \GenericObjectType ;
12
13
use PHPStan \Type \Type ;
13
14
use PHPStan \Type \TypeCombinator ;
14
15
use PHPStan \Type \TypeUtils ;
15
- use PHPStan \Type \TypeWithClassName ;
16
16
use Psl \Type \Internal \OptionalType ;
17
17
use Psl \Type \TypeInterface ;
18
18
use function count ;
@@ -40,12 +40,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
40
40
41
41
$ results = [];
42
42
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 );
49
44
}
50
45
51
46
return new GenericObjectType (
@@ -56,32 +51,12 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
56
51
);
57
52
}
58
53
59
- private function createResult (ConstantArrayType $ arrayType ): ? Type
54
+ private function createResult (ConstantArrayType $ arrayType ): Type
60
55
{
61
56
$ builder = ConstantArrayTypeBuilder::createEmpty ();
62
57
foreach ($ arrayType ->getKeyTypes () as $ key ) {
63
58
$ 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 ' ));
85
60
86
61
$ builder ->setOffsetValueType ($ key , $ type , $ optional );
87
62
}
@@ -94,26 +69,12 @@ private function createResult(ConstantArrayType $arrayType): ?Type
94
69
*/
95
70
private function extractOptional (Type $ type ): array
96
71
{
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) {
113
74
return [$ type , false ];
114
75
}
115
76
116
- return [$ t , true ];
77
+ return [$ optionalType , true ];
117
78
}
118
79
119
80
}
0 commit comments