From 116cebc6aebd96a28637492dae59a5864b08121c Mon Sep 17 00:00:00 2001 From: David Matejka Date: Tue, 11 Apr 2017 16:10:00 +0200 Subject: [PATCH] generated factories: fix return type (php does not support return type covariance) --- src/DI/PhpGenerator.php | 7 ++++--- tests/DI/Compiler.generatedFactory.returnTypes.phpt | 11 +++++++++++ .../files/compiler.generatedFactory.returnTypes.neon | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/DI/PhpGenerator.php b/src/DI/PhpGenerator.php index dc1868d45..23d24a3ed 100644 --- a/src/DI/PhpGenerator.php +++ b/src/DI/PhpGenerator.php @@ -10,11 +10,10 @@ namespace Nette\DI; use Nette; -use Nette\Utils\Validators; use Nette\Utils\Strings; use Nette\PhpGenerator\Helpers as PhpHelpers; use Nette\PhpGenerator\PhpLiteral; -use ReflectionClass; +use Nette\Utils\Reflection; /** @@ -150,10 +149,12 @@ private function generateService(string $name): string ->addParameter('container') ->setTypeHint($this->className); + $rm = new \ReflectionMethod($def->getImplement(), $def->getImplementMode()); + $factoryClass->addMethod($def->getImplementMode()) ->setParameters($this->convertParameters($def->parameters)) ->setBody(str_replace('$this', '$this->container', $code)) - ->setReturnType($def->getClass()); + ->setReturnType(Reflection::getReturnType($rm) ?: $def->getClass()); return 'return new class ($this) ' . $factoryClass . ';'; } diff --git a/tests/DI/Compiler.generatedFactory.returnTypes.phpt b/tests/DI/Compiler.generatedFactory.returnTypes.phpt index 21ea4e642..cebe969e5 100644 --- a/tests/DI/Compiler.generatedFactory.returnTypes.phpt +++ b/tests/DI/Compiler.generatedFactory.returnTypes.phpt @@ -29,6 +29,11 @@ class Article } } +class FooArticle extends Article +{ + +} + $compiler = new DI\Compiler; $container = createContainer($compiler, 'files/compiler.generatedFactory.returnTypes.neon'); @@ -41,3 +46,9 @@ Assert::type(IArticleFactory::class, $container->getService('article2')); $article = $container->getService('article2')->create('lorem-ipsum'); Assert::type(Article::class, $article); Assert::same('lorem-ipsum', $article->title); + + +Assert::type(IArticleFactory::class, $container->getService('article3')); +$article = $container->getService('article3')->create('lorem-ipsum'); +Assert::type(FooArticle::class, $article); +Assert::same('lorem-ipsum', $article->title); diff --git a/tests/DI/files/compiler.generatedFactory.returnTypes.neon b/tests/DI/files/compiler.generatedFactory.returnTypes.neon index b70855672..5917be2db 100644 --- a/tests/DI/files/compiler.generatedFactory.returnTypes.neon +++ b/tests/DI/files/compiler.generatedFactory.returnTypes.neon @@ -9,3 +9,7 @@ services: implement: IArticleFactory arguments: [%title%] parameters: [title] + + article3: + implement: IArticleFactory + factory: FooArticle