From 146f07471e8876da6e92c958897a5e798954e219 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 3 Apr 2017 16:43:13 +0200 Subject: [PATCH] [DI] Reduce complexity of autowiring --- .../Compiler/AutowirePass.php | 10 +-------- .../Tests/Compiler/AutowirePassTest.php | 21 +++++++++---------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index d35d38569cf45..5443c6e1deb55 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -230,13 +230,8 @@ private function autowireCalls(\ReflectionClass $reflectionClass, array $methodC */ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $arguments) { - $isConstructor = $reflectionMethod->isConstructor(); $class = $reflectionMethod->class; $method = $reflectionMethod->name; - - if (!$isConstructor && !$arguments && !$reflectionMethod->getNumberOfRequiredParameters()) { - throw new RuntimeException(sprintf('Cannot autowire service "%s": method %s() has only optional arguments, thus must be wired explicitly.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); - } $parameters = $reflectionMethod->getParameters(); if (method_exists('ReflectionMethod', 'isVariadic') && $reflectionMethod->isVariadic()) { array_pop($parameters); @@ -246,9 +241,6 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) { continue; } - if (!$isConstructor && $parameter->isOptional() && !array_key_exists($index, $arguments)) { - break; - } $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true); @@ -258,7 +250,7 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu } // no default value? Then fail - if (!$parameter->isOptional()) { + if (!$parameter->isDefaultValueAvailable()) { throw new RuntimeException(sprintf('Cannot autowire service "%s": argument $%s of method %s() must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 6dbc7c87e59c2..ae88a63df653b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -386,21 +386,19 @@ public function testScalarArgsCannotBeAutowired() $container->getDefinition('arg_no_type_hint'); } - /** - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Cannot autowire service "not_really_optional_scalar": argument $foo of method Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArgumentsOptionalScalarNotReallyOptional::__construct() must have a type-hint or be given a value explicitly. - */ - public function testOptionalScalarNotReallyOptionalThrowException() + public function testOptionalScalarNotReallyOptionalUsesDefaultValue() { $container = new ContainerBuilder(); $container->register('a', __NAMESPACE__.'\A'); $container->register('lille', __NAMESPACE__.'\Lille'); - $container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional') + $definition = $container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional') ->setAutowired(true); $pass = new AutowirePass(); $pass->process($container); + + $this->assertSame('default_val', $definition->getArgument(1)); } public function testOptionalScalarArgsDontMessUpOrder() @@ -637,7 +635,12 @@ public function testNotWireableCalls($method, $expectedMsg) { $container = new ContainerBuilder(); - $foo = $container->register('foo', NotWireable::class)->setAutowired(true); + $foo = $container->register('foo', NotWireable::class)->setAutowired(true) + ->addMethodCall('setBar', array()) + ->addMethodCall('setOptionalNotAutowireable', array()) + ->addMethodCall('setOptionalNoTypeHint', array()) + ->addMethodCall('setOptionalArgNoAutowireable', array()) + ; if ($method) { $foo->addMethodCall($method, array()); @@ -659,10 +662,6 @@ public function provideNotWireableCalls() { return array( array('setNotAutowireable', 'Cannot autowire service "foo": argument $n of method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setNotAutowireable() has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass" but this class does not exist.'), - array('setBar', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setBar() has only optional arguments, thus must be wired explicitly.'), - array('setOptionalNotAutowireable', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalNotAutowireable() has only optional arguments, thus must be wired explicitly.'), - array('setOptionalNoTypeHint', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalNoTypeHint() has only optional arguments, thus must be wired explicitly.'), - array('setOptionalArgNoAutowireable', 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setOptionalArgNoAutowireable() has only optional arguments, thus must be wired explicitly.'), array(null, 'Cannot autowire service "foo": method Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setProtectedMethod() must be public.'), ); }