diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index e11154889c..2482db6314 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -254,6 +254,25 @@ class AutowirePassTest extends TestCase $pass->process($container); } + /** + * @requires PHP 8 + */ + public function testTypeNotGuessableUnionType() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionClasses::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionA|Symfony\Component\DependencyInjection\Tests\Compiler\CollisionB" but this class was not found.'); + $container = new ContainerBuilder(); + + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + $aDefinition = $container->register('a', UnionClasses::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + public function testTypeNotGuessableWithTypeSet() { $container = new ContainerBuilder(); @@ -350,6 +369,40 @@ class AutowirePassTest extends TestCase $this->assertEquals(Foo::class, $definition->getArgument(2)); } + /** + * @requires PHP 8 + */ + public function testParameterWithNullUnionIsSkipped() + { + $container = new ContainerBuilder(); + + $optDefinition = $container->register('opt', UnionNull::class); + $optDefinition->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('opt'); + $this->assertNull($definition->getArgument(0)); + } + + /** + * @requires PHP 8 + */ + public function testParameterWithNullUnionIsAutowired() + { + $container = new ContainerBuilder(); + + $container->register(CollisionInterface::class, CollisionA::class); + + $optDefinition = $container->register('opt', UnionNull::class); + $optDefinition->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('opt'); + $this->assertEquals(CollisionInterface::class, $definition->getArgument(0)); + } + public function testDontTriggerAutowiring() { $container = new ContainerBuilder(); @@ -459,6 +512,21 @@ class AutowirePassTest extends TestCase (new AutowirePass())->process($container); } + /** + * @requires PHP 8 + */ + public function testUnionScalarArgsCannotBeAutowired() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "union_scalars": argument "$timeout" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionScalars::__construct()" is type-hinted "int|float", you should configure its value explicitly.'); + $container = new ContainerBuilder(); + + $container->register('union_scalars', UnionScalars::class) + ->setAutowired(true); + + (new AutowirePass())->process($container); + } + public function testNoTypeArgsCannotBeAutowired() { $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php index 8db7edf1a1..42545c9c2b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php @@ -2,6 +2,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; +if (PHP_VERSION_ID >= 80000) { + require __DIR__.'/uniontype_classes.php'; +} + class Foo { } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/uniontype_classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/uniontype_classes.php new file mode 100644 index 0000000000..3a0c77c539 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/uniontype_classes.php @@ -0,0 +1,24 @@ +getTypes() : [$reflectionType] as $type) { $phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type; + if ('null' === $phpTypeOrClass) { + continue; + } if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) { $types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true); - } elseif ('void' === $phpTypeOrClass || 'null' === $phpTypeOrClass) { + } elseif ('void' === $phpTypeOrClass) { $types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable); - } elseif ($reflectionType->isBuiltin()) { + } elseif ($type->isBuiltin()) { $types[] = new Type($phpTypeOrClass, $nullable); } else { $types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod)); diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 36fc9d55e3..bac036aa5b 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -204,6 +204,26 @@ class ReflectionExtractorTest extends TestCase ]; } + /** + * @dataProvider php80TypesProvider + * @requires PHP 8 + */ + public function testExtractPhp80Type($property, array $type = null) + { + $this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy', $property, [])); + } + + public function php80TypesProvider() + { + return [ + ['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)]], + ['bar', [new Type(Type::BUILTIN_TYPE_INT, true)]], + ['timeout', [new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_FLOAT)]], + ['optional', [new Type(Type::BUILTIN_TYPE_INT, true), new Type(Type::BUILTIN_TYPE_FLOAT, true)]], + ['string', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Stringable'), new Type(Type::BUILTIN_TYPE_STRING)]], + ]; + } + /** * @dataProvider getReadableProperties */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php80Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php80Dummy.php new file mode 100644 index 0000000000..484498f4a6 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php80Dummy.php @@ -0,0 +1,26 @@ +