Skip to content

Commit b0600fa

Browse files
committed
resolved cooperation with union types
1 parent df058c3 commit b0600fa

File tree

5 files changed

+84
-5
lines changed

5 files changed

+84
-5
lines changed

src/DI/Container.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function addService(string $name, $service)
7676
}
7777

7878
$type = $service instanceof \Closure
79-
? (($tmp = (new \ReflectionFunction($service))->getReturnType()) ? $tmp->getName() : '')
79+
? (string) Nette\Utils\Reflection::getReturnType(new \ReflectionFunction($service))
8080
: get_class($service);
8181

8282
if (!isset($this->methods[self::getMethodName($name)])) {

src/DI/Definitions/FactoryDefinition.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,13 @@ private function completeParameters(Nette\DI\Resolver $resolver): void
230230
}
231231

232232
foreach ($method->getParameters() as $param) {
233-
$methodHint = Reflection::getParameterType($param);
233+
$methodHint = Reflection::getParameterTypes($param);
234234
if (isset($ctorParams[$param->name])) {
235235
$ctorParam = $ctorParams[$param->name];
236-
$ctorHint = Reflection::getParameterType($ctorParam);
237-
if ($methodHint !== $ctorHint && !is_a($methodHint, (string) $ctorHint, true)) {
236+
$ctorHint = Reflection::getParameterTypes($ctorParam);
237+
if ($methodHint !== $ctorHint
238+
&& !is_a((string) reset($methodHint), (string) reset($ctorHint), true)
239+
) {
238240
throw new ServiceCreationException("Type hint for \${$param->name} in $interface::create() doesn't match type hint in $class constructor.");
239241
}
240242
$this->resultDefinition->getFactory()->arguments[$ctorParam->getPosition()] = Nette\DI\ContainerBuilder::literal('$' . $ctorParam->name);
@@ -243,7 +245,11 @@ private function completeParameters(Nette\DI\Resolver $resolver): void
243245
$hint = Nette\Utils\Helpers::getSuggestion(array_keys($ctorParams), $param->name);
244246
throw new ServiceCreationException("Unused parameter \${$param->name} when implementing method $interface::create()" . ($hint ? ", did you mean \${$hint}?" : '.'));
245247
}
246-
$paramDef = ($methodHint && $param->allowsNull() ? '?' : '') . $methodHint . ' ' . $param->name;
248+
249+
$methodHint = PHP_VERSION_ID < 80000
250+
? ($methodHint && $param->allowsNull() ? '?' : '') . reset($methodHint)
251+
: implode('|', $methodHint);
252+
$paramDef = $methodHint . ' ' . $param->name;
247253
if ($param->isDefaultValueAvailable()) {
248254
$this->parameters[$paramDef] = Reflection::getParameterDefaultValue($param);
249255
} else {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\DI\Container dynamic usage.
5+
* @phpVersion 8.0
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
use Nette\DI\Container;
11+
use Tester\Assert;
12+
13+
require __DIR__ . '/../bootstrap.php';
14+
15+
16+
$container = new Container;
17+
18+
// union type
19+
Assert::exception(function () use ($container) {
20+
@$container->addService('six', function (): \stdClass|\Closure {}); // @ triggers service should be defined as "imported"
21+
$container->getService('six');
22+
}, Nette\InvalidStateException::class, 'The {closure}() is not expected to have a union type.');
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\DI\Extensions\InjectExtension::getInjectProperties()
5+
* @phpVersion 8.0
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
use Nette\DI\Extensions\InjectExtension;
11+
use Tester\Assert;
12+
13+
require __DIR__ . '/../bootstrap.php';
14+
15+
16+
class AClass
17+
{
18+
/** @inject */
19+
public AClass|\stdClass $var;
20+
}
21+
22+
23+
Assert::exception(function () {
24+
InjectExtension::getInjectProperties(AClass::class);
25+
}, Nette\InvalidStateException::class, 'The AClass::$var is not expected to have a union type.');
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\DI\Resolver::autowireArguments()
5+
* @phpVersion 8.0
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
use Nette\DI\Resolver;
11+
use Tester\Assert;
12+
13+
14+
require __DIR__ . '/../bootstrap.php';
15+
16+
17+
class Test
18+
{
19+
public function methodUnion(\stdClass |self $self)
20+
{
21+
}
22+
}
23+
24+
Assert::exception(function () {
25+
Resolver::autowireArguments(new ReflectionMethod('Test', 'methodUnion'), [], function () {});
26+
}, Nette\InvalidStateException::class, 'The $self in Test::methodUnion() is not expected to have a union type.');

0 commit comments

Comments
 (0)