From 0302128646ac90d07c0bc20e1dee58b2811a1f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sun, 12 Dec 2021 13:23:14 +0100 Subject: [PATCH] [PropertyInfo] Fix phpstan extractor issues --- .../Tests/Extractor/PhpStanExtractorTest.php | 4 +++- .../Tests/Fixtures/DummyUnionType.php | 13 +++++++++++++ .../PropertyInfo/Util/PhpStanTypeHelper.php | 8 ++++++++ .../Tests/Normalizer/ObjectNormalizerTest.php | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php index 8b52433a54fe..5c1bdaad7e2a 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php @@ -355,7 +355,7 @@ public function constructorTypesProvider() /** * @dataProvider unionTypesProvider */ - public function testExtractorUnionTypes(string $property, array $types) + public function testExtractorUnionTypes(string $property, ?array $types) { $this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DummyUnionType', $property)); } @@ -368,6 +368,8 @@ public function unionTypesProvider(): array ['c', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [], [new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_INT)])]], ['d', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [], [new Type(Type::BUILTIN_TYPE_STRING)])])]], ['e', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class, true, [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [], [new Type(Type::BUILTIN_TYPE_STRING)])], [new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_STRING, false, null, true, [], [new Type(Type::BUILTIN_TYPE_OBJECT, false, DefaultValue::class)])])]), new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)]], + ['f', null], + ['g', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, [], [new Type(Type::BUILTIN_TYPE_STRING), new Type(Type::BUILTIN_TYPE_INT)])]], ]; } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyUnionType.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyUnionType.php index 60af596bad3b..86ddb8a1650e 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyUnionType.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyUnionType.php @@ -16,6 +16,9 @@ */ class DummyUnionType { + private const TYPE_A = 'a'; + private const TYPE_B = 'b'; + /** * @var string|int */ @@ -40,4 +43,14 @@ class DummyUnionType * @var (Dummy, (int | (string)[])> | ParentDummy | null) */ public $e; + + /** + * @var self::TYPE_*|null + */ + public $f; + + /** + * @var non-empty-array + */ + public $g; } diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php index b5ed7bb5732e..f3812ea0f35f 100644 --- a/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php +++ b/src/Symfony/Component/PropertyInfo/Util/PhpStanTypeHelper.php @@ -19,6 +19,7 @@ use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode; use PHPStan\PhpDocParser\Ast\Type\CallableTypeParameterNode; +use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode; use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\NullableTypeNode; @@ -102,6 +103,10 @@ private function extractTypes(TypeNode $node, NameScope $nameScope): array if ($node instanceof UnionTypeNode) { $types = []; foreach ($node->types as $type) { + if ($type instanceof ConstTypeNode) { + // It's safer to fall back to other extractors here, as resolving const types correctly is not easy at the moment + return []; + } foreach ($this->extractTypes($type, $nameScope) as $subType) { $types[] = $subType; } @@ -160,7 +165,10 @@ private function extractTypes(TypeNode $node, NameScope $nameScope): array case 'integer': return [new Type(Type::BUILTIN_TYPE_INT)]; case 'list': + case 'non-empty-list': return [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT))]; + case 'non-empty-array': + return [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]; case 'mixed': return []; // mixed seems to be ignored in all other extractors case 'parent': diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 5870a657a5ab..fa9483ccf639 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; use Doctrine\Common\Annotations\AnnotationReader; +use PHPStan\PhpDocParser\Parser\PhpDocParser; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; +use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\Exception\LogicException; @@ -721,6 +723,22 @@ public function testAcceptJsonNumber() $this->assertSame(10.0, $serializer->denormalize(['number' => 10], JsonNumber::class, 'jsonld')->number); } + public function testDoesntHaveIssuesWithUnionConstTypes() + { + if (!class_exists(PhpStanExtractor::class) || !class_exists(PhpDocParser::class)) { + $this->markTestSkipped('phpstan/phpdoc-parser required for this test'); + } + + $extractor = new PropertyInfoExtractor([], [new PhpStanExtractor(), new PhpDocExtractor(), new ReflectionExtractor()]); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer([new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer]); + + $this->assertSame('bar', $serializer->denormalize(['foo' => 'bar'], \get_class(new class() { + /** @var self::*|null */ + public $foo; + }))->foo); + } + public function testExtractAttributesRespectsFormat() { $normalizer = new FormatAndContextAwareNormalizer(); 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