@@ -5525,13 +5525,77 @@ private function exactInstantiation(New_ $node, string $className): ?Type
5525
5525
}
5526
5526
}
5527
5527
5528
- if ($ constructorMethod instanceof DummyConstructorReflection || $ constructorMethod -> getDeclaringClass ()-> getName () !== $ classReflection -> getName () ) {
5528
+ if ($ constructorMethod instanceof DummyConstructorReflection) {
5529
5529
return new GenericObjectType (
5530
5530
$ resolvedClassName ,
5531
5531
$ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5532
5532
);
5533
5533
}
5534
5534
5535
+ if ($ constructorMethod ->getDeclaringClass ()->getName () !== $ classReflection ->getName ()) {
5536
+ if (!$ constructorMethod ->getDeclaringClass ()->isGeneric ()) {
5537
+ return new GenericObjectType (
5538
+ $ resolvedClassName ,
5539
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5540
+ );
5541
+ }
5542
+ $ newType = new GenericObjectType ($ resolvedClassName , $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()));
5543
+ $ ancestorType = $ newType ->getAncestorWithClassName ($ constructorMethod ->getDeclaringClass ()->getName ());
5544
+ if ($ ancestorType === null ) {
5545
+ return new GenericObjectType (
5546
+ $ resolvedClassName ,
5547
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5548
+ );
5549
+ }
5550
+ $ ancestorClassReflections = $ ancestorType ->getObjectClassReflections ();
5551
+ if (count ($ ancestorClassReflections ) !== 1 ) {
5552
+ return new GenericObjectType (
5553
+ $ resolvedClassName ,
5554
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5555
+ );
5556
+ }
5557
+
5558
+ $ newParentNode = new New_ (new Name ($ constructorMethod ->getDeclaringClass ()->getName ()), $ node ->args );
5559
+ $ newParentType = $ this ->getType ($ newParentNode );
5560
+ $ newParentTypeClassReflections = $ newParentType ->getObjectClassReflections ();
5561
+ if (count ($ newParentTypeClassReflections ) !== 1 ) {
5562
+ return new GenericObjectType (
5563
+ $ resolvedClassName ,
5564
+ $ classReflection ->typeMapToList ($ classReflection ->getTemplateTypeMap ()->resolveToBounds ()),
5565
+ );
5566
+ }
5567
+ $ newParentTypeClassReflection = $ newParentTypeClassReflections [0 ];
5568
+
5569
+ $ ancestorClassReflection = $ ancestorClassReflections [0 ];
5570
+ $ ancestorMapping = [];
5571
+ foreach ($ ancestorClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ templateType ) {
5572
+ if (!$ templateType instanceof TemplateType) {
5573
+ continue ;
5574
+ }
5575
+
5576
+ $ ancestorMapping [$ typeName ] = $ templateType ->getName ();
5577
+ }
5578
+
5579
+ $ resolvedTypeMap = [];
5580
+ foreach ($ newParentTypeClassReflection ->getActiveTemplateTypeMap ()->getTypes () as $ typeName => $ type ) {
5581
+ if (!array_key_exists ($ typeName , $ ancestorMapping )) {
5582
+ continue ;
5583
+ }
5584
+
5585
+ if (!array_key_exists ($ ancestorMapping [$ typeName ], $ resolvedTypeMap )) {
5586
+ $ resolvedTypeMap [$ ancestorMapping [$ typeName ]] = $ type ;
5587
+ continue ;
5588
+ }
5589
+
5590
+ $ resolvedTypeMap [$ ancestorMapping [$ typeName ]] = TypeCombinator::union ($ resolvedTypeMap [$ ancestorMapping [$ typeName ]], $ type );
5591
+ }
5592
+
5593
+ return new GenericObjectType (
5594
+ $ resolvedClassName ,
5595
+ $ classReflection ->typeMapToList (new TemplateTypeMap ($ resolvedTypeMap )),
5596
+ );
5597
+ }
5598
+
5535
5599
$ parametersAcceptor = ParametersAcceptorSelector::selectFromArgs (
5536
5600
$ this ,
5537
5601
$ methodCall ->getArgs (),
0 commit comments