Skip to content

Commit

Permalink
AutowireProperties: add support for factory return typehint
Browse files Browse the repository at this point in the history
  • Loading branch information
xificurk committed Jun 17, 2020
1 parent 8172f24 commit a722831
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/Kdyby/Autowired/AutowireProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions tests/KdybyTests/Autowired/AutowireProperties.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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']);

Expand All @@ -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);
}


Expand Down Expand Up @@ -194,6 +198,12 @@ class DummyPresenter extends Nette\Application\UI\Presenter
*/
public $secondFactoryResult;

/**
* @var SampleService
* @autowire(factory=\KdybyTests\Autowired\ITypedSampleServiceFactory)
*/
public $typedFactoryResult;

}


Expand Down Expand Up @@ -322,6 +332,13 @@ interface ISampleServiceFactory
}



interface ITypedSampleServiceFactory
{
function create(): SampleService;
}


(new AutowirePropertiesTest())->run();

namespace KdybyTests\Autowired\UseExpansion;
Expand Down
4 changes: 4 additions & 0 deletions tests/KdybyTests/config/properties.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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')


Expand Down

0 comments on commit a722831

Please sign in to comment.