Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4e92d10

Browse files
[DI] fix analyzing lazy refs involved in circular loops
1 parent ba31bab commit 4e92d10

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
3434
private $graph;
3535
private $currentDefinition;
3636
private $onlyConstructorArguments;
37+
private $hasProxyDumper;
3738
private $lazy;
3839
private $expressionLanguage;
3940

4041
/**
4142
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
4243
*/
43-
public function __construct($onlyConstructorArguments = false)
44+
public function __construct($onlyConstructorArguments = false, $hasProxyDumper = true)
4445
{
4546
$this->onlyConstructorArguments = (bool) $onlyConstructorArguments;
47+
$this->hasProxyDumper = (bool) $hasProxyDumper;
4648
}
4749

4850
/**
@@ -97,7 +99,7 @@ protected function processValue($value, $isRoot = false)
9799
$targetId,
98100
$targetDefinition,
99101
$value,
100-
$this->lazy || ($targetDefinition && $targetDefinition->isLazy()),
102+
$this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
101103
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
102104
);
103105

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1616
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1717
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
18+
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
1819
use Symfony\Component\DependencyInjection\Container;
1920
use Symfony\Component\DependencyInjection\ContainerBuilder;
2021
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -139,29 +140,19 @@ public function dump(array $options = array())
139140
$this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);
140141

141142
if ($this->getProxyDumper() instanceof NullDumper) {
142-
(new AnalyzeServiceReferencesPass(true))->process($this->container);
143-
$this->circularReferences = array();
144-
$checkedNodes = array();
145-
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
146-
$currentPath = array($id => $id);
147-
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
148-
}
149-
foreach ($this->circularReferences as $parent => $ids) {
150-
$path = array($parent);
151-
while (!isset($ids[$parent])) {
152-
foreach ($ids as $id) {
153-
$path[] = $id;
154-
$ids = $this->circularReferences[$id];
155-
break;
156-
}
157-
}
158-
$path[] = $parent.'". Try running "composer require symfony/proxy-manager-bridge';
143+
(new AnalyzeServiceReferencesPass(true, false))->process($this->container);
144+
try {
145+
(new CheckCircularReferencesPass())->process($this->container);
146+
} catch (ServiceCircularReferenceException $e) {
147+
$path = $e->getPath();
148+
end($path);
149+
$path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge';
159150

160-
throw new ServiceCircularReferenceException($parent, $path);
151+
throw new ServiceCircularReferenceException($e->getServiceId(), $path);
161152
}
162153
}
163154

164-
(new AnalyzeServiceReferencesPass())->process($this->container);
155+
(new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
165156
$this->circularReferences = array();
166157
$checkedNodes = array();
167158
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
@@ -367,7 +358,7 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre
367358
$node = $edge->getDestNode();
368359
$id = $node->getId();
369360

370-
if ($node->getValue() && (($edge->isLazy() && !$this->getProxyDumper() instanceof NullDumper) || $edge->isWeak())) {
361+
if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) {
371362
// no-op
372363
} elseif (isset($currentPath[$id])) {
373364
foreach (array_reverse($currentPath) as $parentId) {

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ public function testCircularReferenceAllowanceForLazyServices()
538538

539539
$dumper = new PhpDumper($container);
540540

541-
$message = 'Circular reference detected for service "bar", path: "bar -> foo -> bar". Try running "composer require symfony/proxy-manager-bridge".';
541+
$message = 'Circular reference detected for service "foo", path: "foo -> bar -> foo". Try running "composer require symfony/proxy-manager-bridge".';
542542
if (method_exists($this, 'expectException')) {
543543
$this->expectException(ServiceCircularReferenceException::class);
544544
$this->expectExceptionMessage($message);

0 commit comments

Comments
 (0)