@@ -36,7 +36,7 @@ public function process(ContainerBuilder $container)
3636 try {
3737 parent ::process ($ container );
3838 } finally {
39- // Free memory and remove circular reference to container
39+ // Free memory
4040 $ this ->definedTypes = array ();
4141 $ this ->types = null ;
4242 $ this ->ambiguousServiceTypes = array ();
@@ -90,6 +90,7 @@ protected function processValue($value, $isRoot = false)
9090 }
9191
9292 $ methodCalls = $ this ->autowireMethodCalls ($ reflectionClass , $ methodCalls , $ autowiredMethods );
93+ $ overriddenGetters = $ this ->autowireOverridenGetters ($ value ->getOverriddenGetters (), $ autowiredMethods );
9394
9495 if ($ constructor ) {
9596 list (, $ arguments ) = array_shift ($ methodCalls );
@@ -103,6 +104,10 @@ protected function processValue($value, $isRoot = false)
103104 $ value ->setMethodCalls ($ methodCalls );
104105 }
105106
107+ if ($ overriddenGetters !== $ value ->getOverriddenGetters ()) {
108+ $ value ->setOverriddenGetters ($ overriddenGetters );
109+ }
110+
106111 return parent ::processValue ($ value , $ isRoot );
107112 }
108113
@@ -124,7 +129,7 @@ private function getMethodsToAutowire(\ReflectionClass $reflectionClass, array $
124129 $ regexList [] = '/^ ' .str_replace ('\* ' , '.* ' , preg_quote ($ pattern , '/ ' )).'$/i ' ;
125130 }
126131
127- foreach ($ reflectionClass ->getMethods (\ReflectionMethod::IS_PUBLIC ) as $ reflectionMethod ) {
132+ foreach ($ reflectionClass ->getMethods (\ReflectionMethod::IS_PUBLIC | \ReflectionMethod:: IS_PROTECTED ) as $ reflectionMethod ) {
128133 if ($ reflectionMethod ->isStatic ()) {
129134 continue ;
130135 }
@@ -164,7 +169,7 @@ private function autowireMethodCalls(\ReflectionClass $reflectionClass, array $m
164169 list ($ method , $ arguments ) = $ call ;
165170 $ method = $ parameterBag ->resolveValue ($ method );
166171
167- if (isset ($ autowiredMethods [$ lcMethod = strtolower ($ method )])) {
172+ if (isset ($ autowiredMethods [$ lcMethod = strtolower ($ method )]) && $ autowiredMethods [ $ lcMethod ]-> isPublic () ) {
168173 $ reflectionMethod = $ autowiredMethods [$ lcMethod ];
169174 unset($ autowiredMethods [$ lcMethod ]);
170175 } else {
@@ -177,15 +182,15 @@ private function autowireMethodCalls(\ReflectionClass $reflectionClass, array $m
177182 }
178183 }
179184
180- $ arguments = $ this ->autowireMethod ($ reflectionMethod , $ arguments , true );
185+ $ arguments = $ this ->autowireMethodCall ($ reflectionMethod , $ arguments , true );
181186
182187 if ($ arguments !== $ call [1 ]) {
183188 $ methodCalls [$ i ][1 ] = $ arguments ;
184189 }
185190 }
186191
187192 foreach ($ autowiredMethods as $ reflectionMethod ) {
188- if ($ arguments = $ this ->autowireMethod ($ reflectionMethod , array (), false )) {
193+ if ($ reflectionMethod -> isPublic () && $ arguments = $ this ->autowireMethodCall ($ reflectionMethod , array (), false )) {
189194 $ methodCalls [] = array ($ reflectionMethod ->name , $ arguments );
190195 }
191196 }
@@ -194,7 +199,7 @@ private function autowireMethodCalls(\ReflectionClass $reflectionClass, array $m
194199 }
195200
196201 /**
197- * Autowires the constructor or a setter .
202+ * Autowires the constructor or a method .
198203 *
199204 * @param \ReflectionMethod $reflectionMethod
200205 * @param array $arguments
@@ -204,7 +209,7 @@ private function autowireMethodCalls(\ReflectionClass $reflectionClass, array $m
204209 *
205210 * @throws RuntimeException
206211 */
207- private function autowireMethod (\ReflectionMethod $ reflectionMethod , array $ arguments , $ mustAutowire )
212+ private function autowireMethodCall (\ReflectionMethod $ reflectionMethod , array $ arguments , $ mustAutowire )
208213 {
209214 $ didAutowire = false ; // Whether any arguments have been autowired or not
210215 foreach ($ reflectionMethod ->getParameters () as $ index => $ parameter ) {
@@ -298,6 +303,55 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
298303 return $ arguments ;
299304 }
300305
306+ /**
307+ * Autowires getters.
308+ *
309+ * @param array $overridenGetters
310+ * @param array $autowiredMethods
311+ *
312+ * @return array
313+ */
314+ private function autowireOverridenGetters (array $ overridenGetters , array $ autowiredMethods )
315+ {
316+ foreach ($ autowiredMethods as $ reflectionMethod ) {
317+ if (isset ($ overridenGetters [strtolower ($ reflectionMethod ->name )])
318+ || !method_exists ($ reflectionMethod , 'getReturnType ' )
319+ || 0 !== $ reflectionMethod ->getNumberOfParameters ()
320+ || $ reflectionMethod ->isFinal ()
321+ || $ reflectionMethod ->returnsReference ()
322+ || !$ returnType = $ reflectionMethod ->getReturnType ()
323+ ) {
324+ continue ;
325+ }
326+ $ typeName = $ returnType instanceof \ReflectionNamedType ? $ returnType ->getName () : $ returnType ->__toString ();
327+
328+ if ($ this ->container ->has ($ typeName ) && !$ this ->container ->findDefinition ($ typeName )->isAbstract ()) {
329+ $ overridenGetters [$ reflectionMethod ->name ] = new Reference ($ typeName );
330+ continue ;
331+ }
332+
333+ if (null === $ this ->types ) {
334+ $ this ->populateAvailableTypes ();
335+ }
336+
337+ if (isset ($ this ->types [$ typeName ])) {
338+ $ value = new Reference ($ this ->types [$ typeName ]);
339+ } elseif ($ returnType = $ this ->container ->getReflectionClass ($ typeName , true )) {
340+ try {
341+ $ value = $ this ->createAutowiredDefinition ($ returnType );
342+ } catch (RuntimeException $ e ) {
343+ continue ;
344+ }
345+ } else {
346+ continue ;
347+ }
348+
349+ $ overridenGetters [$ reflectionMethod ->name ] = $ value ;
350+ }
351+
352+ return $ overridenGetters ;
353+ }
354+
301355 /**
302356 * Populates the list of available types.
303357 */
0 commit comments