8000 bug #40699 [PropertyInfo] Make ReflectionExtractor correctly extract … · symfony/symfony@fab61ee · GitHub
[go: up one dir, main page]

Skip to content

Commit fab61ee

Browse files
bug #40699 [PropertyInfo] Make ReflectionExtractor correctly extract nullability (shiftby)
This PR was squashed before being merged into the 4.4 branch. Discussion ---------- [PropertyInfo] Make ReflectionExtractor correctly extract nullability | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #40659 | License | MIT | Doc PR | no When the property had a default value ReflectionExtractor was always returning isNullable: false. After PHP 7.4 we can get isNullable from the typehint. Commits ------- d5fce4c [PropertyInfo] Make ReflectionExtractor correctly extract nullability
2 parents ba38346 + d5fce4c commit fab61ee

File tree

3 files changed

+34
-16
lines changed

3 files changed

+34
-16
lines changed

src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -154,20 +154,8 @@ public function getTypes($class, $property, array $context = []): ?array
154154
return $fromConstructor;
155155
}
156156

157-
if ($fromDefaultValue = $this->extractFromDefaultValue($class, $property)) {
158-
return $fromDefaultValue;
159-
}
160-
161-
if (\PHP_VERSION_ID >= 70400) {
162-
try {
163-
$reflectionProperty = new \ReflectionProperty($class, $property);
164-
$type = $reflectionProperty->getType();
165-
if (null !== $type && $types = $this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass())) {
166-
return $types;
167-
}
168-
} catch (\ReflectionException $e) {
169-
// noop
170-
}
157+
if ($fromPropertyDeclaration = $this->extractFromPropertyDeclaration($class, $property)) {
158+
return $fromPropertyDeclaration;
171159
}
172160

173161
return null;
@@ -312,10 +300,19 @@ private function extractFromConstructor(string $class, string $property): ?array
312300
return null;
313301
}
314302

315-
private function extractFromDefaultValue(string $class, string $property): ?array
303+
private function extractFromPropertyDeclaration(string $class, string $property): ?array
316304
{
317305
try {
318306
$reflectionClass = new \ReflectionClass($class);
307+
308+
if (\PHP_VERSION_ID >= 70400) {
309+
$reflectionProperty = $reflectionClass->getProperty($property);
310+
$reflectionPropertyType = $reflectionProperty->getType();
311+
312+
if (null !== $reflectionPropertyType && $types = $this->extractFromReflectionType($reflectionPropertyType, $reflectionProperty->getDeclaringClass())) {
313+
return $types;
314+
}
315+
}
319316
} catch (\ReflectionException $e) {
320317
return null;
321318
}
@@ -328,7 +325,7 @@ private function extractFromDefaultValue(string $class, string $property): ?arra
328325

329326
$type = \gettype($defaultValue);
330327

331-
return [new Type(static::MAP_TYPES[$type] ?? $type)];
328+
return [new Type(static::MAP_TYPES[$type] ?? $type, $this->isNullableProperty($class, $property))];
332329
}
333330

334331
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionClass $declaringClass): array
@@ -368,6 +365,25 @@ private function resolveTypeName(string $name, \ReflectionClass $declaringClass)
368365
return $name;
369366
}
370367

368+
private function isNullableProperty(string $class, string $property): bool
369+
{
370+
try {
371+
$reflectionProperty = new \ReflectionProperty($class, $property);
372+
373+
if (\PHP_VERSION_ID >= 70400) {
374+
$reflectionPropertyType = $reflectionProperty->getType();
375+
376+
return null !== $reflectionPropertyType && $reflectionPropertyType->allowsNull();
377+
}
378+
379+
return false;
380+
} catch (\ReflectionException $e) {
381+
// Return false if the property doesn't exist
382+
}
383+
384+
return false;
385+
}
386+
371387
private function isAllowedProperty(string $class, string $property): bool
372388
{
373389
try {

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,5 +414,6 @@ public function testTypedProperties()
414414
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], $this->extractor->getTypes(Php74Dummy::class, 'dummy'));
415415
$this->assertEquals([new Type(Type::BUILTIN_TYPE_BOOL, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableBoolProp'));
416416
$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'));
417+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_INT, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableWithDefault'));
417418
}
418419
}

src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class Php74Dummy
2020
private ?bool $nullableBoolProp;
2121
/** @var string[] */
2222
private array $stringCollection;
23+
private ?int $nullableWithDefault = 1;
2324

2425
public function addStringCollection(string $string): void
2526
{

0 commit comments

Comments
 (0)
0