Merge branch '2.8' into 3.0
* 2.8: [EventDispatcher] check for method to exist [DependencyInjection] Fixed the priority of service decoration on service with parent Make failed autowiring error messages more explicit
This commit is contained in:
commit
2100ecdcc2
@ -105,7 +105,7 @@ class AutowirePass implements CompilerPassInterface
|
||||
$this->populateAvailableTypes();
|
||||
}
|
||||
|
||||
if (isset($this->types[$typeHint->name])) {
|
||||
if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) {
|
||||
$value = new Reference($this->types[$typeHint->name]);
|
||||
} else {
|
||||
try {
|
||||
@ -190,22 +190,26 @@ class AutowirePass implements CompilerPassInterface
|
||||
*/
|
||||
private function set($type, $id)
|
||||
{
|
||||
if (isset($this->definedTypes[$type]) || isset($this->notGuessableTypes[$type])) {
|
||||
if (isset($this->definedTypes[$type])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->types[$type])) {
|
||||
if ($this->types[$type] === $id) {
|
||||
return;
|
||||
}
|
||||
if (!isset($this->types[$type])) {
|
||||
$this->types[$type] = $id;
|
||||
|
||||
unset($this->types[$type]);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->types[$type] === $id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($this->notGuessableTypes[$type])) {
|
||||
$this->notGuessableTypes[$type] = true;
|
||||
|
||||
return;
|
||||
$this->types[$type] = (array) $this->types[$type];
|
||||
}
|
||||
|
||||
$this->types[$type] = $id;
|
||||
$this->types[$type][] = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,8 +224,14 @@ class AutowirePass implements CompilerPassInterface
|
||||
*/
|
||||
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
|
||||
{
|
||||
if (isset($this->notGuessableTypes[$typeHint->name]) || !$typeHint->isInstantiable()) {
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s".', $typeHint->name, $id));
|
||||
if (isset($this->notGuessableTypes[$typeHint->name])) {
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Several services implementing this type have been declared: "%s".', $typeHint->name, $id, implode('", "', $this->types[$typeHint->name])));
|
||||
}
|
||||
|
||||
$noAvailableDefinitionMessage = sprintf('Unable to autowire argument of type "%s" for the service "%s". This type cannot be instantiated automatically and no service implementing this type is declared.', $typeHint->name, $id);
|
||||
|
||||
if (!$typeHint->isInstantiable()) {
|
||||
throw new RuntimeException($noAvailableDefinitionMessage);
|
||||
}
|
||||
|
||||
$argumentId = sprintf('autowired.%s', $typeHint->name);
|
||||
@ -230,7 +240,12 @@ class AutowirePass implements CompilerPassInterface
|
||||
$argumentDefinition->setPublic(false);
|
||||
|
||||
$this->populateAvailableType($argumentId, $argumentDefinition);
|
||||
$this->completeDefinition($argumentId, $argumentDefinition);
|
||||
|
||||
try {
|
||||
$this->completeDefinition($argumentId, $argumentDefinition);
|
||||
} catch (RuntimeException $e) {
|
||||
throw new RuntimeException($noAvailableDefinitionMessage, 0, $e);
|
||||
}
|
||||
|
||||
return new Reference($argumentId);
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
if (null === $decoratedService) {
|
||||
$def->setDecoratedService($decoratedService);
|
||||
} else {
|
||||
$def->setDecoratedService($decoratedService[0], $decoratedService[1]);
|
||||
$def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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".
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". Several services implementing this type have been declared: "c1", "c2".
|
||||
*/
|
||||
public function testTypeCollision()
|
||||
{
|
||||
@ -120,7 +120,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\Foo" for the service "a".
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" for the service "a". Several services implementing this type have been declared: "a1", "a2".
|
||||
*/
|
||||
public function testTypeNotGuessable()
|
||||
{
|
||||
@ -137,7 +137,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\A" for the service "a".
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\A" for the service "a". Several services implementing this type have been declared: "a1", "a2".
|
||||
*/
|
||||
public function testTypeNotGuessableWithSubclass()
|
||||
{
|
||||
@ -207,6 +207,21 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". This type cannot be instantiated automatically and no service implementing this type is declared.
|
||||
*/
|
||||
public function testCreateNonInstanciable()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
|
||||
$aDefinition->setAutowired(true);
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
public function testResolveParameter()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -253,10 +253,12 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||
$container->register('parent', 'stdClass');
|
||||
|
||||
$container->setDefinition('child1', new DefinitionDecorator('parent'))
|
||||
->setDecoratedService('foo', 'foo_inner')
|
||||
->setDecoratedService('foo', 'foo_inner', 5)
|
||||
;
|
||||
|
||||
$this->assertEquals(array('foo', 'foo_inner', 0), $container->getDefinition('child1')->getDecoratedService());
|
||||
$this->process($container);
|
||||
|
||||
$this->assertEquals(array('foo', 'foo_inner', 5), $container->getDefinition('child1')->getDecoratedService());
|
||||
}
|
||||
|
||||
public function testDecoratedServiceCopiesDeprecatedStatusFromParent()
|
||||
|
@ -104,6 +104,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function getListenerPriority($eventName, $listener)
|
||||
{
|
||||
if (!method_exists($this->dispatcher, 'getListenerPriority')) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->dispatcher->getListenerPriority($eventName, $listener);
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,16 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
|
||||
}
|
||||
|
||||
public function testGetListenerPriorityReturnsZeroWhenWrappedMethodDoesNotExist()
|
||||
{
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$traceableEventDispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
|
||||
$traceableEventDispatcher->addListener('foo', function () {}, 123);
|
||||
$listeners = $traceableEventDispatcher->getListeners('foo');
|
||||
|
||||
$this->assertSame(0, $traceableEventDispatcher->getListenerPriority('foo', $listeners[0]));
|
||||
}
|
||||
|
||||
public function testAddRemoveSubscriber()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
|
Reference in New Issue
Block a user