Skip to content

Commit

Permalink
Add support for nullable default parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
odan committed May 3, 2020
1 parent 35192eb commit b3351f9
Showing 1 changed file with 37 additions and 20 deletions.
57 changes: 37 additions & 20 deletions src/Resolver/ConstructorResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Psr\Container\ContainerInterface;
use ReflectionClass;
use ReflectionMethod;
use ReflectionParameter;
use Selective\Container\Exceptions\InvalidDefinitionException;
use Throwable;

Expand Down Expand Up @@ -51,11 +52,12 @@ public function resolve(string $id)
$reflectionClass = new ReflectionClass($id);

try {
if ($reflectionClass->getConstructor() === null) {
$constructor = $reflectionClass->getConstructor();
if ($constructor === null) {
return $reflectionClass->newInstance();
}

return $reflectionClass->newInstanceArgs($this->resolveParameters($id, $reflectionClass->getConstructor()));
return $reflectionClass->newInstanceArgs($this->resolveParameters($id, $constructor));
} catch (Throwable $exception) {
throw InvalidDefinitionException::create(sprintf(
'Entry "%s" cannot be resolved: the class is not instantiable',
Expand All @@ -70,8 +72,6 @@ public function resolve(string $id)
* @param string $id The id
* @param ReflectionMethod $method The method
*
* @throws InvalidDefinitionException
*
* @return array<mixed> The resolved parameters
*/
private function resolveParameters(string $id, ReflectionMethod $method = null): array
Expand All @@ -83,28 +83,45 @@ private function resolveParameters(string $id, ReflectionMethod $method = null):
$arguments = [];

foreach ($method->getParameters() as $parameter) {
$reflectionClass = $parameter->getClass();

if ($reflectionClass === null) {
throw InvalidDefinitionException::create(sprintf(
'Parameter $%s of %s has no value defined or guessable',
$parameter->getName(),
$id
));
}
$arguments[] = $this->resolveParameter($id, $parameter);
}

// If the parameter is optional and wasn't specified, we take its default value
if ($parameter->isDefaultValueAvailable() || $parameter->isOptional()) {
$arguments[] = $parameter->getDefaultValue();
return $arguments;
}

continue;
}
/**
* Resolve paramameter value.
*
* @param string $id The id
* @param ReflectionParameter $parameter The parameter
*
* @throws InvalidDefinitionException
*
* @return mixed The value
*/
private function resolveParameter(string $id, ReflectionParameter $parameter)
{
$reflectionClass = $parameter->getClass();

if ($reflectionClass !== null) {
// Look in the definitions or try to create it
$arguments[] = $this->container->get($reflectionClass->getName());
$className = $reflectionClass->getName();

if ($this->container->has($className)) {
return $this->container->get($className);
}
}

return $arguments;
// If the parameter is optional and wasn't specified, we take its default value
if ($parameter->isDefaultValueAvailable() || $parameter->isOptional()) {
return $parameter->getDefaultValue();
}

throw InvalidDefinitionException::create(sprintf(
'Parameter $%s of %s has no value defined or guessable',
$parameter->getName(),
$id
));
}

/**
Expand Down

0 comments on commit b3351f9

Please sign in to comment.