@@ -302,10 +302,10 @@ private function getProxyDumper()
302
302
return $ this ->proxyDumper ;
303
303
}
304
304
305
- private function analyzeCircularReferences ($ sourceId , array $ edges , &$ checkedNodes , &$ currentPath = [])
305
+ private function analyzeCircularReferences ($ sourceId , array $ edges , &$ checkedNodes , &$ currentPath = [], $ byConstructor = true )
306
306
{
307
307
$ checkedNodes [$ sourceId ] = true ;
308
- $ currentPath [$ sourceId ] = $ sourceId ;
308
+ $ currentPath [$ sourceId ] = $ byConstructor ;
309
309
310
310
foreach ($ edges as $ edge ) {
311
311
$ node = $ edge ->getDestNode ();
@@ -314,44 +314,52 @@ private function analyzeCircularReferences($sourceId, array $edges, &$checkedNod
314
314
if (!$ node ->getValue () instanceof Definition || $ sourceId === $ id || $ edge ->isLazy () || $ edge ->isWeak ()) {
315
315
// no-op
316
316
} elseif (isset ($ currentPath [$ id ])) {
317
- $ currentId = $ id ;
318
- foreach (array_reverse ($ currentPath ) as $ parentId ) {
319
- $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
320
- if ($ parentId === $ id ) {
321
- break ;
322
- }
323
- $ currentId = $ parentId ;
324
- }
317
+ $ this ->addCircularReferences ($ id , $ currentPath , $ edge ->isReferencedByConstructor ());
325
318
} elseif (!isset ($ checkedNodes [$ id ])) {
326
- $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes , $ currentPath );
319
+ $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes , $ currentPath, $ edge -> isReferencedByConstructor () );
327
320
} elseif (isset ($ this ->circularReferences [$ id ])) {
328
- $ this ->connectCircularReferences ($ id , $ currentPath );
321
+ $ this ->connectCircularReferences ($ id , $ currentPath, $ edge -> isReferencedByConstructor () );
329
322
}
330
323
}
331
324
unset($ currentPath [$ sourceId ]);
332
325
}
333
326
334
- private function connectCircularReferences ($ sourceId , &$ currentPath , &$ subPath = [])
327
+ private function connectCircularReferences ($ sourceId , &$ currentPath , $ byConstructor , &$ subPath = [])
335
328
{
336
- $ subPath [$ sourceId ] = $ sourceId ;
337
- $ currentPath [$ sourceId ] = $ sourceId ;
329
+ $ currentPath [$ sourceId ] = $ subPath [$ sourceId ] = $ byConstructor ;
338
330
339
- foreach ($ this ->circularReferences [$ sourceId ] as $ id ) {
331
+ foreach ($ this ->circularReferences [$ sourceId ] as $ id => $ byConstructor ) {
340
332
if (isset ($ currentPath [$ id ])) {
341
- $ currentId = $ id ;
342
- foreach (array_reverse ($ currentPath ) as $ parentId ) {
343
- $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
344
- if ($ parentId === $ id ) {
345
- break ;
346
- }
347
- $ currentId = $ parentId ;
348
- }
333
+ $ this ->addCircularReferences ($ id , $ currentPath , $ byConstructor );
349
334
} elseif (!isset ($ subPath [$ id ]) && isset ($ this ->circularReferences [$ id ])) {
350
- $ this ->connectCircularReferences ($ id , $ currentPath , $ subPath );
335
+ $ this ->connectCircularReferences ($ id , $ currentPath , $ byConstructor , $ subPath );
351
336
}
352
337
}
353
- unset($ currentPath [$ sourceId ]);
354
- unset($ subPath [$ sourceId ]);
338
+ unset($ currentPath [$ sourceId ], $ subPath [$ sourceId ]);
339
+ }
340
+
341
+ private function addCircularReferences ($ id , $ currentPath , $ byConstructor )
342
+ {
343
+ $ currentPath [$ id ] = $ byConstructor ;
344
+ $ circularRefs = [];
345
+
346
+ foreach (array_reverse ($ currentPath ) as $ parentId => $ v ) {
347
+ $ byConstructor = $ byConstructor && $ v ;
348
+ $ circularRefs [] = $ parentId ;
349
+
350
+ if ($ parentId === $ id ) {
351
+ break ;
352
+ }
353
+ }
354
+
355
+ $ currentId = $ id ;
356
+ foreach ($ circularRefs as $ parentId ) {
357
+ if (empty ($ this ->circularReferences [$ parentId ][$ currentId ])) {
358
+ $ this ->circularReferences [$ parentId ][$ currentId ] = $ byConstructor ;
359
+ }
360
+
361
+ $ currentId = $ parentId ;
362
+ }
355
363
}
356
364
357
365
private function collectLineage ($ class , array &$ lineage )
@@ -661,7 +669,6 @@ private function addService($id, Definition $definition, &$file = null)
661
669
$ autowired = $ definition ->isAutowired () ? ' autowired ' : '' ;
662
670
663
671
if ($ definition ->isLazy ()) {
664
- unset($ this ->circularReferences [$ id ]);
665
672
$ lazyInitialization = '$lazyLoad = true ' ;
666
673
} else {
667
674
$ lazyInitialization = '' ;
@@ -736,12 +743,12 @@ private function addInlineVariables($id, Definition $definition, array $argument
736
743
737
744
private function addInlineReference ($ id , Definition $ definition , $ targetId , $ forConstructor )
738
745
{
739
- list ($ callCount , $ behavior ) = $ this ->serviceCalls [$ targetId ];
740
-
741
746
while ($ this ->container ->hasAlias ($ targetId )) {
742
747
$ targetId = (string ) $ this ->container ->getAlias ($ targetId );
743
748
}
744
749
750
+ list ($ callCount , $ behavior ) = $ this ->serviceCalls [$ targetId ];
751
+
745
752
if ($ id === $ targetId ) {
746
753
return $ this ->addInlineService ($ id , $ definition , $ definition );
747
754
}
@@ -750,9 +757,13 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
750
757
return '' ;
751
758
}
752
759
753
- $ hasSelfRef = isset ($ this ->circularReferences [$ id ][$ targetId ]);
754
- $ forConstructor = $ forConstructor && !isset ($ this ->definitionVariables [$ definition ]);
755
- $ code = $ hasSelfRef && !$ forConstructor ? $ this ->addInlineService ($ id , $ definition , $ definition ) : '' ;
760
+ $ hasSelfRef = isset ($ this ->circularReferences [$ id ][$ targetId ]) && !isset ($ this ->definitionVariables [$ definition ]);
761
+
762
+ if ($ hasSelfRef && !$ forConstructor && !$ forConstructor = !$ this ->circularReferences [$ id ][$ targetId ]) {
763
+ $ code = $ this ->addInlineService ($ id , $ definition , $ definition );
764
+ } else {
765
+ $ code = '' ;
766
+ }
756
767
757
768
if (isset ($ this ->referenceVariables [$ targetId ]) || (2 > $ callCount && (!$ hasSelfRef || !$ forConstructor ))) {
758
769
return $ code ;
@@ -785,15 +796,23 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
785
796
786
797
private function addInlineService ($ id , Definition $ definition , Definition $ inlineDef = null , $ forConstructor = true )
787
798
{
788
- $ isSimpleInstance = $ isRootInstance = null === $ inlineDef ;
799
+ $ code = '' ;
800
+
801
+ if ($ isSimpleInstance = $ isRootInstance = null === $ inlineDef ) {
802
+ foreach ($ this ->serviceCalls as $ targetId => list ($ callCount , $ behavior , $ byConstructor )) {
803
+ if ($ byConstructor && isset ($ this ->circularReferences [$ id ][$ targetId ]) && !$ this ->circularReferences [$ id ][$ targetId ]) {
804
+ $ code .= $ this ->addInlineReference ($ id , $ definition , $ targetId , $ forConstructor );
805
+ }
806
+ }
807
+ }
789
808
790
809
if (isset ($ this ->definitionVariables [$ inlineDef = $ inlineDef ?: $ definition ])) {
791
- return '' ;
810
+ return $ code ;
792
811
}
793
812
794
813
$ arguments = [$ inlineDef ->getArguments (), $ inlineDef ->getFactory ()];
795
814
796
- $ code = $ this ->addInlineVariables ($ id , $ definition , $ arguments , $ forConstructor );
815
+ $ code . = $ this ->addInlineVariables ($ id , $ definition , $ arguments , $ forConstructor );
797
816
798
817
if ($ arguments = array_filter ([$ inlineDef ->getProperties (), $ inlineDef ->getMethodCalls (), $ inlineDef ->getConfigurator ()])) {
799
818
$ isSimpleInstance = false ;
@@ -1550,20 +1569,24 @@ private function getServiceConditionals($value)
1550
1569
return implode (' && ' , $ conditions );
1551
1570
}
1552
1571
1553
- private function getDefinitionsFromArguments (array $ arguments , \SplObjectStorage $ definitions = null , array &$ calls = [])
1572
+ private function getDefinitionsFromArguments (array $ arguments , \SplObjectStorage $ definitions = null , array &$ calls = [], $ byConstructor = null )
1554
1573
{
1555
1574
if (null === $ definitions ) {
1556
1575
$ definitions = new \SplObjectStorage ();
1557
1576
}
1558
1577
1559
1578
foreach ($ arguments as $ argument ) {
1560
1579
if (\is_array ($ argument )) {
1561
- $ this ->getDefinitionsFromArguments ($ argument , $ definitions , $ calls );
1580
+ $ this ->getDefinitionsFromArguments ($ argument , $ definitions , $ calls, $ byConstructor );
1562
1581
} elseif ($ argument instanceof Reference) {
1563
1582
$ id = $ this ->container ->normalizeId ($ argument );
1564
1583
1584
+ while ($ this ->container ->hasAlias ($ id )) {
1585
+ $ id = (string ) $ this ->container ->getAlias ($ id );
1586
+ }
1587
+
1565
1588
if (!isset ($ calls [$ id ])) {
1566
- $ calls [$ id ] = [0 , $ argument ->getInvalidBehavior ()];
1589
+ $ calls [$ id ] = [0 , $ argument ->getInvalidBehavior (), $ byConstructor ];
1567
1590
} else {
1568
1591
$ calls [$ id ][1 ] = min ($ calls [$ id ][1 ], $ argument ->getInvalidBehavior ());
1569
1592
}
@@ -1575,8 +1598,10 @@ private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage
1575
1598
$ definitions [$ argument ] = 1 + $ definitions [$ argument ];
1576
1599
} else {
1577
1600
$ definitions [$ argument ] = 1 ;
1578
- $ arguments = [$ argument ->getArguments (), $ argument ->getFactory (), $ argument ->getProperties (), $ argument ->getMethodCalls (), $ argument ->getConfigurator ()];
1579
- $ this ->getDefinitionsFromArguments ($ arguments , $ definitions , $ calls );
1601
+ $ arguments = [$ argument ->getArguments (), $ argument ->getFactory ()];
1602
+ $ this ->getDefinitionsFromArguments ($ arguments , $ definitions , $ calls , null === $ byConstructor || $ byConstructor );
1603
+ $ arguments = [$ argument ->getProperties (), $ argument ->getMethodCalls (), $ argument ->getConfigurator ()];
1604
+ $ this ->getDefinitionsFromArguments ($ arguments , $ definitions , $ calls , null !== $ byConstructor && $ byConstructor );
1580
1605
}
1581
1606
}
1582
1607
@@ -1717,6 +1742,11 @@ private function dumpValue($value, $interpolate = true)
1717
1742
return '$ ' .$ value ;
1718
1743
} elseif ($ value instanceof Reference) {
1719
1744
$ id = $ this ->container ->normalizeId ($ value );
1745
+
1746
+ while ($ this ->container ->hasAlias ($ id )) {
1747
+ $ id = (string ) $ this ->container ->getAlias ($ id );
1748
+ }
1749
+
1720
1750
if (null !== $ this ->referenceVariables && isset ($ this ->referenceVariables [$ id ])) {
1721
1751
return $ this ->dumpValue ($ this ->referenceVariables [$ id ], $ interpolate );
1722
1752
}
0 commit comments