diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php index b97032574ab86..b7987668b4f8f 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php @@ -14,10 +14,13 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Clazz; use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummyWithoutDocBlock; use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue; use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection; +use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyGeneric; +use Symfony\Component\PropertyInfo\Tests\Fixtures\IFace; use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php80Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php80PromotedDummy; @@ -482,7 +485,88 @@ public static function php80TypesProvider() public function testGenericInterface() { - $this->assertNull($this->extractor->getTypes(Dummy::class, 'genericInterface')); + $this->assertEquals( + [ + new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: \BackedEnum::class, + collectionValueType: new Type( + builtinType: Type::BUILTIN_TYPE_STRING, + ) + ), + ], + $this->extractor->getTypes(Dummy::class, 'genericInterface') + ); + } + + /** + * @param list $expectedTypes + * @dataProvider genericsProvider + */ + public function testGenericsLegacy(string $property, array $expectedTypes) + { + $this->assertEquals($expectedTypes, $this->extractor->getTypes(DummyGeneric::class, $property)); + } + + /** + * @return iterable}> + */ + public static function genericsProvider(): iterable + { + yield [ + 'basicClass', + [ + new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Clazz::class, + collectionValueType: new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Dummy::class, + ) + ), + ], + ]; + yield [ + 'nullableClass', + [ + new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Clazz::class, + nullable: true, + collectionValueType: new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Dummy::class, + ) + ), + ], + ]; + yield [ + 'basicInterface', + [ + new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: IFace::class, + collectionValueType: new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Dummy::class, + ) + ), + ], + ]; + yield [ + 'nullableInterface', + [ + new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: IFace::class, + nullable: true, + collectionValueType: new Type( + builtinType: Type::BUILTIN_TYPE_OBJECT, + class: Dummy::class, + ) + ), + ], + ]; } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyGeneric.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyGeneric.php new file mode 100644 index 0000000000000..5863fbfc95450 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyGeneric.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Tests\Fixtures; + +interface IFace {} + +class Clazz {} + +class DummyGeneric +{ + + /** + * @var Clazz + */ + public $basicClass; + + /** + * @var ?Clazz + */ + public $nullableClass; + + /** + * @var IFace + */ + public $basicInterface; + + /** + * @var ?IFace + */ + public $nullableInterface; + +} diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php index 7d439f55660dd..56a6b509172c7 100644 --- a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php +++ b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php @@ -128,7 +128,7 @@ private function extractTypes(TypeNode $node, NameScope $nameScope): array $collection = $mainType->isCollection() || \is_a($mainType->getClassName(), \Traversable::class, true) || \is_a($mainType->getClassName(), \ArrayAccess::class, true); // it's safer to fall back to other extractors if the generic type is too abstract - if (!$collection && !class_exists($mainType->getClassName())) { + if (!$collection && !class_exists($mainType->getClassName()) && !interface_exists($mainType->getClassName(), false)) { return []; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy