bug #18039 Fixing autowiring collision failure (weaverryan)
This PR was merged into the 3.1-dev branch.
Discussion
----------
Fixing autowiring collision failure
| Q | A
| ------------- | ---
| Branch | master
| Bug fix? | yes (bug introduced in master)
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | none
| License | MIT
| Doc PR | n/a
In #17877, I introduced a bug: https://github.com/symfony/symfony/pull/17877/files#diff-62df969ae028c559d33ffd256de1ac49L200.
Namely, if some class cannot be autowired because there is an *odd* number of matching services, then it *would* autowire the last service found, instead of throwing an exception. The tests only tested even numbers, which is how it was missed. This fixes that.
Thanks!
Commits
-------
2aea337
Fixing a bug where an odd number of type collisions would incorrectly autowire (instead of an error)
This commit is contained in:
commit
681a3494d5
@ -181,6 +181,13 @@ class AutowirePass implements CompilerPassInterface
|
||||
return;
|
||||
}
|
||||
|
||||
// is this already a type/class that is known to match multiple services?
|
||||
if (isset($this->ambiguousServiceTypes[$type])) {
|
||||
$this->addServiceToAmbiguousType($id, $type);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check to make sure the type doesn't match multiple services
|
||||
if (isset($this->types[$type])) {
|
||||
if ($this->types[$type] === $id) {
|
||||
@ -188,12 +195,7 @@ class AutowirePass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
// keep an array of all services matching this type
|
||||
if (!isset($this->ambiguousServiceTypes[$type])) {
|
||||
$this->ambiguousServiceTypes[$type] = array(
|
||||
$this->types[$type],
|
||||
);
|
||||
}
|
||||
$this->ambiguousServiceTypes[$type][] = $id;
|
||||
$this->addServiceToAmbiguousType($id, $type);
|
||||
|
||||
unset($this->types[$type]);
|
||||
|
||||
@ -265,4 +267,15 @@ class AutowirePass implements CompilerPassInterface
|
||||
// return null
|
||||
}
|
||||
}
|
||||
|
||||
private function addServiceToAmbiguousType($id, $type)
|
||||
{
|
||||
// keep an array of all services matching this type
|
||||
if (!isset($this->ambiguousServiceTypes[$type])) {
|
||||
$this->ambiguousServiceTypes[$type] = array(
|
||||
$this->types[$type],
|
||||
);
|
||||
}
|
||||
$this->ambiguousServiceTypes[$type][] = $id;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (c1, c2).
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Multiple services exist for this interface (c1, c2, c3).
|
||||
*/
|
||||
public function testTypeCollision()
|
||||
{
|
||||
@ -111,6 +111,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$container->register('c1', __NAMESPACE__.'\CollisionA');
|
||||
$container->register('c2', __NAMESPACE__.'\CollisionB');
|
||||
$container->register('c3', __NAMESPACE__.'\CollisionB');
|
||||
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
|
||||
$aDefinition->setAutowired(true);
|
||||
|
||||
|
Reference in New Issue
Block a user