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

Skip to content

Commit 53c9316

Browse files
[DI] Fix dumping Doctrine-like service graphs (bis)
1 parent ee49144 commit 53c9316

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ protected function processValue($value, $isRoot = false)
122122
$this->lazy = false;
123123

124124
$byConstructor = $this->byConstructor;
125-
$this->byConstructor = true;
125+
$this->byConstructor = $isRoot || $byConstructor;
126126
$this->processValue($value->getFactory());
127127
$this->processValue($value->getArguments());
128128
$this->byConstructor = $byConstructor;

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,27 @@ public function dump(array $options = [])
157157
(new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
158158
$checkedNodes = [];
159159
$this->circularReferences = [];
160-
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
160+
$graph = $this->container->getCompiler()->getServiceReferenceGraph();
161+
foreach ($graph->getNodes() as $id => $node) {
161162
if (!$node->getValue() instanceof Definition) {
162163
continue;
163164
}
164165
if (!isset($checkedNodes[$id])) {
165166
$this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes);
166167
}
167168
}
168-
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
169+
170+
foreach ($this->circularReferences as $parentId => $targetIds) {
171+
foreach ($graph->getNode($parentId)->getOutEdges() as $edge) {
172+
if (!isset($targetIds[$id = $edge->getDestNode()->getId()])) {
173+
continue;
174+
}
175+
if ($this->circularReferences[$parentId][$id] = $edge->isReferencedByConstructor()) {
176+
unset($targetIds[$id]);
177+
}
178+
}
179+
}
180+
$graph->clear();
169181
$checkedNodes = [];
170182

171183
$this->docStar = $options['debug'] ? '*' : '';
@@ -661,7 +673,6 @@ private function addService($id, Definition $definition, &$file = null)
661673
$autowired = $definition->isAutowired() ? ' autowired' : '';
662674

663675
if ($definition->isLazy()) {
664-
unset($this->circularReferences[$id]);
665676
$lazyInitialization = '$lazyLoad = true';
666677
} else {
667678
$lazyInitialization = '';
@@ -736,12 +747,12 @@ private function addInlineVariables($id, Definition $definition, array $argument
736747

737748
private function addInlineReference($id, Definition $definition, $targetId, $forConstructor)
738749
{
739-
list($callCount, $behavior) = $this->serviceCalls[$targetId];
740-
741750
while ($this->container->hasAlias($targetId)) {
742751
$targetId = (string) $this->container->getAlias($targetId);
743752
}
744753

754+
list($callCount, $behavior) = $this->serviceCalls[$targetId];
755+
745756
if ($id === $targetId) {
746757
return $this->addInlineService($id, $definition, $definition);
747758
}
@@ -751,7 +762,7 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
751762
}
752763

753764
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
754-
$forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]);
765+
$forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]) && !empty($this->circularReferences[$id][$targetId]);
755766
$code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : '';
756767

757768
if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) {
@@ -1562,6 +1573,10 @@ private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage
15621573
} elseif ($argument instanceof Reference) {
15631574
$id = $this->container->normalizeId($argument);
15641575

1576+
while ($this->container->hasAlias($id)) {
1577+
$id = (string) $this->container->getAlias($id);
1578+
}
1579+
15651580
if (!isset($calls[$id])) {
15661581
$calls[$id] = [0, $argument->getInvalidBehavior()];
15671582
} else {
@@ -1716,7 +1731,12 @@ private function dumpValue($value, $interpolate = true)
17161731
} elseif ($value instanceof Variable) {
17171732
return '$'.$value;
17181733
} elseif ($value instanceof Reference) {
1719-
$id = $this->container->normalizeId($value);
1734+
$id = $this->container->normalizeId($id);
1735+
1736+
while ($this->container->hasAlias($id)) {
1737+
$id = (string) $this->container->getAlias($id);
1738+
}
1739+
17201740
if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) {
17211741
return $this->dumpValue($this->referenceVariables[$id], $interpolate);
17221742
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,12 @@ protected function getManager2Service()
370370
protected function getManager3Service($lazyLoad = true)
371371
{
372372
$a = new \stdClass();
373+
374+
$this->services['manager3'] = $instance = new \stdClass($a);
375+
373376
$a->listener = [0 => ${($_ = isset($this->services['listener3']) ? $this->services['listener3'] : $this->getListener3Service()) && false ?: '_'}];
374377

375-
return $this->services['manager3'] = new \stdClass($a);
378+
return $instance;
376379
}
377380

378381
/**
@@ -489,9 +492,12 @@ protected function getLevel6Service()
489492
protected function getManager4Service($lazyLoad = true)
490493
{
491494
$a = new \stdClass();
495+
496+
$this->services['manager4'] = $instance = new \stdClass($a);
497+
492498
$a->listener = [0 => ${($_ = isset($this->services['listener4']) ? $this->services['listener4'] : $this->getListener4Service()) && false ?: '_'}];
493499

494-
return $this->services['manager4'] = new \stdClass($a);
500+
return $instance;
495501
}
496502

497503
/**

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,13 @@ protected function getManager2Service()
497497
*/
498498
protected function getManager3Service($lazyLoad = true)
499499
{
500-
return $this->services['manager3'] = new \stdClass(${($_ = isset($this->services['connection3']) ? $this->services['connection3'] : $this->getConnection3Service()) && false ?: '_'});
500+
$a = ${($_ = isset($this->services['connection3']) ? $this->services['connection3'] : $this->getConnection3Service()) && false ?: '_'};
501+
502+
if (isset($this->services['manager3'])) {
503+
return $this->services['manager3'];
504+
}
505+
506+
return $this->services['manager3'] = new \stdClass($a);
501507
}
502508

503509
/**
@@ -613,7 +619,13 @@ protected function getLevel6Service()
613619
*/
614620
protected function getManager4Service($lazyLoad = true)
615621
{
616-
return $this->services['manager4'] = new \stdClass(${($_ = isset($this->services['connection4']) ? $this->services['connection4'] : $this->getConnection4Service()) && false ?: '_'});
622+
$a = ${($_ = isset($this->services['connection4']) ? $this->services['connection4'] : $this->getConnection4Service()) && false ?: '_'};
623+
624+
if (isset($this->services['manager4'])) {
625+
return $this->services['manager4'];
626+
}
627+
628+
return $this->services['manager4'] = new \stdClass($a);
617629
}
618630

619631
/**

0 commit comments

Comments
 (0)