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