Skip to content

Commit 1a3210f

Browse files
committed
Resolver: handles nullable or default union|types
1 parent 8d5e286 commit 1a3210f

4 files changed

+32
-9
lines changed

src/DI/Resolver.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,8 @@ public static function autowireArguments(
541541
*/
542542
private static function autowireArgument(\ReflectionParameter $parameter, callable $getter)
543543
{
544-
$type = Reflection::getParameterType($parameter);
544+
$types = array_diff(Reflection::getParameterTypes($parameter), ['null']);
545+
$type = count($types) === 1 ? reset($types) : null;
545546
$method = $parameter->getDeclaringFunction();
546547
$desc = Reflection::toString($parameter);
547548

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

573574
} elseif (
574-
($type && $parameter->allowsNull())
575+
($types && $parameter->allowsNull())
575576
|| $parameter->isOptional()
576577
|| $parameter->isDefaultValueAvailable()
577578
) {
@@ -582,7 +583,8 @@ private static function autowireArgument(\ReflectionParameter $parameter, callab
582583
: null;
583584

584585
} else {
585-
throw new ServiceCreationException("Parameter $desc has no class type hint or default value, so its value must be specified.");
586+
$tmp = count($types) > 1 ? 'union' : 'no class';
587+
throw new ServiceCreationException("Parameter $desc has $tmp type hint and no default value, so its value must be specified.");
586588
}
587589
}
588590
}

tests/DI/ContainerBuilder.autowiring.novalue.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Assert::exception(function () {
2424
$builder = new DI\ContainerBuilder;
2525
$builder->addDefinition('foo')->setType('Foo');
2626
$container = createContainer($builder);
27-
}, 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.");
27+
}, 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.");
2828

2929

3030
class Bar
@@ -38,7 +38,7 @@ Assert::exception(function () {
3838
$builder = new DI\ContainerBuilder;
3939
$builder->addDefinition('foo')->setType('Bar');
4040
$container = createContainer($builder);
41-
}, 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.");
41+
}, 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.");
4242

4343

4444
class Bar2

tests/DI/Resolver.autowireArguments.80.phpt

+23-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,32 @@ require __DIR__ . '/../bootstrap.php';
1616

1717
class Test
1818
{
19-
public function methodUnion(\stdClass |self $self)
19+
public function methodUnion(\stdClass|self $self)
20+
{
21+
}
22+
23+
24+
public function methodUnionNullable(\stdClass|self|null $nullable)
25+
{
26+
}
27+
28+
29+
public function methodUnionDefault(\stdClass|int $default = 1)
2030
{
2131
}
2232
}
2333

34+
2435
Assert::exception(function () {
2536
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnion'), [], function () {});
26-
}, Nette\InvalidStateException::class, 'The $self in Test::methodUnion() is not expected to have a union type.');
37+
}, Nette\InvalidStateException::class, 'Parameter $self in Test::methodUnion() has union type hint and no default value, so its value must be specified.');
38+
39+
Assert::same(
40+
[null],
41+
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnionNullable'), [], function () {}),
42+
);
43+
44+
Assert::same(
45+
[],
46+
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnionDefault'), [], function () {}),
47+
);

tests/DI/Resolver.autowireArguments.errors.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ Assert::exception(function () {
2525

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

3030

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

0 commit comments

Comments
 (0)