@@ -155,17 +155,18 @@ public function dump(array $options = array())
155
155
}
156
156
157
157
(new AnalyzeServiceReferencesPass (false , !$ this ->getProxyDumper () instanceof NullDumper))->process ($ this ->container );
158
+ $ checkedNodes = array ();
158
159
$ this ->circularReferences = array (
8000
);
159
- foreach (array (true , false ) as $ byConstructor ) {
160
- foreach ($ this ->container ->getCompiler ()->getServiceReferenceGraph ()->getNodes () as $ id => $ node ) {
161
- if (!$ node ->getValue () instanceof Definition) {
162
- continue ;
163
- }
164
- $ currentPath = array ($ id => true );
165
- $ this ->analyzeCircularReferences ($ node ->getOutEdges (), $ currentPath , $ id , $ byConstructor );
160
+ foreach ($ this ->container ->getCompiler ()->getServiceReferenceGraph ()->getNodes () as $ id => $ node ) {
161
+ if (!$ node ->getValue () instanceof Definition) {
162
+ continue ;
163
+ }
164
+ if (!isset ($ checkedNodes [$ id ])) {
165
+ $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes );
166
166
}
167
167
}
168
168
$ this ->container ->getCompiler ()->getServiceReferenceGraph ()->clear ();
169
+ $ checkedNodes = array ();
169
170
170
171
$ this ->docStar = $ options ['debug ' ] ? '* ' : '' ;
171
172
@@ -301,12 +302,12 @@ private function getProxyDumper()
301
302
return $ this ->proxyDumper ;
302
303
}
303
304
304
- private function analyzeCircularReferences (array $ edges , &$ currentPath , $ sourceId , $ byConstructor )
305
+ private function analyzeCircularReferences ($ sourceId , array $ edges , &$ checkedNodes , & $ currentPath = array () )
305
306
{
307
+ $ checkedNodes [$ sourceId ] = true ;
308
+ $ currentPath [$ sourceId ] = $ sourceId ;
309
+
306
310
foreach ($ edges as $ edge ) {
307
- if ($ byConstructor && !$ edge ->isReferencedByConstructor ()) {
308
- continue ;
309
- }
310
311
$ node = $ edge ->getDestNode ();
311
312
$ id = $ node ->getId ();
312
313
@@ -315,20 +316,42 @@ private function analyzeCircularReferences(array $edges, &$currentPath, $sourceI
315
316
} elseif (isset ($ currentPath [$ id ])) {
316
317
$ currentId = $ id ;
317
318
foreach (array_reverse ($ currentPath ) as $ parentId ) {
318
- if (!isset ($ this ->circularReferences [$ parentId ][$ currentId ])) {
319
- $ this ->circularReferences [$ parentId ][$ currentId ] = $ byConstructor ;
319
+ $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
320
+ if ($ parentId === $ id ) {
321
+ break ;
320
322
}
323
+ $ currentId = $ parentId ;
324
+ }
325
+ } elseif (!isset ($ checkedNodes [$ id ])) {
326
+ $ this ->analyzeCircularReferences ($ id , $ node ->getOutEdges (), $ checkedNodes , $ currentPath );
327
+ } elseif (isset ($ this ->circularReferences [$ id ])) {
328
+ $ this ->connectCircularReferences ($ id , $ currentPath );
329
+ }
330
+ }
331
+ unset($ currentPath [$ sourceId ]);
332
+ }
333
+
334
+ private function connectCircularReferences ($ sourceId , &$ currentPath , &$ subPath = array ())
335
+ {
336
+ $ subPath [$ sourceId ] = $ sourceId ;
337
+ $ currentPath [$ sourceId ] = $ sourceId ;
338
+
339
+ foreach ($ this ->circularReferences [$ sourceId ] as $ id ) {
340
+ if (isset ($ currentPath [$ id ])) {
341
+ $ currentId = $ id ;
342
+ foreach (array_reverse ($ currentPath ) as $ parentId ) {
343
+ $ this ->circularReferences [$ parentId ][$ currentId ] = $ currentId ;
321
344
if ($ parentId === $ id ) {
322
345
break ;
323
346
}
324
347
$ currentId = $ parentId ;
325
348
}
326
- } else {
327
- $ currentPath [$ id ] = $ id ;
328
- $ this ->analyzeCircularReferences ($ node ->getOutEdges (), $ currentPath , $ id , $ byConstructor );
329
- unset($ currentPath [$ id ]);
349
+ } elseif (!isset ($ subPath [$ id ]) && isset ($ this ->circularReferences [$ id ])) {
350
+ $ this ->connectCircularReferences ($ id , $ currentPath , $ subPath );
330
351
}
331
352
}
353
+ unset($ currentPath [$ sourceId ]);
354
+ unset($ subPath [$ sourceId ]);
332
355
}
333
356
334
357
private function collectLineage ($ class , array &$ lineage )
@@ -569,8 +592,11 @@ private function addServiceConfigurator(Definition $definition, $variableName =
569
592
570
593
if (\is_array ($ callable )) {
571
594
if ($ callable [0 ] instanceof Reference
572
- || ($ callable [0 ] instanceof Definition && $ this ->definitionVariables ->contains ($ callable [0 ]))) {
573
- return sprintf (" %s->%s( \$%s); \n" , $ this ->dumpValue ($ callable [0 ]), $ callable [1 ], $ variableName );
595
+ || ($ callable [0 ] instanceof Definition && $ this ->definitionVariables ->contains ($ callable [0 ]))
596
+ ) {
597
+ $ callable [0 ] = $ this ->dumpValue ($ callable [0 ]);
598
+
599
+ return sprintf (' ' .('$ ' === $ callable [0 ][0 ] ? '%s ' : '(%s) ' )."->%s( \$%s); \n" , $ callable [0 ], $ callable [1 ], $ variableName );
574
600
}
575
601
576
602
$ class = $ this ->dumpValue ($ callable [0 ]);
@@ -724,7 +750,7 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
724
750
725
751
$ hasSelfRef = isset ($ this ->circularReferences [$ id ][$ targetId ]);
726
752
$ forConstructor = $ forConstructor && !isset ($ this ->definitionVariables [$ definition ]);
727
- $ code = $ hasSelfRef && $ this -> circularReferences [ $ id ][ $ targetId ] && !$ forConstructor ? $ this ->addInlineService ($ id , $ definition , $ definition ) : '' ;
753
+ $ code = $ hasSelfRef && !$ forConstructor ? $ this ->addInlineService ($ id , $ definition , $ definition ) : '' ;
728
754
729
755
if (isset ($ this ->referenceVariables [$ targetId ]) || (2 > $ callCount && (!$ hasSelfRef || !$ forConstructor ))) {
730
756
return $ code ;
0 commit comments