From a72283190297db4398742a1c83c73671861de41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mor=C3=A1vek?= Date: Wed, 17 Jun 2020 23:20:39 +0200 Subject: [PATCH] AutowireProperties: add support for factory return typehint --- src/Kdyby/Autowired/AutowireProperties.php | 20 ++++++++++++++++--- .../Autowired/AutowireProperties.phpt | 17 ++++++++++++++++ tests/KdybyTests/config/properties.neon | 4 ++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/Kdyby/Autowired/AutowireProperties.php b/src/Kdyby/Autowired/AutowireProperties.php index 181bf78..bbb3d70 100644 --- a/src/Kdyby/Autowired/AutowireProperties.php +++ b/src/Kdyby/Autowired/AutowireProperties.php @@ -153,9 +153,7 @@ private function resolveProperty(Property $prop): void } $factoryMethod = Method::from($factoryType, 'create'); - /** @var Nette\Reflection\Annotation $returnAnnotation */ - $returnAnnotation = $factoryMethod->getAnnotation('return'); - $createsType = $this->resolveAnnotationClass($factoryMethod, (string) $returnAnnotation, 'return'); + $createsType = $this->resolveReturnType($factoryMethod); if ($createsType !== $type) { throw new UnexpectedValueException("The property $prop requires $type, but factory of type $factoryType, that creates $createsType was provided.", $prop); } @@ -191,6 +189,22 @@ private function resolvePropertyType(Property $prop): string } + private function resolveReturnType(Method $method): string + { + if ($method->hasReturnType()) { + $type = $method->getReturnType()->getName(); + if (!class_exists($type) && !interface_exists($type)) { + throw new MissingClassException("Class \"{$type}\" not found, please check the return type on {$method}.", $method); + } + return $type; + } + + /** @var Nette\Reflection\Annotation $returnAnnotation */ + $returnAnnotation = $method->getAnnotation('return'); + return $this->resolveAnnotationClass($method, (string) $returnAnnotation, 'return'); + } + + /** * @param Property|Method $prop diff --git a/tests/KdybyTests/Autowired/AutowireProperties.phpt b/tests/KdybyTests/Autowired/AutowireProperties.phpt index e409837..fb21d18 100644 --- a/tests/KdybyTests/Autowired/AutowireProperties.phpt +++ b/tests/KdybyTests/Autowired/AutowireProperties.phpt @@ -50,6 +50,7 @@ class AutowirePropertiesTest extends ContainerTestCase Assert::null($presenter->service); Assert::null($presenter->factoryResult); Assert::null($presenter->secondFactoryResult); + Assert::null($presenter->typedFactoryResult); $this->container->callMethod([$presenter, 'injectProperties']); @@ -61,6 +62,9 @@ class AutowirePropertiesTest extends ContainerTestCase Assert::true($presenter->secondFactoryResult instanceof SampleService); Assert::same(['string argument', 'and another'], $presenter->secondFactoryResult->args); + + Assert::true($presenter->typedFactoryResult instanceof SampleService); + Assert::same(['foo'], $presenter->typedFactoryResult->args); } @@ -194,6 +198,12 @@ class DummyPresenter extends Nette\Application\UI\Presenter */ public $secondFactoryResult; + /** + * @var SampleService + * @autowire(factory=\KdybyTests\Autowired\ITypedSampleServiceFactory) + */ + public $typedFactoryResult; + } @@ -322,6 +332,13 @@ interface ISampleServiceFactory } + +interface ITypedSampleServiceFactory +{ + function create(): SampleService; +} + + (new AutowirePropertiesTest())->run(); namespace KdybyTests\Autowired\UseExpansion; diff --git a/tests/KdybyTests/config/properties.neon b/tests/KdybyTests/config/properties.neon index a8c3095..b55fd2c 100644 --- a/tests/KdybyTests/config/properties.neon +++ b/tests/KdybyTests/config/properties.neon @@ -6,6 +6,10 @@ services: secondName: null factory: KdybyTests\Autowired\SampleService(%name%, %secondName%) + typedSampleFactory: + implement: KdybyTests\Autowired\ITypedSampleServiceFactory + factory: KdybyTests\Autowired\SampleService('foo') + sample: KdybyTests\Autowired\SampleService('shared')