diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/BackedEnumTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/BackedEnumTypeTest.php index be3fb65678e3e..6f69173f3a4c1 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/BackedEnumTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/BackedEnumTypeTest.php @@ -29,6 +29,11 @@ public function testIsNullable() $this->assertFalse((new BackedEnumType(DummyBackedEnum::class, Type::int()))->isNullable()); } + public function testGetBaseType() + { + $this->assertEquals(new BackedEnumType(DummyBackedEnum::class, Type::int()), (new BackedEnumType(DummyBackedEnum::class, Type::int()))->getBaseType()); + } + public function testAsNonNullable() { $type = new BackedEnumType(DummyBackedEnum::class, Type::int()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/BuiltinTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/BuiltinTypeTest.php index c417e71ec58fa..8442761dbc1dd 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/BuiltinTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/BuiltinTypeTest.php @@ -24,6 +24,11 @@ public function testToString() $this->assertSame('int', (string) new BuiltinType(TypeIdentifier::INT)); } + public function testGetBaseType() + { + $this->assertEquals(new BuiltinType(TypeIdentifier::INT), (new BuiltinType(TypeIdentifier::INT))->getBaseType()); + } + public function testIsNullable() { $this->assertFalse((new BuiltinType(TypeIdentifier::INT))->isNullable()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php index 5faee73d95ea4..a529149723f9c 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php @@ -74,6 +74,11 @@ public function testToString() $this->assertEquals('array', (string) $type); } + public function testGetBaseType() + { + $this->assertEquals(Type::int(), Type::collection(Type::generic(Type::int(), Type::string()))->getBaseType()); + } + public function testIsNullable() { $this->assertFalse((new CollectionType(Type::generic(Type::builtin(TypeIdentifier::ARRAY), Type::int())))->isNullable()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/EnumTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/EnumTypeTest.php index fdf7bafb3805a..9fe2712798f2c 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/EnumTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/EnumTypeTest.php @@ -23,6 +23,11 @@ public function testToString() $this->assertSame(DummyEnum::class, (string) new EnumType(DummyEnum::class)); } + public function testGetBaseType() + { + $this->assertEquals(new EnumType(DummyEnum::class), (new EnumType(DummyEnum::class))->getBaseType()); + } + public function testIsNullable() { $this->assertFalse((new EnumType(DummyEnum::class))->isNullable()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/GenericTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/GenericTypeTest.php index bdaf7e8654834..adca4a00d9147 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/GenericTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/GenericTypeTest.php @@ -30,6 +30,11 @@ public function testToString() $this->assertEquals(sprintf('%s', self::class), (string) $type); } + public function testGetBaseType() + { + $this->assertEquals(Type::object(), Type::generic(Type::object(), Type::int())->getBaseType()); + } + public function testIsNullable() { $this->assertFalse((new GenericType(Type::builtin(TypeIdentifier::ARRAY), Type::int()))->isNullable()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/IntersectionTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/IntersectionTypeTest.php index a6db32f126234..8002ebcba1430 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/IntersectionTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/IntersectionTypeTest.php @@ -56,6 +56,12 @@ public function testEveryTypeIs() $this->assertFalse($type->everyTypeIs(fn (Type $t) => $t instanceof BuiltinType)); } + public function testGetBaseType() + { + $this->expectException(LogicException::class); + (new IntersectionType(Type::string(), Type::int()))->getBaseType(); + } + public function testToString() { $type = new IntersectionType(Type::int(), Type::string(), Type::float()); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/ObjectTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/ObjectTypeTest.php index c9e3399361a20..334ee70e70c09 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/ObjectTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/ObjectTypeTest.php @@ -27,6 +27,11 @@ public function testIsNullable() $this->assertFalse((new ObjectType(self::class))->isNullable()); } + public function testGetBaseType() + { + $this->assertEquals(new ObjectType(self::class), (new ObjectType(self::class))->getBaseType()); + } + public function testIsA() { $this->assertFalse((new ObjectType(self::class))->isA(TypeIdentifier::ARRAY)); diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/UnionTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/UnionTypeTest.php index 827793ff71c2e..d270b56b02d66 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/UnionTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/UnionTypeTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\TypeInfo\Exception\InvalidArgumentException; +use Symfony\Component\TypeInfo\Exception\LogicException; use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\Type\BuiltinType; use Symfony\Component\TypeInfo\Type\UnionType; @@ -66,6 +67,14 @@ public function testAsNonNullable() ], $type->asNonNullable()->getTypes()); } + public function testGetBaseType() + { + $this->assertEquals(Type::string(), (new UnionType(Type::string(), Type::null()))->getBaseType()); + + $this->expectException(LogicException::class); + (new UnionType(Type::string(), Type::int(), Type::null()))->getBaseType(); + } + public function testAtLeastOneTypeIs() { $type = new UnionType(Type::int(), Type::string(), Type::bool()); diff --git a/src/Symfony/Component/TypeInfo/Tests/TypeTest.php b/src/Symfony/Component/TypeInfo/Tests/TypeTest.php index 2f0ad858ed3e9..f368dd5e31695 100644 --- a/src/Symfony/Component/TypeInfo/Tests/TypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/TypeTest.php @@ -57,15 +57,6 @@ public function testIsNullable() $this->assertFalse(Type::generic(Type::int(), Type::mixed())->isNullable()); } - public function testGetBaseType() - { - $this->assertEquals(Type::string(), Type::string()->getBaseType()); - $this->assertEquals(Type::object(self::class), Type::object(self::class)->getBaseType()); - $this->assertEquals(Type::object(), Type::generic(Type::object(), Type::int())->getBaseType()); - $this->assertEquals(Type::builtin(TypeIdentifier::ARRAY), Type::list()->getBaseType()); - $this->assertEquals(Type::int(), Type::collection(Type::generic(Type::int(), Type::string()))->getBaseType()); - } - public function testCannotGetBaseTypeOnCompoundType() { $this->expectException(LogicException::class); diff --git a/src/Symfony/Component/TypeInfo/Type/CompositeTypeTrait.php b/src/Symfony/Component/TypeInfo/Type/CompositeTypeTrait.php index 15373674ee79a..5270bd3f9f7f1 100644 --- a/src/Symfony/Component/TypeInfo/Type/CompositeTypeTrait.php +++ b/src/Symfony/Component/TypeInfo/Type/CompositeTypeTrait.php @@ -12,7 +12,6 @@ namespace Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\Exception\InvalidArgumentException; -use Symfony\Component\TypeInfo\Exception\LogicException; use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\TypeIdentifier; @@ -50,11 +49,6 @@ public function __construct(Type ...$types) $this->types = array_values(array_unique($types)); } - public function getBaseType(): BuiltinType|ObjectType - { - throw new LogicException(sprintf('Cannot get base type on "%s" compound type.', $this)); - } - public function isA(TypeIdentifier $typeIdentifier): bool { return $this->is(fn (Type $type) => $type->isA($typeIdentifier)); diff --git a/src/Symfony/Component/TypeInfo/Type/IntersectionType.php b/src/Symfony/Component/TypeInfo/Type/IntersectionType.php index c829874eab81f..133b409434865 100644 --- a/src/Symfony/Component/TypeInfo/Type/IntersectionType.php +++ b/src/Symfony/Component/TypeInfo/Type/IntersectionType.php @@ -45,6 +45,17 @@ public function __toString(): string return $string; } + /** + * @throws LogicException + */ + public function getBaseType(): BuiltinType|ObjectType + { + throw new LogicException(sprintf('Cannot get base type on "%s" compound type.', $this)); + } + + /** + * @throws LogicException + */ public function asNonNullable(): self { if ($this->isNullable()) { diff --git a/src/Symfony/Component/TypeInfo/Type/UnionType.php b/src/Symfony/Component/TypeInfo/Type/UnionType.php index 380d66b2d7e88..0b29fc43c0ca1 100644 --- a/src/Symfony/Component/TypeInfo/Type/UnionType.php +++ b/src/Symfony/Component/TypeInfo/Type/UnionType.php @@ -11,6 +11,7 @@ namespace Symfony\Component\TypeInfo\Type; +use Symfony\Component\TypeInfo\Exception\LogicException; use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\TypeIdentifier; @@ -32,6 +33,19 @@ public function is(callable $callable): bool return $this->atLeastOneTypeIs($callable); } + /** + * @throws LogicException + */ + public function getBaseType(): BuiltinType|ObjectType + { + $nonNullableType = $this->asNonNullable(); + if (!$nonNullableType instanceof self) { + return $nonNullableType->getBaseType(); + } + + throw new LogicException(sprintf('Cannot get base type on "%s" compound type.', $this)); + } + public function asNonNullable(): Type { $nonNullableTypes = [];