From d5fce4c77903aa843fb3dac6956853555a979319 Mon Sep 17 00:00:00 2001 From: Maxim Dovydenok Date: Sat, 3 Apr 2021 16:47:18 +0300 Subject: [PATCH] [PropertyInfo] Make ReflectionExtractor correctly extract nullability --- .../Extractor/ReflectionExtractor.php | 48 ++++++++++++------- .../Extractor/ReflectionExtractorTest.php | 1 + .../Tests/Fixtures/Php74Dummy.php | 1 + 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index c0f59cea9acf3..ebe9d070322e0 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -154,20 +154,8 @@ public function getTypes($class, $property, array $context = []): ?array return $fromConstructor; } - if ($fromDefaultValue = $this->extractFromDefaultValue($class, $property)) { - return $fromDefaultValue; - } - - if (\PHP_VERSION_ID >= 70400) { - try { - $reflectionProperty = new \ReflectionProperty($class, $property); - $type = $reflectionProperty->getType(); - if (null !== $type && $types = $this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass())) { - return $types; - } - } catch (\ReflectionException $e) { - // noop - } + if ($fromPropertyDeclaration = $this->extractFromPropertyDeclaration($class, $property)) { + return $fromPropertyDeclaration; } return null; @@ -312,10 +300,19 @@ private function extractFromConstructor(string $class, string $property): ?array return null; } - private function extractFromDefaultValue(string $class, string $property): ?array + private function extractFromPropertyDeclaration(string $class, string $property): ?array { try { $reflectionClass = new \ReflectionClass($class); + + if (\PHP_VERSION_ID >= 70400) { + $reflectionProperty = $reflectionClass->getProperty($property); + $reflectionPropertyType = $reflectionProperty->getType(); + + if (null !== $reflectionPropertyType && $types = $this->extractFromReflectionType($reflectionPropertyType, $reflectionProperty->getDeclaringClass())) { + return $types; + } + } } catch (\ReflectionException $e) { return null; } @@ -328,7 +325,7 @@ private function extractFromDefaultValue(string $class, string $property): ?arra $type = \gettype($defaultValue); - return [new Type(static::MAP_TYPES[$type] ?? $type)]; + return [new Type(static::MAP_TYPES[$type] ?? $type, $this->isNullableProperty($class, $property))]; } private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionClass $declaringClass): array @@ -368,6 +365,25 @@ private function resolveTypeName(string $name, \ReflectionClass $declaringClass) return $name; } + private function isNullableProperty(string $class, string $property): bool + { + try { + $reflectionProperty = new \ReflectionProperty($class, $property); + + if (\PHP_VERSION_ID >= 70400) { + $reflectionPropertyType = $reflectionProperty->getType(); + + return null !== $reflectionPropertyType && $reflectionPropertyType->allowsNull(); + } + + return false; + } catch (\ReflectionException $e) { + // Return false if the property doesn't exist + } + + return false; + } + private function isAllowedProperty(string $class, string $property): bool { try { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 18f8d4d018f02..60b4efdbcf815 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -414,5 +414,6 @@ public function testTypedProperties() $this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], $this->extractor->getTypes(Php74Dummy::class, 'dummy')); $this->assertEquals([new Type(Type::BUILTIN_TYPE_BOOL, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableBoolProp')); $this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))], $this->extractor->getTypes(Php74Dummy::class, 'stringCollection')); + $this->assertEquals([new Type(Type::BUILTIN_TYPE_INT, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableWithDefault')); } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php index ffc4f4cd37621..405043252a7de 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php @@ -20,6 +20,7 @@ class Php74Dummy private ?bool $nullableBoolProp; /** @var string[] */ private array $stringCollection; + private ?int $nullableWithDefault = 1; public function addStringCollection(string $string): void { 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