diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index ffd3c4e08b819..4fb467d965d8d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -203,6 +203,10 @@ protected function getReflectionMethod(Definition $definition, $method) } if (!$r->hasMethod($method)) { + if ($r->hasMethod('__call') && ($r = $r->getMethod('__call')) && $r->isPublic()) { + return new \ReflectionMethod(static function (...$arguments) {}, '__invoke'); + } + throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php index adb725cc99c7f..9de33d2f5eef3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php @@ -988,4 +988,22 @@ public function testIntersectionTypeFailsWithReference() (new CheckTypeDeclarationsPass(true))->process($container); } + + public function testCallableClass() + { + $container = new ContainerBuilder(); + $definition = $container->register('foo', CallableClass::class); + $definition->addMethodCall('callMethod', [123]); + + (new CheckTypeDeclarationsPass())->process($container); + + $this->addToAssertionCount(1); + } +} + +class CallableClass +{ + public function __call($name, $arguments) + { + } }