Skip to content

Commit 89db508

Browse files
Merge branch '6.0' into 6.1
* 6.0: [Console] Correctly overwrite progressbars with different line count per step [DependencyInjection] Fix deduplicating service instances in circular graphs [Form] Make `ButtonType` handle `form_attr` option [PhpUnitBridge] Use verbose deprecation output for quiet types only when it reaches the threshold [CssSelector] Fix escape patterns
2 parents b847f2d + 37ffd67 commit 89db508

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

Dumper/PhpDumper.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
3333
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
3434
use Symfony\Component\DependencyInjection\ExpressionLanguage;
35-
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
35+
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
3636
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
3737
use Symfony\Component\DependencyInjection\Loader\FileLoader;
3838
use Symfony\Component\DependencyInjection\Parameter;
@@ -90,7 +90,8 @@ class PhpDumper extends Dumper
9090
private string $serviceLocatorTag;
9191
private array $exportedVariables = [];
9292
private string $baseClass;
93-
private ProxyDumper $proxyDumper;
93+
private DumperInterface $proxyDumper;
94+
private bool $hasProxyDumper = false;
9495

9596
/**
9697
* {@inheritdoc}
@@ -107,9 +108,10 @@ public function __construct(ContainerBuilder $container)
107108
/**
108109
* Sets the dumper to be used when dumping proxies in the generated container.
109110
*/
110-
public function setProxyDumper(ProxyDumper $proxyDumper)
111+
public function setProxyDumper(DumperInterface $proxyDumper)
111112
{
112113
$this->proxyDumper = $proxyDumper;
114+
$this->hasProxyDumper = !$proxyDumper instanceof NullDumper;
113115
}
114116

115117
/**
@@ -167,7 +169,7 @@ public function dump(array $options = []): string|array
167169

168170
$this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);
169171

170-
if ($this->getProxyDumper() instanceof NullDumper) {
172+
if (!$this->hasProxyDumper) {
171173
(new AnalyzeServiceReferencesPass(true, false))->process($this->container);
172174
try {
173175
(new CheckCircularReferencesPass())->process($this->container);
@@ -400,14 +402,14 @@ class %s extends {$options['class']}
400402
/**
401403
* Retrieves the currently set proxy dumper or instantiates one.
402404
*/
403-
private function getProxyDumper(): ProxyDumper
405+
private function getProxyDumper(): DumperInterface
404406
{
405407
return $this->proxyDumper ??= new NullDumper();
406408
}
407409

408410
private function analyzeReferences()
409411
{
410-
(new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
412+
(new AnalyzeServiceReferencesPass(false, $this->hasProxyDumper))->process($this->container);
411413
$checkedNodes = [];
412414
$this->circularReferences = [];
413415
$this->singleUsePrivateIds = [];
@@ -434,13 +436,13 @@ private function collectCircularReferences(string $sourceId, array $edges, array
434436
foreach ($edges as $edge) {
435437
$node = $edge->getDestNode();
436438
$id = $node->getId();
437-
if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isLazy() || $edge->isWeak()) {
439+
if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isWeak()) {
438440
continue;
439441
}
440442

441443
if (isset($path[$id])) {
442444
$loop = null;
443-
$loopByConstructor = $edge->isReferencedByConstructor();
445+
$loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
444446
$pathInLoop = [$id, []];
445447
foreach ($path as $k => $pathByConstructor) {
446448
if (null !== $loop) {
@@ -454,7 +456,7 @@ private function collectCircularReferences(string $sourceId, array $edges, array
454456
}
455457
$this->addCircularReferences($id, $loop, $loopByConstructor);
456458
} elseif (!isset($checkedNodes[$id])) {
457-
$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor());
459+
$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor() && !$edge->isLazy());
458460
} elseif (isset($loops[$id])) {
459461
// we already had detected loops for this edge
460462
// let's check if we have a common ancestor in one of the detected loops
@@ -475,7 +477,7 @@ private function collectCircularReferences(string $sourceId, array $edges, array
475477

476478
// we can now build the loop
477479
$loop = null;
478-
$loopByConstructor = $edge->isReferencedByConstructor();
480+
$loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
479481
foreach ($fillPath as $k => $pathByConstructor) {
480482
if (null !== $loop) {
481483
$loop[] = $k;
@@ -975,7 +977,7 @@ private function addInlineReference(string $id, Definition $definition, string $
975977
return '';
976978
}
977979

978-
$hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]);
980+
$hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]) && !($this->hasProxyDumper && $definition->isLazy());
979981

980982
if ($hasSelfRef && !$forConstructor && !$forConstructor = !$this->circularReferences[$id][$targetId]) {
981983
$code = $this->addInlineService($id, $definition, $definition);
@@ -1018,7 +1020,7 @@ private function addInlineService(string $id, Definition $definition, Definition
10181020

10191021
if ($isSimpleInstance = $isRootInstance = null === $inlineDef) {
10201022
foreach ($this->serviceCalls as $targetId => [$callCount, $behavior, $byConstructor]) {
1021-
if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) {
1023+
if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId] && !($this->hasProxyDumper && $definition->isLazy())) {
10221024
$code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor);
10231025
}
10241026
}

Tests/Fixtures/php/services_almost_circular_private.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,13 @@ protected function getBar6Service()
489489
*/
490490
protected function getDoctrine_ListenerService()
491491
{
492-
return $this->privates['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService()));
492+
$a = ($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService());
493+
494+
if (isset($this->privates['doctrine.listener'])) {
495+
return $this->privates['doctrine.listener'];
496+
}
497+
498+
return $this->privates['doctrine.listener'] = new \stdClass($a);
493499
}
494500

495501
/**

Tests/Fixtures/php/services_almost_circular_public.php

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,16 @@ protected function getDoctrine_EntityListenerResolverService()
283283
*/
284284
protected function getDoctrine_EntityManagerService()
285285
{
286-
$a = new \stdClass();
287-
$a->resolver = ($this->services['doctrine.entity_listener_resolver'] ?? $this->getDoctrine_EntityListenerResolverService());
288-
$a->flag = 'ok';
286+
$a = ($this->services['doctrine.entity_listener_resolver'] ?? $this->getDoctrine_EntityListenerResolverService());
287+
288+
if (isset($this->services['doctrine.entity_manager'])) {
289+
return $this->services['doctrine.entity_manager'];
290+
}
291+
$b = new \stdClass();
292+
$b->resolver = $a;
293+
$b->flag = 'ok';
289294

290-
return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($a);
295+
return $this->services['doctrine.entity_manager'] = \FactoryChecker::create($b);
291296
}
292297

293298
/**
@@ -297,7 +302,13 @@ protected function getDoctrine_EntityManagerService()
297302
*/
298303
protected function getDoctrine_ListenerService()
299304
{
300-
return $this->services['doctrine.listener'] = new \stdClass(($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService()));
305+
$a = ($this->services['doctrine.entity_manager'] ?? $this->getDoctrine_EntityManagerService());
306+
307+
if (isset($this->services['doctrine.listener'])) {
308+
return $this->services['doctrine.listener'];
309+
}
310+
311+
return $this->services['doctrine.listener'] = new \stdClass($a);
301312
}
302313

303314
/**
@@ -493,7 +504,13 @@ protected function getLoggerService()
493504
*/
494505
protected function getMailer_TransportService()
495506
{
496-
return $this->services['mailer.transport'] = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService())->create();
507+
$a = ($this->services['mailer.transport_factory'] ?? $this->getMailer_TransportFactoryService());
508+
509+
if (isset($this->services['mailer.transport'])) {
510+
return $this->services['mailer.transport'];
511+
}
512+
513+
return $this->services['mailer.transport'] = $a->create();
497514
}
498515

499516
/**
@@ -516,7 +533,13 @@ protected function getMailer_TransportFactoryService()
516533
*/
517534
protected function getMailer_TransportFactory_AmazonService()
518535
{
519-
return $this->services['mailer.transport_factory.amazon'] = new \stdClass(($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service()));
536+
$a = ($this->services['monolog.logger_2'] ?? $this->getMonolog_Logger2Service());
537+
538+
if (isset($this->services['mailer.transport_factory.amazon'])) {
539+
return $this->services['mailer.transport_factory.amazon'];
540+
}
541+
542+
return $this->services['mailer.transport_factory.amazon'] = new \stdClass($a);
520543
}
521544

522545
/**

0 commit comments

Comments
 (0)