@@ -28,6 +28,7 @@ class CheckCircularReferencesPass implements CompilerPassInterface
28
28
{
29
29
private array $ currentPath ;
30
30
private array $ checkedNodes ;
31
+ private array $ checkedLazyNodes ;
31
32
32
33
/**
33
34
* Checks the ContainerBuilder object for circular references.
@@ -59,22 +60,36 @@ private function checkOutEdges(array $edges): void
59
60
$ node = $ edge ->getDestNode ();
60
61
$ id = $ node ->getId ();
61
62
62
- if (empty ($ this ->checkedNodes [$ id ])) {
63
- // Don't check circular references for lazy edges
64
- if (!$ node ->getValue () || (!$ edge ->isLazy () && !$ edge ->isWeak ())) {
65
- $ searchKey = array_search ($ id , $ this ->currentPath );
66
- $ this ->currentPath [] = $ id ;
63
+ if (!empty ($ this ->checkedNodes [$ id ])) {
64
+ continue ;
65
+ }
66
+
67
+ $ isLeaf = !!$ node ->getValue ();
68
+ $ isConcrete = !$ edge ->isLazy () && !$ edge ->isWeak ();
69
+
70
+ // Skip already checked lazy services if they are still lazy. Will not gain any new information.
71
+ if (!empty ($ this ->checkedLazyNodes [$ id ]) && (!$ isLeaf || !$ isConcrete )) {
72
+ continue ;
73
+ }
67
74
68
- if (false !== $ searchKey ) {
69
- throw new ServiceCircularReferenceException ($ id , \array_slice ($ this ->currentPath , $ searchKey ));
70
- }
75
+ // Process concrete references, otherwise defer check circular references for lazy edges.
76
+ if (!$ isLeaf || $ isConcrete ) {
77
+ $ searchKey = array_search ($ id , $ this ->currentPath );
78
+ $ this ->currentPath [] = $ id ;
71
79
72
- $ this ->checkOutEdges ($ node ->getOutEdges ());
80
+ if (false !== $ searchKey ) {
81
+ throw new ServiceCircularReferenceException ($ id , \array_slice ($ this ->currentPath , $ searchKey ));
73
82
}
74
83
84
+ $ this ->checkOutEdges ($ node ->getOutEdges ());
85
+
75
86
$ this ->checkedNodes [$ id ] = true ;
76
- array_pop ($ this ->currentPath );
87
+ unset($ this ->checkedLazyNodes [$ id ]);
88
+ } else {
89
+ $ this ->checkedLazyNodes [$ id ] = true ;
77
90
}
91
+
92
+ array_pop ($ this ->currentPath );
78
93
}
79
94
}
80
95
}
0 commit comments