@@ -187,6 +187,7 @@ public function dump(array $options = [])
187
187
}
188
188
$ this ->container ->getCompiler ()->getServiceReferenceGraph ()->clear ();
189
189
$ checkedNodes = [];
190
+ $ this ->singleUsePrivateIds = array_diff_key ($ this ->singleUsePrivateIds , $ this ->circularReferences );
190
191
191
192
$ this ->docStar = $ options ['debug ' ] ? '* ' : '' ;
192
193
@@ -338,10 +339,10 @@ private function getProxyDumper(): ProxyDumper
338
339
return $ this ->proxyDumper ;
339
340
}
340
341
341
- private function analyzeCircularReferences ($ sourceId , array $ edges , &$ checkedNodes , &$ currentPath = [])
342
+ private function analyzeCircularReferences ($ sourceId , array $ edges , &$ checkedNodes , &$ currentPath = [], $ byConstructor = true )
342
343
{
343
344
$ checkedNodes [$ sourceId ] = true ;
344
- $ currentPath [$ sourceId ] = $ sourceId ;
345
+ $ currentPath [$ sourceId ] = $ byConstructor ;
345
346
346
347
foreach ($ edges as $ edge ) {
347
348
$ node = $ edge ->getDestNode ();
@@ -350,44 +351,46 @@ private function analyzeCircularReferences($sourceId, array $edges, &$checkedNod
350
351
if (!$ node ->getValue () instanceof Definition || $ sourceId === $ id || $ edge ->isLazy () || $ edge ->isWeak ()) {
351
352
// no-op
352
353
} elseif (isset ($ currentPath [$ id ])) {
353
- $ currentId = $ id ;
354
- foreach (array_reverse ($ currentPath ) as $ parentId ) {
355
- $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
356
- if ($ parentId === $ id ) {
357
- break ;
358
- }
359
- $ currentId = $ parentId ;
360
- }
354
+ $ this ->addCircularReferences ($ id , $ currentPath , $ edge ->isReferencedByConstructor ());
361
355
} elseif (!isset ($ checkedNodes [$ id ])) {
362
- $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes , $ currentPath );
356
+ $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes , $ currentPath, $ edge -> isReferencedByConstructor () );
363
357
} elseif (isset ($ this ->circularReferences [$ id ])) {
364
- $ this ->connectCircularReferences ($ id , $ currentPath );
358
+ $ this ->connectCircularReferences ($ id , $ currentPath, $ edge -> isReferencedByConstructor () );
365
359
}
366
360
}
367
361
unset($ currentPath [$ sourceId ]);
368
362
}
369
363
370
- private function connectCircularReferences ($ sourceId , &$ currentPath , &$ subPath = [])
364
+ private function connectCircularReferences ($ sourceId , &$ currentPath , $ byConstructor , &$ subPath = [])
371
365
{
372
- $ subPath [$ sourceId ] = $ sourceId ;
373
- $ currentPath [$ sourceId ] = $ sourceId ;
366
+ $ currentPath [$ sourceId ] = $ subPath [$ sourceId ] = $ byConstructor ;
374
367
375
- foreach ($ this ->circularReferences [$ sourceId ] as $ id ) {
368
+ foreach ($ this ->circularReferences [$ sourceId ] as $ id => $ byConstructor ) {
376
369
if (isset ($ currentPath [$ id ])) {
377
- $ currentId = $ id ;
378
- foreach (array_reverse ($ currentPath ) as $ parentId ) {
379
- $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
380
- if ($ parentId === $ id ) {
381
- break ;
382
- }
383
- $ currentId = $ parentId ;
384
- }
370
+ $ this ->addCircularReferences ($ id , $ currentPath , $ byConstructor );
385
371
} elseif (!isset ($ subPath [$ id ]) && isset ($ this ->circularReferences [$ id ])) {
386
- $ this ->connectCircularReferences ($ id , $ currentPath , $ subPath );
372
+ $ this ->connectCircularReferences ($ id , $ currentPath , $ byConstructor , $ subPath );
387
373
}
388
374
}
389
- unset($ currentPath [$ sourceId ]);
390
- unset($ subPath [$ sourceId ]);
375
+ unset($ currentPath [$ sourceId ], $ subPath [$ sourceId ]);
376
+ }
377
+
378
+ private function addCircularReferences ($ id , $ currentPath , $ byConstructor )
379
+ {
380
+ $ currentPath [$ id ] = $ byConstructor ;
381
+ $ currentId = $ id ;
382
+
383
+ foreach (array_reverse ($ currentPath ) as $ parentId => $ byConstructor ) {
384
+ if (empty ($ this ->circularReferences [$ parentId ][$ currentId ])) {
385
+ $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentPath [$ currentId ];
386
+ }
387
+
388
+ if ($ parentId === $ id ) {
389
+ break ;
390
+ }
391
+
392
+ $ currentId = $ parentId ;
393
+ }
391
394
}
392
395
393
396
private function collectLineage ($ class , array &$ lineage )
@@ -655,7 +658,6 @@ private function addService(string $id, Definition $definition): array
655
658
$ autowired = $ definition ->isAutowired () ? ' autowired ' : '' ;
656
659
657
660
if ($ definition ->isLazy ()) {
658
- unset($ this ->circularReferences [$ id ]);
659
661
$ lazyInitialization = '$lazyLoad = true ' ;
660
662
} else {
661
663
$ lazyInitialization = '' ;
@@ -731,12 +733,12 @@ private function addInlineVariables(string $id, Definition $definition, array $a
731
733
732
734
private function addInlineReference (string $ id , Definition $ definition , string $ targetId , bool $ forConstructor ): string
733
735
{
734
- list ($ callCount , $ behavior ) = $ this ->serviceCalls [$ targetId ];
735
-
736
736
while ($ this ->container ->hasAlias ($ targetId )) {
737
737
$ targetId = (string ) $ this ->container ->getAlias ($ targetId );
738
738
}
739
739
740
+ list ($ callCount , $ behavior ) = $ this ->serviceCalls [$ targetId ];
741
+
740
742
if ($ id === $ targetId ) {
741
743
return $ this ->addInlineService ($ id , $ definition , $ definition );
742
744
}
@@ -746,7 +748,7 @@ private function addInlineReference(string $id, Definition $definition, string $
746
748
}
747
749
748
750
$ hasSelfRef = isset ($ this ->circularReferences [$ id ][$ targetId ]);
749
- $ forConstructor = $ forConstructor && !isset ($ this ->definitionVariables [$ definition ]);
751
+ $ forConstructor = $ forConstructor && !isset ($ this ->definitionVariables [$ definition ]) && ! empty ( $ this -> circularReferences [ $ id ][ $ targetId ]) ;
750
752
$ code = $ hasSelfRef && !$ forConstructor ? $ this ->addInlineService ($ id , $ definition , $ definition ) : '' ;
751
753
752
754
if (isset ($ this ->referenceVariables [$ targetId ]) || (2 > $ callCount && (!$ hasSelfRef || !$ forConstructor ))) {
@@ -1415,6 +1417,10 @@ private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage
1415
1417
} elseif ($ argument instanceof Reference) {
1416
1418
$ id = (string ) $ argument ;
1417
1419
1420
+ while ($ this ->container ->hasAlias ($ id )) {
1421
+ $ id = (string ) $ this ->container ->getAlias ($ id );
1422
+ }
1423
+
1418
1424
if (!isset ($ calls [$ id ])) {
1419
1425
$ calls [$ id ] = [0 , $ argument ->getInvalidBehavior ()];
1420
1426
} else {
@@ -1548,6 +1554,11 @@ private function dumpValue($value, bool $interpolate = true): string
1548
1554
return '$ ' .$ value ;
1549
1555
} elseif ($ value instanceof Reference) {
1550
1556
$ id = (string ) $ value ;
1557
+
1558
+ while ($ this ->container ->hasAlias ($ id )) {
1559
+ $ id = (string ) $ this ->container ->getAlias ($ id );
1560
+ }
1561
+
1551
1562
if (null !== $ this ->referenceVariables && isset ($ this ->referenceVariables [$ id ])) {
1552
1563
return $ this ->dumpValue ($ this ->referenceVariables [$ id ], $ interpolate );
1553
1564
}
0 commit comments