Skip to content

Commit

Permalink
Resolver: handles nullable or default union|types
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Mar 2, 2021
1 parent 8d5e286 commit 1a3210f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 9 deletions.
8 changes: 5 additions & 3 deletions src/DI/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,8 @@ public static function autowireArguments(
*/
private static function autowireArgument(\ReflectionParameter $parameter, callable $getter)
{
$type = Reflection::getParameterType($parameter);
$types = array_diff(Reflection::getParameterTypes($parameter), ['null']);
$type = count($types) === 1 ? reset($types) : null;
$method = $parameter->getDeclaringFunction();
$desc = Reflection::toString($parameter);

Expand Down Expand Up @@ -571,7 +572,7 @@ private static function autowireArgument(\ReflectionParameter $parameter, callab
return $getter($itemType, false);

} elseif (
($type && $parameter->allowsNull())
($types && $parameter->allowsNull())
|| $parameter->isOptional()
|| $parameter->isDefaultValueAvailable()
) {
Expand All @@ -582,7 +583,8 @@ private static function autowireArgument(\ReflectionParameter $parameter, callab
: null;

} else {
throw new ServiceCreationException("Parameter $desc has no class type hint or default value, so its value must be specified.");
$tmp = count($types) > 1 ? 'union' : 'no class';
throw new ServiceCreationException("Parameter $desc has $tmp type hint and no default value, so its value must be specified.");
}
}
}
4 changes: 2 additions & 2 deletions tests/DI/ContainerBuilder.autowiring.novalue.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('foo')->setType('Foo');
$container = createContainer($builder);
}, Nette\DI\ServiceCreationException::class, "Service 'foo' (type of Foo): Parameter \$x in __construct() has no class type hint or default value, so its value must be specified.");
}, Nette\DI\ServiceCreationException::class, "Service 'foo' (type of Foo): Parameter \$x in __construct() has no class type hint and no default value, so its value must be specified.");


class Bar
Expand All @@ -38,7 +38,7 @@ Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('foo')->setType('Bar');
$container = createContainer($builder);
}, Nette\DI\ServiceCreationException::class, "Service 'foo' (type of Bar): Parameter \$x in __construct() has no class type hint or default value, so its value must be specified.");
}, Nette\DI\ServiceCreationException::class, "Service 'foo' (type of Bar): Parameter \$x in __construct() has no class type hint and no default value, so its value must be specified.");


class Bar2
Expand Down
25 changes: 23 additions & 2 deletions tests/DI/Resolver.autowireArguments.80.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,32 @@ require __DIR__ . '/../bootstrap.php';

class Test
{
public function methodUnion(\stdClass |self $self)
public function methodUnion(\stdClass|self $self)
{
}


public function methodUnionNullable(\stdClass|self|null $nullable)
{
}


public function methodUnionDefault(\stdClass|int $default = 1)
{
}
}


Assert::exception(function () {
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnion'), [], function () {});
}, Nette\InvalidStateException::class, 'The $self in Test::methodUnion() is not expected to have a union type.');
}, Nette\InvalidStateException::class, 'Parameter $self in Test::methodUnion() has union type hint and no default value, so its value must be specified.');

Assert::same(
[null],
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnionNullable'), [], function () {}),
);

Assert::same(
[],
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnionDefault'), [], function () {}),
);
4 changes: 2 additions & 2 deletions tests/DI/Resolver.autowireArguments.errors.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ Assert::exception(function () {

Assert::exception(function () {
Resolver::autowireArguments(new ReflectionFunction(function ($x) {}), [], function () {});
}, Nette\DI\ServiceCreationException::class, 'Parameter $x in {closure}%a?% has no class type hint or default value, so its value must be specified.');
}, Nette\DI\ServiceCreationException::class, 'Parameter $x in {closure}() has no class type hint and no default value, so its value must be specified.');


Assert::exception(function () {
Resolver::autowireArguments(new ReflectionFunction(function (int $x) {}), [], function () {});
}, Nette\DI\ServiceCreationException::class, 'Parameter $x in {closure}%a?% has no class type hint or default value, so its value must be specified.');
}, Nette\DI\ServiceCreationException::class, 'Parameter $x in {closure}() has no class type hint and no default value, so its value must be specified.');

0 comments on commit 1a3210f

Please sign in to comment.