8000 feature #34557 [PropertyInfo] Add support for typed properties (PHP 7… · symfony/symfony@3888312 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3888312

Browse files
committed
feature #34557 [PropertyInfo] Add support for typed properties (PHP 7.4) (dunglas)
This PR was squashed before being merged into the 5.1-dev branch (closes #34557). Discussion ---------- [PropertyInfo] Add support for typed properties (PHP 7.4) | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | n/a <!-- prefix each issue number with "Fix #", if any --> | License | MIT | Doc PR | n/a Add support for [typed properties](https://wiki.php.net/rfc/typed_properties_v2), a new feature introduced in PHP 7.4: ```php class Foo { public Bar $bar; private ?bool $nullableBoolProp; } $this->extractor->getTypes(Foo::class, 'bar'); // Type[] $this->extractor->getTypes(Foo::class, 'nullableBoolProp'); // Type[] ``` #SymfonyHackday Commits ------- 7edfe4f [PropertyInfo] Add support for typed properties (PHP 7.4)
2 parents adbc1df + 7edfe4f commit 3888312

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ public function getProperties(string $class, array $context = []): ?array
133133
*/
134134
public function getTypes(string $class, string $property, array $context = []): ?array
135135
{
136+
if (\PHP_VERSION_ID >= 70400) {
137+
try {
138+
$reflectionProperty = new \ReflectionProperty($class, $property);
139+
$type = $reflectionProperty->getType();
140+
if (null !== $type) {
141+
return [$this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass())];
142+
}
143+
} catch (\ReflectionException $e) {
144+
// noop
145+
}
146+
}
147+
136148
if ($fromMutator = $this->extractFromMutator($class, $property)) {
137149
return $fromMutator;
138150
}
@@ -227,7 +239,7 @@ private function extractFromMutator(string $class, string $property): ?array
227239
if (!$reflectionType = $reflectionParameter->getType()) {
228240
return null;
229241
}
230-
$type = $this->extractFromReflectionType($reflectionType, $reflectionMethod);
242+
$type = $this->extractFromReflectionType($reflectionType, $reflectionMethod->getDeclaringClass());
231243

232244
if (\in_array($prefix, $this->arrayMutatorPrefixes)) {
233245
$type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type);
@@ -249,7 +261,7 @@ private function extractFromAccessor(string $class, string $property): ?array
249261
}
250262

251263
if ($reflectionType = $reflectionMethod->getReturnType()) {
252-
return [$this->extractFromReflectionType($reflectionType, $reflectionMethod)];
264+
return [$this->extractFromReflectionType($reflectionType, $reflectionMethod->getDeclaringClass())];
253265
}
254266

255267
if (\in_array($prefix, ['is', 'can', 'has'])) {
@@ -284,7 +296,7 @@ private function extractFromConstructor(string $class, string $property): ?array
284296
}
285297
$reflectionType = $parameter->getType();
286298

287-
return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor)] : null;
299+
return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor->getDeclaringClass())] : null;
288300
}
289301

290302
if ($parentClass = $reflectionClass->getParentClass()) {
@@ -313,7 +325,7 @@ private function extractFromDefaultValue(string $class, string $property): ?arra
313325
return [new Type(static::MAP_TYPES[$type] ?? $type)];
314326
}
315327

316-
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod): Type
328+
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionClass $declaringClass): Type
317329
{
318330
$phpTypeOrClass = $reflectionType->getName();
319331
$nullable = $reflectionType->allowsNull();
@@ -325,18 +337,18 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, \Ref
325337
} elseif ($reflectionType->isBuiltin()) {
326338
$type = new Type($phpTypeOrClass, $nullable);
327339
} else {
328-
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));
340+
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $declaringClass));
329341
}
330342

331343
return $type;
332344
}
333345

334-
private function resolveTypeName(string $name, \ReflectionMethod $reflectionMethod): string
346+
private function resolveTypeName(string $name, \ReflectionClass $declaringClass): string
335347
{
336348
if ('self' === $lcName = strtolower($name)) {
337-
return $reflectionMethod->getDeclaringClass()->name;
349+
return $declaringClass->name;
338350
}
339-
if ('parent' === $lcName && $parent = $reflectionMethod->getDeclaringClass()->getParentClass()) {
351+
if ('parent' === $lcName && $parent = $declaringClass->getParentClass()) {
340352
return $parent->name;
341353
}
342354

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\PropertyInfo\Tests\Fixtures\NotInstantiable;
2020
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy;
2121
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2;
22+
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy;
2223
use Symfony\Component\PropertyInfo\Type;
2324

2425
/**
@@ -365,4 +366,13 @@ public function constructorTypesProvider(): array
365366
[DefaultValue::class, 'foo', null],
366367
];
367368
}
369+
370+
/**
371+
* @requires PHP 7.4
372+
*/
373+
public function testTypedProperties(): void
374+
{
375+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], $this->extractor->getTypes(Php74Dummy::class, 'dummy'));
376+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_BOOL, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableBoolProp'));
377+
}
368378
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
13+
14+
/**
15+
* @author Kévin Dunglas <dunglas@gmail.com>
16+
*/
17+
class Php74Dummy
18+
{
19+
public Dummy $dummy;
20+
private ?bool $nullableBoolProp;
21+
}

0 commit comments

Comments
 (0)
0