Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc48c36b

Browse files
dunglasnicolas-grekas
authored andcommitted
[DI] Add support for getter autowiring
1 parent03b7cf7 commitc48c36b

File tree

5 files changed

+160
-9
lines changed

5 files changed

+160
-9
lines changed

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* deprecated`ContainerBuilder::getClassResource()`, use`ContainerBuilder::getReflectionClass()` or`ContainerBuilder::addObjectResource()` instead
99
* added`ContainerBuilder::fileExists()` for checking and tracking file or directory existence
1010
* deprecated autowiring-types, use aliases instead
11+
*[EXPERIMENTAL] added support for getter autowiring
1112
*[EXPERIMENTAL] added support for getter-injection
1213
* added support for omitting the factory class name in a service definition if the definition class is set
1314
* deprecated case insensitivity of service identifiers

‎src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php‎

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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
returnparent::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 ($autowiredMethodsas$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 asetter.
202+
* Autowires the constructor or amethod.
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-
privatefunctionautowireMethod(\ReflectionMethod$reflectionMethod,array$arguments,$mustAutowire)
212+
privatefunctionautowireMethodCall(\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+
privatefunctionautowireOverridenGetters(array$overridenGetters,array$autowiredMethods)
315+
{
316+
foreach ($autowiredMethodsas$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 =$returnTypeinstanceof \ReflectionNamedType ?$returnType->getName() :$returnType->__toString();
327+
328+
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
329+
$overridenGetters[$reflectionMethod->name] =newReference($typeName);
330+
continue;
331+
}
332+
333+
if (null ===$this->types) {
334+
$this->populateAvailableTypes();
335+
}
336+
337+
if (isset($this->types[$typeName])) {
338+
$value =newReference($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
*/

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
useSymfony\Component\DependencyInjection\ContainerBuilder;
1616
useSymfony\Component\DependencyInjection\Reference;
1717
useSymfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;
18+
useSymfony\Component\DependencyInjection\Tests\Fixtures\GetterOverriding;
1819

1920
/**
2021
* @author Kévin Dunglas <dunglas@gmail.com>
@@ -516,6 +517,31 @@ public function testExplicitMethodInjection()
516517
);
517518
}
518519

520+
/**
521+
* @requires PHP 7.1
522+
*/
523+
publicfunctiontestGetterOverriding()
524+
{
525+
$container =newContainerBuilder();
526+
$container->register('b', B::class);
527+
528+
$container
529+
->register('getter_overriding', GetterOverriding::class)
530+
->setOverriddenGetter('getExplicitlyDefined',newReference('b'))
531+
->setAutowiredMethods(array('get*'))
532+
;
533+
534+
$pass =newAutowirePass();
535+
$pass->process($container);
536+
537+
$overridenGetters =$container->getDefinition('getter_overriding')->getOverriddenGetters();
538+
$this->assertEquals(array(
539+
'getexplicitlydefined' =>newReference('b'),
540+
'getfoo' =>newReference('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Foo'),
541+
'getbar' =>newReference('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Bar'),
542+
),$overridenGetters);
543+
}
544+
519545
/**
520546
* @dataProvider getCreateResourceTests
521547
* @group legacy
@@ -854,6 +880,11 @@ public function notASetter(A $a)
854880
{
855881
// should be called only when explicitly specified
856882
}
883+
884+
protectedfunctionsetProtectedMethod(A$a)
885+
{
886+
// should not be called
887+
}
857888
}
858889

859890
class SetterInjectionCollision

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ public function testDumpOverridenGettersWithConstructor()
354354

355355
$dump =$dumper->dump(array('class' =>'Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor'));
356356
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dump_overriden_getters_with_constructor.php',$dump);
357-
$resources =array_map('strval',$container->getResources());
358-
$this->assertContains(realpath(self::$fixturesPath.'/containers/container_dump_overriden_getters_with_constructor.php'),$resources);
357+
$res =$container->getResources();
358+
$this->assertSame('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo', (string)array_pop($res));
359359

360360
$baz =$container->get('baz');
361361
$r =new \ReflectionMethod($baz,'getBaz');
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\DependencyInjection\Tests\Fixtures;
13+
14+
useSymfony\Component\DependencyInjection\Tests\Compiler\A;
15+
useSymfony\Component\DependencyInjection\Tests\Compiler\B;
16+
useSymfony\Component\DependencyInjection\Tests\Compiler\Bar;
17+
useSymfony\Component\DependencyInjection\Tests\Compiler\Foo;
18+
19+
/**
20+
* To test getter autowiring with PHP >= 7.1.
21+
*
22+
* @author Kévin Dunglas <dunglas@gmail.com>
23+
*/
24+
class GetterOverriding
25+
{
26+
publicfunctiongetFoo(): ?Foo
27+
{
28+
// should be called
29+
}
30+
31+
protectedfunctiongetBar():Bar
32+
{
33+
// should be called
34+
}
35+
36+
publicfunctiongetNoTypeHint()
37+
{
38+
// should not be called
39+
}
40+
41+
publicfunctiongetUnknown():NotExist
42+
{
43+
// should not be called
44+
}
45+
46+
publicfunctiongetExplicitlyDefined():B
47+
{
48+
// should be called but not autowired
49+
}
50+
51+
publicfunctiongetScalar():string
52+
{
53+
// should not be called
54+
}
55+
56+
finalpublicfunctiongetFinal():A
57+
{
58+
// should not be called
59+
}
60+
61+
publicfunction &getReference():A
62+
{
63+
// should not be called
64+
}
65+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp