bug #21602 [DI] Always consider abstract getters as autowiring candidates (nicolas-grekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Always consider abstract getters as autowiring candidates

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes (a missing part of getter autowiring really)
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

When a definition is set to be autowired with no method explicitly configured, we already wire the constructor.
We should also autowire abstract getters - with the same reasoning that makes us autowire the constructor: without concrete getters, the class is unusable. This just makes it usable again.

Commits
-------

8f246bde1d [DI] Always consider abstract getters as autowiring candidates
This commit is contained in:
Fabien Potencier 2017-02-27 14:16:56 -08:00
commit e37bff942a
3 changed files with 47 additions and 1 deletions

View File

@ -176,6 +176,10 @@ class AutowirePass extends AbstractRecursivePass
continue 2;
}
}
if ($reflectionMethod->isAbstract() && !$reflectionMethod->getNumberOfParameters()) {
$methodsToAutowire[strtolower($reflectionMethod->name)] = $reflectionMethod;
}
}
if ($notFound = array_diff($autowiredMethods, $found)) {
@ -501,7 +505,7 @@ class AutowirePass extends AbstractRecursivePass
$this->populateAvailableType($argumentId, $argumentDefinition);
try {
$this->processValue($argumentDefinition, true);
$this->processValue($argumentDefinition);
$this->currentId = $currentId;
} catch (RuntimeException $e) {
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';

View File

@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\AbstractGetterOverriding;
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;
use Symfony\Component\DependencyInjection\Tests\Fixtures\GetterOverriding;
@ -519,6 +520,27 @@ class AutowirePassTest extends TestCase
);
}
/**
* @requires PHP 7.0
*/
public function testAbstractGetterOverriding()
{
$container = new ContainerBuilder();
$container
->register('getter_overriding', AbstractGetterOverriding::class)
->setAutowired(true)
;
$pass = new AutowirePass();
$pass->process($container);
$overridenGetters = $container->getDefinition('getter_overriding')->getOverriddenGetters();
$this->assertEquals(array(
'abstractgetfoo' => new Reference('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Foo'),
), $overridenGetters);
}
/**
* @requires PHP 7.1
*/

View File

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
abstract class AbstractGetterOverriding
{
abstract public function abstractGetFoo(): Foo;
abstract public function abstractDoFoo($arg = null): Foo;
}