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

Skip to content

Commit 0be8bf7

Browse files
[DI] fine tune dumped factories
1 parent 965e484 commit 0be8bf7

File tree

5 files changed

+36
-24
lines changed

5 files changed

+36
-24
lines changed

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\Variable;
1818
use Symfony\Component\DependencyInjection\Definition;
1919
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
20+
use Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Container;
2223
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -68,6 +69,7 @@ class PhpDumper extends Dumper
6869
private $inlineRequires;
6970
private $inlinedRequires = array();
7071
private $circularReferences = array();
72+
private $singleUsePrivateIds = array();
7173

7274
/**
7375
* @var ProxyDumper
@@ -141,10 +143,14 @@ public function dump(array $options = array())
141143

142144
(new AnalyzeServiceReferencesPass())->process($this->container);
143145
$this->circularReferences = array();
146+
$this->singleUsePrivateIds = array();
144147
$checkedNodes = array();
145148
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
146149
$currentPath = array($id => $id);
147150
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
151+
if ($this->isSingleUsePrivateNode($node)) {
152+
$this->singleUsePrivateIds[$id] = $id;
153+
}
148154
}
149155
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
150156

@@ -526,7 +532,7 @@ private function addServiceInstance(string $id, Definition $definition, string $
526532
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
527533
$instantiation = '';
528534

529-
if (!$isProxyCandidate && $definition->isShared()) {
535+
if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
530536
$instantiation = sprintf('$this->%s[\'%s\'] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $id, $isSimpleInstance ? '' : '$instance');
531537
} elseif (!$isSimpleInstance) {
532538
$instantiation = '$instance';
@@ -819,7 +825,7 @@ private function generateServiceFiles()
819825
$definitions = $this->container->getDefinitions();
820826
ksort($definitions);
821827
foreach ($definitions as $id => $definition) {
822-
if (!$definition->isSynthetic() && !$this->isHotPath($definition)) {
828+
if (!$definition->isSynthetic() && !$this->isHotPath($definition) && ($definition->isPublic() || !$this->isTrivialInstance($definition))) {
823829
$code = $this->addService($id, $definition, $file);
824830

825831
if (!$definition->isShared()) {
@@ -1662,7 +1668,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
16621668
$code = 'null';
16631669
} elseif ($this->isTrivialInstance($definition)) {
16641670
$code = substr($this->addNewInstance($definition, '', '', $id), 8, -2);
1665-
if ($definition->isShared()) {
1671+
if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
16661672
$code = sprintf('$this->%s[\'%s\'] = %s', $definition->isPublic() ? 'services' : 'privates', $id, $code);
16671673
}
16681674
} elseif ($this->asFiles && !$this->isHotPath($definition)) {
@@ -1674,7 +1680,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
16741680
} else {
16751681
$code = sprintf('$this->%s()', $this->generateMethodName($id));
16761682
}
1677-
if ($definition->isShared()) {
1683+
if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
16781684
$code = sprintf('($this->%s[\'%s\'] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $id, $code);
16791685
}
16801686

@@ -1798,6 +1804,22 @@ private function isHotPath(Definition $definition)
17981804
return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated();
17991805
}
18001806

1807+
private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node)
1808+
{
1809+
if ($node->getValue()->isPublic()) {
1810+
return false;
1811+
}
1812+
$ids = array();
1813+
foreach ($node->getInEdges() as $edge) {
1814+
if ($edge->isLazy() || !$edge->getSourceNode()->getValue()->isShared()) {
1815+
return false;
1816+
}
1817+
$ids[$edge->getSourceNode()->getId()] = true;
1818+
}
1819+
1820+
return 1 === \count($ids);
1821+
}
1822+
18011823
private function export($value)
18021824
{
18031825
if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) {

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
155155
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
156156
// Returns the public 'factory_service_simple' shared service.
157157

158-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->load('getFactorySimpleService.php'))->getInstance();
158+
return $this->services['factory_service_simple'] = $this->load('getFactorySimpleService.php')->getInstance();
159159

160160
[Container%s/getFactorySimpleService.php] => <?php
161161

@@ -167,7 +167,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
167167

168168
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
169169

170-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
170+
return new \SimpleFactoryClass('foo');
171171

172172
[Container%s/getFooService.php] => <?php
173173

@@ -326,7 +326,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
326326
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
327327
// Returns the public 'runtime_error' shared service.
328328

329-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->load('getErroredDefinitionService.php')));
329+
return $this->services['runtime_error'] = new \stdClass($this->load('getErroredDefinitionService.php'));
330330

331331
[Container%s/getServiceFromStaticMethodService.php] => <?php
332332

@@ -351,16 +351,6 @@ return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(fun
351351
yield 1 => ($this->privates['tagged_iterator_foo'] ?? $this->privates['tagged_iterator_foo'] = new \Bar());
352352
}, 2));
353353

354-
[Container%s/getTaggedIteratorFooService.php] => <?php
355-
356-
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
357-
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
358-
359-
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
360-
// Returns the private 'tagged_iterator_foo' shared service.
361-
362-
return $this->privates['tagged_iterator_foo'] = new \Bar();
363-
364354
[Container%s/ProjectServiceContainer.php] => <?php
365355

366356
namespace Container%s;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ protected function getFactoryServiceService()
243243
*/
244244
protected function getFactoryServiceSimpleService()
245245
{
246-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->getFactorySimpleService())->getInstance();
246+
return $this->services['factory_service_simple'] = $this->getFactorySimpleService()->getInstance();
247247
}
248248

249249
/**
@@ -381,7 +381,7 @@ protected function getNewFactoryServiceService()
381381
*/
382382
protected function getRuntimeErrorService()
383383
{
384-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->getErroredDefinitionService()));
384+
return $this->services['runtime_error'] = new \stdClass($this->getErroredDefinitionService());
385385
}
386386

387387
/**
@@ -428,7 +428,7 @@ protected function getFactorySimpleService()
428428
{
429429
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
430430

431-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
431+
return new \SimpleFactoryClass('foo');
432432
}
433433

434434
public function getParameter($name)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ protected function getFactoryServiceService()
243243
*/
244244
protected function getFactoryServiceSimpleService()
245245
{
246-
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->getFactorySimpleService())->getInstance();
246+
return $this->services['factory_service_simple'] = $this->getFactorySimpleService()->getInstance();
247247
}
248248

249249
/**
@@ -381,7 +381,7 @@ protected function getNewFactoryServiceService()
381381
*/
382382
protected function getRuntimeErrorService()
383383
{
384-
return $this->services['runtime_error'] = new \stdClass(($this->privates['errored_definition'] ?? $this->getErroredDefinitionService()));
384+
return $this->services['runtime_error'] = new \stdClass($this->getErroredDefinitionService());
385385
}
386386

387387
/**
@@ -428,7 +428,7 @@ protected function getFactorySimpleService()
428428
{
429429
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
430430

431-
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
431+
return new \SimpleFactoryClass('foo');
432432
}
433433

434434
public function getParameter($name)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ public function getRemovedIds()
6767
*/
6868
protected function getPublicFooService()
6969
{
70-
return $this->services['public_foo'] = new \stdClass(($this->privates['private_foo'] ?? $this->privates['private_foo'] = new \stdClass()));
70+
return $this->services['public_foo'] = new \stdClass(new \stdClass());
7171
}
7272
}

0 commit comments

Comments
 (0)