diff --git a/UPGRADE-7.3.md b/UPGRADE-7.3.md index 685bc6b2e6807..0a11e920cca18 100644 --- a/UPGRADE-7.3.md +++ b/UPGRADE-7.3.md @@ -98,6 +98,12 @@ Validator ) ``` +TypeInfo +-------- + + * Deprecate constructing a `CollectionType` instance as a list that is not an array + * Deprecate the third `$asList` argument of `TypeFactoryTrait::iterable()`, use `TypeFactoryTrait::list()` instead + VarDumper --------- diff --git a/src/Symfony/Component/TypeInfo/CHANGELOG.md b/src/Symfony/Component/TypeInfo/CHANGELOG.md index 122720c1c3e5e..2dfd862c9f77d 100644 --- a/src/Symfony/Component/TypeInfo/CHANGELOG.md +++ b/src/Symfony/Component/TypeInfo/CHANGELOG.md @@ -6,6 +6,8 @@ CHANGELOG * Add `Type::accepts()` method * Add `TypeFactoryTrait::fromValue()` method + * Deprecate constructing a `CollectionType` instance as a list that is not an array + * Deprecate the third `$asList` argument of `TypeFactoryTrait::iterable()`, use `TypeFactoryTrait::list()` instead 7.2 --- diff --git a/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php b/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php index f4f2b1caeb87d..fdc2a215f63be 100644 --- a/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/Type/CollectionTypeTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\TypeInfo\Tests\Type; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait; use Symfony\Component\TypeInfo\Exception\InvalidArgumentException; use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\Type\CollectionType; @@ -20,6 +21,8 @@ class CollectionTypeTest extends TestCase { + use ExpectUserDeprecationMessageTrait; + public function testCannotCreateInvalidBuiltinType() { $this->expectException(InvalidArgumentException::class); @@ -122,4 +125,13 @@ public function testAccepts() $this->assertTrue($type->accepts(new \ArrayObject([0 => true, 1 => false]))); $this->assertFalse($type->accepts(new \ArrayObject([0 => true, 1 => 'string']))); } + + /** + * @group legacy + */ + public function testCannotCreateIterableList() + { + $this->expectUserDeprecationMessage('Since symfony/type-info 7.3: Creating a "Symfony\Component\TypeInfo\Type\CollectionType" that is a list and not an array is deprecated and will throw a "Symfony\Component\TypeInfo\Exception\InvalidArgumentException" in 8.0.'); + new CollectionType(Type::generic(Type::builtin(TypeIdentifier::ITERABLE), Type::bool()), isList: true); + } } diff --git a/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php b/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php index d1732671604bb..e62e881f7ceef 100644 --- a/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\TypeInfo\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait; use Symfony\Component\TypeInfo\Tests\Fixtures\DummyBackedEnum; use Symfony\Component\TypeInfo\Tests\Fixtures\DummyEnum; use Symfony\Component\TypeInfo\Type; @@ -29,6 +30,8 @@ class TypeFactoryTest extends TestCase { + use ExpectUserDeprecationMessageTrait; + public function testCreateBuiltin() { $this->assertEquals(new BuiltinType(TypeIdentifier::INT), Type::builtin(TypeIdentifier::INT)); @@ -136,15 +139,6 @@ public function testCreateIterable() )), Type::iterable(Type::bool(), Type::string()), ); - - $this->assertEquals( - new CollectionType(new GenericType( - new BuiltinType(TypeIdentifier::ITERABLE), - new BuiltinType(TypeIdentifier::INT), - new BuiltinType(TypeIdentifier::BOOL), - ), isList: true), - Type::iterable(Type::bool(), Type::int(), true), - ); } public function testCreateObject() @@ -263,4 +257,13 @@ public function offsetUnset(mixed $offset): void yield [Type::collection(Type::object(\Generator::class), Type::string(), Type::int()), (fn (): iterable => yield 'string')()]; yield [Type::collection(Type::object($arrayAccess::class)), $arrayAccess]; } + + /** + * @group legacy + */ + public function testCannotCreateIterableList() + { + $this->expectUserDeprecationMessage('Since symfony/type-info 7.3: The third argument of "Symfony\Component\TypeInfo\TypeFactoryTrait::iterable()" is deprecated. Use the "Symfony\Component\TypeInfo\Type::list()" method to create a list instead.'); + Type::iterable(key: Type::int(), asList: true); + } } diff --git a/src/Symfony/Component/TypeInfo/Type/CollectionType.php b/src/Symfony/Component/TypeInfo/Type/CollectionType.php index 90f5a4a398fe2..127345b52fa9f 100644 --- a/src/Symfony/Component/TypeInfo/Type/CollectionType.php +++ b/src/Symfony/Component/TypeInfo/Type/CollectionType.php @@ -39,6 +39,11 @@ public function __construct( } if ($this->isList()) { + if (!$type->isIdentifiedBy(TypeIdentifier::ARRAY)) { + trigger_deprecation('symfony/type-info', '7.3', 'Creating a "%s" that is a list and not an array is deprecated and will throw a "%s" in 8.0.', self::class, InvalidArgumentException::class); + // throw new InvalidArgumentException(\sprintf('Cannot create a "%s" as list when type is not "array".', self::class)); + } + $keyType = $this->getCollectionKeyType(); if (!$keyType instanceof BuiltinType || TypeIdentifier::INT !== $keyType->getTypeIdentifier()) { diff --git a/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php b/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php index 0afc94d1234f1..382644dd5e38c 100644 --- a/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php +++ b/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php @@ -171,6 +171,10 @@ public static function array(?Type $value = null, ?Type $key = null, bool $asLis */ public static function iterable(?Type $value = null, ?Type $key = null, bool $asList = false): CollectionType { + if ($asList) { + trigger_deprecation('symfony/type-info', '7.3', 'The third argument of "%s()" is deprecated. Use the "%s::list()" method to create a list instead.', __METHOD__, self::class); + } + return self::collection(self::builtin(TypeIdentifier::ITERABLE), $value, $key, $asList); } diff --git a/src/Symfony/Component/TypeInfo/composer.json b/src/Symfony/Component/TypeInfo/composer.json index a246dd94f45fd..66a842203f2ef 100644 --- a/src/Symfony/Component/TypeInfo/composer.json +++ b/src/Symfony/Component/TypeInfo/composer.json @@ -26,7 +26,8 @@ ], "require": { "php": ">=8.2", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { "phpstan/phpdoc-parser": "^1.0|^2.0"