17
17
use Symfony \Component \DependencyInjection \Variable ;
18
18
use Symfony \Component \DependencyInjection \Definition ;
19
19
use Symfony \Component \DependencyInjection \Compiler \AnalyzeServiceReferencesPass ;
20
+ use Symfony \Component \DependencyInjection \Compiler \ServiceReferenceGraphNode ;
20
21
use Symfony \Component \DependencyInjection \ContainerBuilder ;
21
22
use Symfony \Component \DependencyInjection \Container ;
22
23
use Symfony \Component \DependencyInjection \ContainerInterface ;
@@ -68,6 +69,7 @@ class PhpDumper extends Dumper
68
69
private $ inlineRequires ;
69
70
private $ inlinedRequires = array ();
70
71
private $ circularReferences = array ();
72
+ private $ singleUsePrivateIds = array ();
71
73
72
74
/**
73
75
* @var ProxyDumper
@@ -141,10 +143,14 @@ public function dump(array $options = array())
141
143
142
144
(new AnalyzeServiceReferencesPass ())->process ($ this ->container );
143
145
$ this ->circularReferences = array ();
146
+ $ this ->singleUsePrivateIds = array ();
144
147
$ checkedNodes = array ();
145
148
foreach ($ this ->container ->getCompiler ()->getServiceReferenceGraph ()->getNodes () as $ id => $ node ) {
146
149
$ currentPath = array ($ id => $ id );
147
150
$ this ->analyzeCircularReferences ($ node ->getOutEdges (), $ checkedNodes , $ currentPath );
151
+ if ($ this ->isSingleUsePrivateNode ($ node )) {
152
+ $ this ->singleUsePrivateIds [$ id ] = $ id ;
153
+ }
148
154
}
149
155
$ this ->container ->getCompiler ()->getServiceReferenceGraph ()->clear ();
150
156
@@ -526,7 +532,7 @@ private function addServiceInstance(string $id, Definition $definition, string $
526
532
$ isProxyCandidate = $ this ->getProxyDumper ()->isProxyCandidate ($ definition );
527
533
$ instantiation = '' ;
528
534
529
- if (!$ isProxyCandidate && $ definition ->isShared ()) {
535
+ if (!$ isProxyCandidate && $ definition ->isShared () && ! isset ( $ this -> singleUsePrivateIds [ $ id ]) ) {
530
536
$ instantiation = sprintf ('$this->%s[ \'%s \'] = %s ' , $ this ->container ->getDefinition ($ id )->isPublic () ? 'services ' : 'privates ' , $ id , $ isSimpleInstance ? '' : '$instance ' );
531
537
} elseif (!$ isSimpleInstance ) {
532
538
$ instantiation = '$instance ' ;
@@ -819,7 +825,7 @@ private function generateServiceFiles()
819
825
$ definitions = $ this ->container ->getDefinitions ();
820
826
ksort ($ definitions );
821
827
foreach ($ definitions as $ id => $ definition ) {
822
- if (!$ definition ->isSynthetic () && !$ this ->isHotPath ($ definition )) {
828
+ if (!$ definition ->isSynthetic () && !$ this ->isHotPath ($ definition ) && ( $ definition -> isPublic () || ! $ this -> isTrivialInstance ( $ definition )) ) {
823
829
$ code = $ this ->addService ($ id , $ definition , $ file );
824
830
825
831
if (!$ definition ->isShared ()) {
@@ -1662,7 +1668,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
1662
1668
$ code = 'null ' ;
1663
1669
} elseif ($ this ->isTrivialInstance ($ definition )) {
1664
1670
$ code = substr ($ this ->addNewInstance ($ definition , '' , '' , $ id ), 8 , -2 );
1665
- if ($ definition ->isShared ()) {
1671
+ if ($ definition ->isShared () && ! isset ( $ this -> singleUsePrivateIds [ $ id ]) ) {
1666
1672
$ code = sprintf ('$this->%s[ \'%s \'] = %s ' , $ definition ->isPublic () ? 'services ' : 'privates ' , $ id , $ code );
1667
1673
}
1668
1674
} elseif ($ this ->asFiles && !$ this ->isHotPath ($ definition )) {
@@ -1674,7 +1680,7 @@ private function getServiceCall(string $id, Reference $reference = null): string
1674
1680
} else {
1675
1681
$ code = sprintf ('$this->%s() ' , $ this ->generateMethodName ($ id ));
1676
1682
}
1677
- if ($ definition ->isShared ()) {
1683
+ if ($ definition ->isShared () && ! isset ( $ this -> singleUsePrivateIds [ $ id ]) ) {
1678
1684
$ code = sprintf ('($this->%s[ \'%s \'] ?? %s) ' , $ definition ->isPublic () ? 'services ' : 'privates ' , $ id , $ code );
1679
1685
}
1680
1686
@@ -1798,6 +1804,22 @@ private function isHotPath(Definition $definition)
1798
1804
return $ this ->hotPathTag && $ definition ->hasTag ($ this ->hotPathTag ) && !$ definition ->isDeprecated ();
1799
1805
}
1800
1806
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
+
1801
1823
private function export ($ value )
1802
1824
{
1803
1825
if (null !== $ this ->targetDirRegex && is_string ($ value ) && preg_match ($ this ->targetDirRegex , $ value , $ matches , PREG_OFFSET_CAPTURE )) {
0 commit comments