@@ -86,65 +86,59 @@ public function changeBaseClass(ClassReflection $classReflection): StaticType
8686 return new StaticType ($ classReflection );
8787 }
8888
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+ }
91104
92105 $ newType = new GenericObjectType ($ classReflection ->getName (), $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()));
93106 $ ancestorType = $ newType ->getAncestorWithClassName ($ this ->getClassName ());
94107 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+ );
96114 }
97115
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+ );
101124 }
102125
103- $ ancestorClassReflection = $ ancestorClassReflections [ 0 ];
104- $ ancestorMapping = [];
126+ $ newClassTypes = [ ];
127+ $ newClassVariances = [];
105128 foreach ($ ancestorClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ templateType ) {
106129 if (!$ templateType instanceof TemplateType) {
107130 continue ;
108131 }
109132
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 )) {
141134 continue ;
142135 }
143136
144- $ resolvedVariances [$ ancestorType ->getName ()] = $ resolvedVariances [$ ancestorType ->getName ()]->compose ($ variance );
137+ $ newClassTypes [$ templateType ->getName ()] = $ indexedTypes [$ typeName ];
138+ $ newClassVariances [$ templateType ->getName ()] = $ indexedVariances [$ typeName ];
145139 }
146140
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 )));
148142 }
149143
150144 public function isSuperTypeOf (Type $ type ): IsSuperTypeOfResult
0 commit comments