@@ -86,65 +86,59 @@ public function changeBaseClass(ClassReflection $classReflection): StaticType
86
86
return new StaticType ($ classReflection );
87
87
}
88
88
89
- // this template type mapping logic is very similar to mapping logic in MutatingScope::exactInstantiation()
90
- // where inferring "new Foo" but with the constructor being only in Foo parent class
89
+ $ templateTags = $ this ->getClassReflection ()->getTemplateTags ();
90
+ $ i = 0 ;
91
+ $ indexedTypes = [];
92
+ $ indexedVariances = [];
93
+ foreach ($ templateTags as $ typeName => $ tag ) {
94
+ if (!array_key_exists ($ i , $ this ->types )) {
95
+ break ;
96
+ }
97
+ if (!array_key_exists ($ i , $ this ->variances )) {
98
+ break ;
99
+ }
100
+ $ indexedTypes [$ typeName ] = $ this ->types [$ i ];
101
+ $ indexedVariances [$ typeName ] = $ this ->variances [$ i ];
102
+ $ i ++;
103
+ }
91
104
92
105
$ newType = new GenericObjectType ($ classReflection ->getName (), $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()));
93
106
$ ancestorType = $ newType ->getAncestorWithClassName ($ this ->getClassName ());
94
107
if ($ ancestorType === null ) {
95
- return new self ($ classReflection , $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()), $ this ->subtractedType , $ this ->variances );
108
+ return new self (
109
+ $ classReflection ,
110
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
111
+ $ this ->subtractedType ,
112
+ $ classReflection ->varianceMapToList ($ classReflection ->getCallSiteVarianceMap ()),
113
+ );
96
114
}
97
115
98
- $ ancestorClassReflections = $ ancestorType ->getObjectClassReflections ();
99
- if (count ($ ancestorClassReflections ) !== 1 ) {
100
- return new self ($ classReflection , $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()), $ this ->subtractedType , $ this ->variances );
116
+ $ ancestorClassReflection = $ ancestorType ->getClassReflection ();
117
+ if ($ ancestorClassReflection === null ) {
118
+ return new self (
119
+ $ classReflection ,
120
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
121
+ $ this ->subtractedType ,
122
+ $ classReflection ->varianceMapToList ($ classReflection ->getCallSiteVarianceMap ()),
123
+ );
101
124
}
102
125
103
- $ ancestorClassReflection = $ ancestorClassReflections [ 0 ];
104
- $ ancestorMapping = [];
126
+ $ newClassTypes = [ ];
127
+ $ newClassVariances = [];
105
128
foreach ($ ancestorClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ templateType ) {
106
129
if (!$ templateType instanceof TemplateType) {
107
130
continue ;
108
131
}
109
132
110
- $ ancestorMapping [$ typeName ] = $ templateType ;
111
- }
112
-
113
- $ resolvedTypeMap = [];
114
- foreach ($ ancestorClassReflection ->typeMapFromList ($ this ->types )->getTypes () as $ typeName => $ type ) {
115
- if (!array_key_exists ($ typeName , $ ancestorMapping )) {
116
- continue ;
117
- }
118
-
119
- $ ancestorType = $ ancestorMapping [$ typeName ];
120
- if (!$ ancestorType ->getBound ()->isSuperTypeOf ($ type )->yes ()) {
121
- continue ;
122
- }
123
-
124
- if (!array_key_exists ($ ancestorType ->getName (), $ resolvedTypeMap )) {
125
- $ resolvedTypeMap [$ ancestorType ->getName ()] = $ type ;
126
- continue ;
127
- }
128
-
129
- $ resolvedTypeMap [$ ancestorType ->getName ()] = TypeCombinator::union ($ resolvedTypeMap [$ ancestorType ->getName ()], $ type );
130
- }
131
-
132
- $ resolvedVariances = [];
133
- foreach ($ ancestorClassReflection ->varianceMapFromList ($ this ->variances )->getVariances () as $ typeName => $ variance ) {
134
- if (!array_key_exists ($ typeName , $ ancestorMapping )) {
135
- continue ;
136
- }
137
-
138
- $ ancestorType = $ ancestorMapping [$ typeName ];
139
- if (!array_key_exists ($ ancestorType ->getName (), $ resolvedVariances )) {
140
- $ resolvedVariances [$ ancestorType ->getName ()] = $ variance ;
133
+ if (!array_key_exists ($ typeName , $ indexedTypes )) {
141
134
continue ;
142
135
}
143
136
144
- $ resolvedVariances [$ ancestorType ->getName ()] = $ resolvedVariances [$ ancestorType ->getName ()]->compose ($ variance );
137
+ $ newClassTypes [$ templateType ->getName ()] = $ indexedTypes [$ typeName ];
138
+ $ newClassVariances [$ templateType ->getName ()] = $ indexedVariances [$ typeName ];
145
139
}
146
140
147
- return new self ($ classReflection , $ classReflection ->typeMapToList (new TemplateTypeMap ($ resolvedTypeMap )), $ this ->subtractedType , $ classReflection ->varianceMapToList (new TemplateTypeVarianceMap ($ resolvedVariances )));
141
+ return new self ($ classReflection , $ classReflection ->typeMapToList (new TemplateTypeMap ($ newClassTypes )), $ this ->subtractedType , $ classReflection ->varianceMapToList (new TemplateTypeVarianceMap ($ newClassVariances )));
148
142
}
149
143
150
144
public function isSuperTypeOf (Type $ type ): IsSuperTypeOfResult
0 commit comments