Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a37f3e0

Browse filesBrowse files
[DI] Fix dumping Doctrine-like service graphs (bis)
1 parent ee49144 commit a37f3e0
Copy full SHA for a37f3e0

File tree

Expand file treeCollapse file tree

4 files changed

+98
-48
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+98
-48
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
+1-1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+71-41Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ private function getProxyDumper()
302302
return $this->proxyDumper;
303303
}
304304

305-
private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = [])
305+
private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = [], $byConstructor = true)
306306
{
307307
$checkedNodes[$sourceId] = true;
308-
$currentPath[$sourceId] = $sourceId;
308+
$currentPath[$sourceId] = $byConstructor;
309309

310310
foreach ($edges as $edge) {
311311
$node = $edge->getDestNode();
@@ -314,44 +314,52 @@ private function analyzeCircularReferences($sourceId, array $edges, &$checkedNod
314314
if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) {
315315
// no-op
316316
} elseif (isset($currentPath[$id])) {
317-
$currentId = $id;
318-
foreach (array_reverse($currentPath) as $parentId) {
319-
$this->circularReferences[$parentId][$currentId] = $currentId;
320-
if ($parentId === $id) {
321-
break;
322-
}
323-
$currentId = $parentId;
324-
}
317+
$this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
325318
} elseif (!isset($checkedNodes[$id])) {
326-
$this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath);
319+
$this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor());
327320
} elseif (isset($this->circularReferences[$id])) {
328-
$this->connectCircularReferences($id, $currentPath);
321+
$this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor());
329322
}
330323
}
331324
unset($currentPath[$sourceId]);
332325
}
333326

334-
private function connectCircularReferences($sourceId, &$currentPath, &$subPath = [])
327+
private function connectCircularReferences($sourceId, &$currentPath, $byConstructor, &$subPath = [])
335328
{
336-
$subPath[$sourceId] = $sourceId;
337-
$currentPath[$sourceId] = $sourceId;
329+
$currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor;
338330

339-
foreach ($this->circularReferences[$sourceId] as $id) {
331+
foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) {
340332
if (isset($currentPath[$id])) {
341-
$currentId = $id;
342-
foreach (array_reverse($currentPath) as $parentId) {
343-
$this->circularReferences[$parentId][$currentId] = $currentId;
344-
if ($parentId === $id) {
345-
break;
346-
}
347-
$currentId = $parentId;
348-
}
333+
$this->addCircularReferences($id, $currentPath, $byConstructor);
349334
} elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) {
350-
$this->connectCircularReferences($id, $currentPath, $subPath);
335+
$this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath);
351336
}
352337
}
353-
unset($currentPath[$sourceId]);
354-
unset($subPath[$sourceId]);
338+
unset($currentPath[$sourceId], $subPath[$sourceId]);
339+
}
340+
341+
private function addCircularReferences($id, $currentPath, $byConstructor)
342+
{
343+
$currentPath[$id] = $byConstructor;
344+
$circularRefs = [];
345+
346+
foreach (array_reverse($currentPath) as $parentId => $v) {
347+
$byConstructor = $byConstructor && $v;
348+
$circularRefs[] = $parentId;
349+
350+
if ($parentId === $id) {
351+
break;
352+
}
353+
}
354+
355+
$currentId = $id;
356+
foreach ($circularRefs as $parentId) {
357+
if (empty($this->circularReferences[$parentId][$currentId])) {
358+
$this->circularReferences[$parentId][$currentId] = $byConstructor;
359+
}
360+
361+
$currentId = $parentId;
362+
}
355363
}
356364

357365
private function collectLineage($class, array &$lineage)
@@ -661,7 +669,6 @@ private function addService($id, Definition $definition, &$file = null)
661669
$autowired = $definition->isAutowired() ? ' autowired' : '';
662670

663671
if ($definition->isLazy()) {
664-
unset($this->circularReferences[$id]);
665672
$lazyInitialization = '$lazyLoad = true';
666673
} else {
667674
$lazyInitialization = '';
@@ -736,12 +743,12 @@ private function addInlineVariables($id, Definition $definition, array $argument
736743

737744
private function addInlineReference($id, Definition $definition, $targetId, $forConstructor)
738745
{
739-
list($callCount, $behavior) = $this->serviceCalls[$targetId];
740-
741746
while ($this->container->hasAlias($targetId)) {
742747
$targetId = (string) $this->container->getAlias($targetId);
743748
}
744749

750+
list($callCount, $behavior) = $this->serviceCalls[$targetId];
751+
745752
if ($id === $targetId) {
746753
return $this->addInlineService($id, $definition, $definition);
747754
}
@@ -750,9 +757,13 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
750757
return '';
751758
}
752759

753-
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
754-
$forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]);
755-
$code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : '';
760+
$hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]);
761+
762+
if ($hasSelfRef && !$forConstructor && !$forConstructor = !$this->circularReferences[$id][$targetId]) {
763+
$code = $this->addInlineService($id, $definition, $definition);
764+
} else {
765+
$code = '';
766+
}
756767

757768
if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) {
758769
return $code;
@@ -785,15 +796,23 @@ private function addInlineReference($id, Definition $definition, $targetId, $for
785796

786797
private function addInlineService($id, Definition $definition, Definition $inlineDef = null, $forConstructor = true)
787798
{
788-
$isSimpleInstance = $isRootInstance = null === $inlineDef;
799+
$code = '';
800+
801+
if ($isSimpleInstance = $isRootInstance = null === $inlineDef) {
802+
foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) {
803+
if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) {
804+
$code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor);
805+
}
806+
}
807+
}
789808

790809
if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) {
791-
return '';
810+
return $code;
792811
}
793812

794813
$arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()];
795814

796-
$code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor);
815+
$code .= $this->addInlineVariables($id, $definition, $arguments, $forConstructor);
797816

798817
if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) {
799818
$isSimpleInstance = false;
@@ -1550,20 +1569,24 @@ private function getServiceConditionals($value)
15501569
return implode(' && ', $conditions);
15511570
}
15521571

1553-
private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [])
1572+
private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [], $byConstructor = null)
15541573
{
15551574
if (null === $definitions) {
15561575
$definitions = new \SplObjectStorage();
15571576
}
15581577

15591578
foreach ($arguments as $argument) {
15601579
if (\is_array($argument)) {
1561-
$this->getDefinitionsFromArguments($argument, $definitions, $calls);
1580+
$this->getDefinitionsFromArguments($argument, $definitions, $calls, $byConstructor);
15621581
} elseif ($argument instanceof Reference) {
15631582
$id = $this->container->normalizeId($argument);
15641583

1584+
while ($this->container->hasAlias($id)) {
1585+
$id = (string) $this->container->getAlias($id);
1586+
}
1587+
15651588
if (!isset($calls[$id])) {
1566-
$calls[$id] = [0, $argument->getInvalidBehavior()];
1589+
$calls[$id] = [0, $argument->getInvalidBehavior(), $byConstructor];
15671590
} else {
15681591
$calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior());
15691592
}
@@ -1575,8 +1598,10 @@ private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage
15751598
$definitions[$argument] = 1 + $definitions[$argument];
15761599
} else {
15771600
$definitions[$argument] = 1;
1578-
$arguments = [$argument->getArguments(), $argument->getFactory(), $argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()];
1579-
$this->getDefinitionsFromArguments($arguments, $definitions, $calls);
1601+
$arguments = [$argument->getArguments(), $argument->getFactory()];
1602+
$this->getDefinitionsFromArguments($arguments, $definitions, $calls, null === $byConstructor || $byConstructor);
1603+
$arguments = [$argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()];
1604+
$this->getDefinitionsFromArguments($arguments, $definitions, $calls, null !== $byConstructor && $byConstructor);
15801605
}
15811606
}
15821607

@@ -1717,6 +1742,11 @@ private function dumpValue($value, $interpolate = true)
17171742
return '$'.$value;
17181743
} elseif ($value instanceof Reference) {
17191744
$id = $this->container->normalizeId($value);
1745+
1746+
while ($this->container->hasAlias($id)) {
1747+
$id = (string) $this->container->getAlias($id);
1748+
}
1749+
17201750
if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) {
17211751
return $this->dumpValue($this->referenceVariables[$id], $interpolate);
17221752
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php
+12-4Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,15 @@ protected function getManager2Service()
369369
*/
370370
protected function getManager3Service($lazyLoad = true)
371371
{
372-
$a = new \stdClass();
373-
$a->listener = [0 => ${($_ = isset($this->services['listener3']) ? $this->services['listener3'] : $this->getListener3Service()) && false ?: '_'}];
372+
$a = ${($_ = isset($this->services['listener3']) ? $this->services['listener3'] : $this->getListener3Service()) && false ?: '_'};
373+
374+
if (isset($this->services['manager3'])) {
375+
return $this->services['manager3'];
376+
}
377+
$b = new \stdClass();
378+
$b->listener = [0 => $a];
374379

375-
return $this->services['manager3'] = new \stdClass($a);
380+
return $this->services['manager3'] = new \stdClass($b);
376381
}
377382

378383
/**
@@ -489,9 +494,12 @@ protected function getLevel6Service()
489494
protected function getManager4Service($lazyLoad = true)
490495
{
491496
$a = new \stdClass();
497+
498+
$this->services['manager4'] = $instance = new \stdClass($a);
499+
492500
$a->listener = [0 => ${($_ = isset($this->services['listener4']) ? $this->services['listener4'] : $this->getListener4Service()) && false ?: '_'}];
493501

494-
return $this->services['manager4'] = new \stdClass($a);
502+
return $instance;
495503
}
496504

497505
/**

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php
+14-2Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.