12
12
namespace Symfony \Component \DependencyInjection \Compiler ;
13
13
14
14
use Symfony \Component \DependencyInjection \Argument \ArgumentInterface ;
15
+ use Symfony \Component \DependencyInjection \ContainerBuilder ;
15
16
use Symfony \Component \DependencyInjection \Definition ;
16
17
use Symfony \Component \DependencyInjection \Exception \ServiceCircularReferenceException ;
17
18
use Symfony \Component \DependencyInjection \Reference ;
23
24
*/
24
25
class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface
25
26
{
27
+ private $ analyzingPass ;
28
+ private $ repeatedPass ;
26
29
private $ cloningIds = array ();
30
+ private $ connectedIds = array ();
31
+ private $ notInlinedIds = array ();
32
+ private $ inlinedIds = array ();
33
+ private $ graph ;
34
+
35
+ public function __construct (AnalyzeServiceReferencesPass $ analyzingPass = null )
36
+ {
37
+ $ this ->analyzingPass = $ analyzingPass ;
38
+ }
27
39
28
40
/**
29
41
* {@inheritdoc}
30
42
*/
31
43
public function setRepeatedPass (RepeatedPass $ repeatedPass )
32
44
{
33
- // no-op for BC
45
+ @trigger_error (sprintf ('The "%s" method is deprecated since Symfony 4.1. ' , __METHOD__ ), E_USER_DEPRECATED );
46
+ $ this ->repeatedPass = $ repeatedPass ;
47
+ }
48
+
49
+ public function process (ContainerBuilder $ container )
50
+ {
51
+ $ this ->container = $ container ;
52
+ if ($ this ->analyzingPass ) {
53
+ $ analyzedContainer = new ContainerBuilder ();
54
+ $ analyzedContainer ->setAliases ($ container ->getAliases ());
55
+ $ analyzedContainer ->setDefinitions ($ container ->getDefinitions ());
56
+ } else {
57
+ $ analyzedContainer = $ container ;
58
+ }
59
+ try {
60
+ $ this ->connectedIds = $ this ->notInlinedIds = $ container ->getDefinitions ();
61
+ do {
62
+ if ($ this ->analyzingPass ) {
63
+ $ analyzedContainer ->setDefinitions (array_intersect_key ($ analyzedContainer ->getDefinitions (), $ this ->connectedIds ));
64
+ $ this ->analyzingPass ->process ($ analyzedContainer );
65
+ }
66
+ $ this ->graph = $ analyzedContainer ->getCompiler ()->getServiceReferenceGraph ();
67
+ $ notInlinedIds = $ this ->notInlinedIds ;
68
+ $ this ->connectedIds = $ this ->notInlinedIds = $ this ->inlinedIds = array ();
69
+
70
+ foreach ($ analyzedContainer ->getDefinitions () as $ id => $ definition ) {
71
+ if (!$ this ->graph ->hasNode ($ id )) {
72
+ continue ;
73
+ }
74
+ foreach ($ this ->graph ->getNode ($ id )->getOutEdges () as $ edge ) {
75
+ if (isset ($ notInlinedIds [$ edge ->getSourceNode ()->getId ()])) {
76
+ $ this ->currentId = $ id ;
77
+ $ this ->processValue ($ definition , true );
78
+ break ;
79
+ }
80
+ }
81
+ }
82
+
83
+ foreach ($ this ->inlinedIds as $ id => $ isPublic ) {
84
+ if (!$ isPublic ) {
85
+ $ container ->removeDefinition ($ id );
86
+ $ analyzedContainer ->removeDefinition ($ id );
87
+ }
88
+ }
89
+ } while ($ this ->inlinedIds && $ this ->analyzingPass );
90
+
91
+ if ($ this ->inlinedIds && $ this ->repeatedPass ) {
92
+ $ this ->repeatedPass ->setRepeat ();
93
+ }
94
+ } finally {
95
+ $ this ->container = null ;
96
+ $ this ->connectedIds = $ this ->notInlinedIds = $ this ->inlinedIds = array ();
97
+ $ this ->graph = null ;
98
+ }
34
99
}
35
100
36
101
/**
@@ -50,17 +115,21 @@ protected function processValue($value, $isRoot = false)
50
115
$ value = clone $ value ;
51
116
}
52
117
53
- if (!$ value instanceof Reference || ! $ this -> container -> hasDefinition ( $ id = ( string ) $ value ) ) {
118
+ if (!$ value instanceof Reference) {
54
119
return parent ::processValue ($ value , $ isRoot );
120
+ } elseif (!$ this ->container ->hasDefinition ($ id = (string ) $ value )) {
121
+ return $ value ;
55
122
}
56
123
57
124
$ definition = $ this ->container ->getDefinition ($ id );
58
125
59
- if (!$ this ->isInlineableDefinition ($ id , $ definition, $ this -> container -> getCompiler ()-> getServiceReferenceGraph () )) {
126
+ if (!$ this ->isInlineableDefinition ($ id , $ definition )) {
60
127
return $ value ;
61
128
}
62
129
63
130
$ this ->container ->log ($ this , sprintf ('Inlined service "%s" to "%s". ' , $ id , $ this ->currentId ));
131
+ $ this ->inlinedIds [$ id ] = $ definition ->isPublic ();
132
+ $ this ->notInlinedIds [$ this ->currentId ] = true ;
64
133
65
134
if ($ definition ->isShared ()) {
66
135
return $ definition ;
@@ -86,7 +155,7 @@ protected function processValue($value, $isRoot = false)
86
155
*
87
156
* @return bool If the definition is inlineable
88
157
*/
89
- private function isInlineableDefinition ($ id , Definition $ definition, ServiceReferenceGraph $ graph )
158
+ private function isInlineableDefinition ($ id , Definition $ definition )
90
159
{
91
160
if ($ definition ->getErrors () || $ definition ->isDeprecated () || $ definition ->isLazy () || $ definition ->isSynthetic ()) {
92
161
return false ;
@@ -100,30 +169,37 @@ private function isInlineableDefinition($id, Definition $definition, ServiceRefe
100
169
return false ;
101
170
}
102
171
103
- if (!$ graph ->hasNode ($ id )) {
172
+ if (!$ this -> graph ->hasNode ($ id )) {
104
173
return true ;
105
174
}
106
175
107
176
if ($ this ->currentId == $ id ) {
108
177
return false ;
109
178
}
179
+ $ this ->connectedIds [$ id ] = true ;
110
180
111
- $ ids = array ();
112
- foreach ($ graph ->getNode ($ id )->getInEdges () as $ edge ) {
181
+ $ srcIds = array ();
182
+ $ srcIdsCount = 0 ;
183
+ foreach ($ this ->graph ->getNode ($ id )->getInEdges () as $ edge ) {
184
+ $ srcId = $ edge ->getSourceNode ()->getId ();
185
+ $ this ->connectedIds [$ srcId ] = true ;
113
186
if ($ edge ->isWeak ()) {
114
187
return false ;
115
188
}
116
- $ ids [] = $ edge ->getSourceNode ()->getId ();
189
+ $ srcIds [$ srcId ] = true ;
190
+ ++$ srcIdsCount ;
117
191
}
118
192
119
- if (count (array_unique ($ ids )) > 1 ) {
193
+ if (1 !== \count ($ srcIds )) {
194
+ $ this ->notInlinedIds [$ id ] = true ;
195
+
120
196
return false ;
121
197
}
122
198
123
- if (count ( $ ids ) > 1 && is_array ($ factory = $ definition ->getFactory ()) && ($ factory [0 ] instanceof Reference || $ factory [0 ] instanceof Definition)) {
199
+ if ($ srcIdsCount > 1 && is_array ($ factory = $ definition ->getFactory ()) && ($ factory [0 ] instanceof Reference || $ factory [0 ] instanceof Definition)) {
124
200
return false ;
125
201
}
126
202
127
- return ! $ ids || $ this ->container ->getDefinition ($ ids [ 0 ] )->isShared ();
203
+ return $ this ->container ->getDefinition ($ srcId )->isShared ();
128
204
}
129
205
}
0 commit comments