@@ -5631,13 +5631,77 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56315631 }
56325632 }
56335633
5634- if ($ constructorMethod instanceof DummyConstructorReflection || $ constructorMethod -> getDeclaringClass ()-> getName () !== $ classReflection -> getName () ) {
5634+ if ($ constructorMethod instanceof DummyConstructorReflection) {
56355635 return new GenericObjectType (
56365636 $ resolvedClassName ,
56375637 $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
56385638 );
56395639 }
56405640
5641+ if ($ constructorMethod ->getDeclaringClass ()->getName () !== $ classReflection ->getName ()) {
5642+ if (!$ constructorMethod ->getDeclaringClass ()->isGeneric ()) {
5643+ return new GenericObjectType (
5644+ $ resolvedClassName ,
5645+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5646+ );
5647+ }
5648+ $ newType = new GenericObjectType ($ resolvedClassName , $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()));
5649+ $ ancestorType = $ newType ->getAncestorWithClassName ($ constructorMethod ->getDeclaringClass ()->getName ());
5650+ if ($ ancestorType === null ) {
5651+ return new GenericObjectType (
5652+ $ resolvedClassName ,
5653+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5654+ );
5655+ }
5656+ $ ancestorClassReflections = $ ancestorType ->getObjectClassReflections ();
5657+ if (count ($ ancestorClassReflections ) !== 1 ) {
5658+ return new GenericObjectType (
5659+ $ resolvedClassName ,
5660+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5661+ );
5662+ }
5663+
5664+ $ newParentNode = new New_ (new Name ($ constructorMethod ->getDeclaringClass ()->getName ()), $ node ->args );
5665+ $ newParentType = $ this ->getType ($ newParentNode );
5666+ $ newParentTypeClassReflections = $ newParentType ->getObjectClassReflections ();
5667+ if (count ($ newParentTypeClassReflections ) !== 1 ) {
5668+ return new GenericObjectType (
5669+ $ resolvedClassName ,
5670+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5671+ );
5672+ }
5673+ $ newParentTypeClassReflection = $ newParentTypeClassReflections [0 ];
5674+
5675+ $ ancestorClassReflection = $ ancestorClassReflections [0 ];
5676+ $ ancestorMapping = [];
5677+ foreach ($ ancestorClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ templateType ) {
5678+ if (!$ templateType instanceof TemplateType) {
5679+ continue ;
5680+ }
5681+
5682+ $ ancestorMapping [$ typeName ] = $ templateType ->getName ();
5683+ }
5684+
5685+ $ resolvedTypeMap = [];
5686+ foreach ($ newParentTypeClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ type ) {
5687+ if (!array_key_exists ($ typeName , $ ancestorMapping )) {
5688+ continue ;
5689+ }
5690+
5691+ if (!array_key_exists ($ ancestorMapping [$ typeName ], $ resolvedTypeMap )) {
5692+ $ resolvedTypeMap [$ ancestorMapping [$ typeName ]] = $ type ;
5693+ continue ;
5694+ }
5695+
5696+ $ resolvedTypeMap [$ ancestorMapping [$ typeName ]] = TypeCombinator::union ($ resolvedTypeMap [$ ancestorMapping [$ typeName ]], $ type );
5697+ }
5698+
5699+ return new GenericObjectType (
5700+ $ resolvedClassName ,
5701+ $ classReflection ->typeMapToList (new TemplateTypeMap ($ resolvedTypeMap )),
5702+ );
5703+ }
5704+
56415705 $ parametersAcceptor = ParametersAcceptorSelector::selectFromArgs (
56425706 $ this ,
56435707 $ methodCall ->getArgs (),
0 commit comments