bug #26595 [DI] Do not suggest writing an implementation when multiple exist (chalasr)

This PR was merged into the 3.4 branch.

Discussion
----------

[DI] Do not suggest writing an implementation when multiple exist

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Before:

> Cannot autowire service "App\Decorator2": argument "$inner" of method "__construct()" references interface "App\SomeInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "App\Decorator1", "App\Decorator2", "App\Original". Did you create a class that implements this interface?

After:

> Cannot autowire service "App\Decorator2": argument "$inner" of method "__construct()" references interface "App\SomeInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "App\Decorator1", "App\Decorator2", "App\Original".

Commits
-------

1ffdb50 [DI] Do not suggest writing an implementation when multiple exist
This commit is contained in:
Nicolas Grekas 2018-03-29 15:00:03 +02:00
commit 99df7cbafb
2 changed files with 12 additions and 7 deletions

View File

@ -462,10 +462,11 @@ class AutowirePass extends AbstractRecursivePass
$message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
} else {
$alternatives = $this->createTypeAlternatives($reference);
$message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $this->createTypeAlternatives($reference));
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);
if ($r->isInterface()) {
if ($r->isInterface() && !$alternatives) {
$message .= ' Did you create a class that implements this interface?';
}
}

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
@ -684,10 +685,6 @@ class AutowirePassTest extends TestCase
$this->assertTrue($container->hasDefinition('bar'));
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
* @expectedExceptionMessage Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2".
*/
public function testSetterInjectionCollisionThrowsException()
{
$container = new ContainerBuilder();
@ -700,7 +697,14 @@ class AutowirePassTest extends TestCase
(new AutowireRequiredMethodsPass())->process($container);
$pass = new AutowirePass();
$pass->process($container);
try {
$pass->process($container);
} catch (AutowiringFailedException $e) {
}
$this->assertNotNull($e);
$this->assertSame('Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2".', $e->getMessage());
}
/**