diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 39d0cdac07..1ab8c0eac1 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -80,7 +80,7 @@ class AutowirePass extends AbstractRecursivePass if ($ref = $this->getAutowiredReference($value)) { return $ref; } - $this->container->log($this, $this->createTypeNotFoundMessage($value->getType(), 'it')); + $this->container->log($this, $this->createTypeNotFoundMessage($value, 'it')); } $value = parent::processValue($value, $isRoot); @@ -240,8 +240,8 @@ class AutowirePass extends AbstractRecursivePass continue; } - if (!$value = $this->getAutowiredReference(new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''))) { - $failureMessage = $this->createTypeNotFoundMessage($type, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); + if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''))) { + $failureMessage = $this->createTypeNotFoundMessage($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); if ($parameter->isDefaultValueAvailable()) { $value = $parameter->getDefaultValue(); @@ -424,13 +424,13 @@ class AutowirePass extends AbstractRecursivePass return new TypedReference($argumentId, $type); } - private function createTypeNotFoundMessage($type, $label) + private function createTypeNotFoundMessage(TypedReference $reference, $label) { - if (!$r = $this->container->getReflectionClass($type, true)) { + if (!$r = $this->container->getReflectionClass($type = $reference->getType(), true)) { $message = sprintf('has type "%s" but this class does not exist.', $type); } else { $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($type)); + $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $this->createTypeAlternatives($reference)); } $message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message); @@ -443,12 +443,14 @@ class AutowirePass extends AbstractRecursivePass return $message; } - private function createTypeAlternatives($type) + private function createTypeAlternatives(TypedReference $reference) { - if (isset($this->ambiguousServiceTypes[$type])) { + if (isset($this->ambiguousServiceTypes[$type = $reference->getType()])) { $message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type])); } elseif (isset($this->types[$type])) { $message = sprintf('the existing "%s" service', $this->types[$type]); + } elseif ($reference->getRequiringClass() && !$reference->canBeAutoregistered()) { + return ' It cannot be auto-registered because it is from a different root namespace.'; } else { return; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 9ed9698e40..e8a522cf41 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -694,6 +694,7 @@ class AutowirePassTest extends TestCase { 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('setDifferentNamespace', 'Cannot autowire service "foo": argument "$n" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setDifferentNamespace()" references class "stdClass" but no such service exists. It cannot be auto-registered because it is from a different root namespace.'), array(null, 'Cannot autowire service "foo": method "Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setProtectedMethod()" must be public.'), ); } @@ -1019,6 +1020,10 @@ class NotWireable { } + public function setDifferentNamespace(\stdClass $n) + { + } + public function setOptionalNoTypeHint($foo = null) { }