From 4baeb0c12fe6a5de6d443dc25c3f38a70eb28f0d Mon Sep 17 00:00:00 2001 From: tsantos Date: Sun, 2 Jun 2019 16:22:14 -0300 Subject: [PATCH 01/15] [PropertyInfo] Extract type from property declaration --- .../Extractor/ReflectionExtractor.php | 33 +++++++++++++++++++ .../Extractor/ReflectionExtractorTest.php | 25 ++++++++++++++ .../Tests/Fixtures/Php74Dummy.php | 16 +++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 83f14acb70760..04b5a193aa6ca 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -109,6 +109,10 @@ public function getProperties($class, array $context = []) */ public function getTypes($class, $property, array $context = []) { + if ($fromDeclared = $this->extractFromDeclaredType($class, $property)) { + return $fromDeclared; + } + if ($fromMutator = $this->extractFromMutator($class, $property)) { return $fromMutator; } @@ -185,6 +189,35 @@ public function isInitializable(string $class, string $property, array $context return false; } + private function extractFromDeclaredType(string $class, string $property) + { + // to be removed as soon as Symfony bumps the minimum PHP Version to 7.4 + if (version_compare(PHP_VERSION, '7.4.0-dev', '<')) { + return null; + } + + try { + $reflectionClass = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + return null; + } + + $reflectionProperty = $reflectionClass->getProperty($property); + + if (!$reflectionProperty->hasType()) { + return null; + } + + $reflectionType = $reflectionProperty->getType(); + $type = $reflectionType->getName(); + + if ($reflectionType->isBuiltIn()) { + return [new Type(static::MAP_TYPES[$type] ?? $type, $reflectionType->allowsNull())]; + } + + return [new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionType->allowsNull(), $type)]; + } + /** * @return Type[]|null */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 7472d6ef21b00..cca2142757e70 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -15,9 +15,11 @@ use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\NotInstantiable; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy; use Symfony\Component\PropertyInfo\Type; /** @@ -228,6 +230,29 @@ public function defaultValueProvider() ]; } + /** + * @dataProvider declaredTypeProvider + */ + public function testExtractFromDeclaredType($property, $type) + { + if (version_compare(PHP_VERSION, '7.4.0-dev', '<')) { + $this->markTestSkipped('Extracting type from declared type is enabled only on PHP 7.4+'); + } + + $this->assertEquals($type, $this->extractor->getTypes(Php74Dummy::class, $property, [])); + } + + public function declaredTypeProvider() + { + return [ + ['int', [new Type(Type::BUILTIN_TYPE_INT, false)]], + ['string', [new Type(Type::BUILTIN_TYPE_STRING, true)]], + ['dummy', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]], + ['optionalDummy', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], + ['callable', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], + ]; + } + /** * @dataProvider getReadableProperties */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php new file mode 100644 index 0000000000000..afdc5e0728b59 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php @@ -0,0 +1,16 @@ + + */ +class Php74Dummy +{ + public int $int; + public ?string $string; + public Dummy $dummy; + public ?Dummy $optionalDummy; +} From e903eeb7a8d1f596aeee375613ca2537cf92ca64 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sun, 2 Jun 2019 16:22:53 -0300 Subject: [PATCH 02/15] [PropertyInfo] Add PHP 7.4-dev to travisci --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b279eac0215a8..d20a9be048d2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,7 @@ matrix: env: deps=high - php: 7.3 env: deps=low + - php: 7.4snapshot fast_finish: true From e71852d83159b710d6e130d6efcfacf5014dc691 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sun, 2 Jun 2019 16:24:47 -0300 Subject: [PATCH 03/15] [PropertyInfo] Change log note --- src/Symfony/Component/PropertyInfo/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/PropertyInfo/CHANGELOG.md b/src/Symfony/Component/PropertyInfo/CHANGELOG.md index 9db346c21787f..f965429df9631 100644 --- a/src/Symfony/Component/PropertyInfo/CHANGELOG.md +++ b/src/Symfony/Component/PropertyInfo/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.4.0 +----- + +* Added the ability to extract property type from the property declaration + 4.3.0 ----- From 550c4d24c4e1e803a18c2d26472382f353020392 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sun, 2 Jun 2019 16:59:43 -0300 Subject: [PATCH 04/15] [PropertyInfo] Change variable name --- .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 04b5a193aa6ca..c7f61001bbafe 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -109,8 +109,8 @@ public function getProperties($class, array $context = []) */ public function getTypes($class, $property, array $context = []) { - if ($fromDeclared = $this->extractFromDeclaredType($class, $property)) { - return $fromDeclared; + if ($fromDeclaredType = $this->extractFromDeclaredType($class, $property)) { + return $fromDeclaredType; } if ($fromMutator = $this->extractFromMutator($class, $property)) { From afaea213ff86b7a3a6ae6b6e86bfbd2d54fd04c4 Mon Sep 17 00:00:00 2001 From: tsantos Date: Thu, 6 Jun 2019 22:24:05 -0300 Subject: [PATCH 05/15] [PropertyInfo] Remove callable from tests --- .../PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index cca2142757e70..ddaf5b9cffbd6 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -249,7 +249,6 @@ public function declaredTypeProvider() ['string', [new Type(Type::BUILTIN_TYPE_STRING, true)]], ['dummy', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]], ['optionalDummy', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], - ['callable', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], ]; } From d11d8f0936a20386497dfb99b80836833c96abcc Mon Sep 17 00:00:00 2001 From: tsantos Date: Thu, 6 Jun 2019 22:29:14 -0300 Subject: [PATCH 06/15] [PropertyInfo] Add copyright text --- .../Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php index afdc5e0728b59..9218dac02e640 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php @@ -1,5 +1,14 @@ + * + * 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; /** From f2b5c1af61e796cb01f72ea41b1d15fb0848243c Mon Sep 17 00:00:00 2001 From: tsantos Date: Thu, 6 Jun 2019 22:32:17 -0300 Subject: [PATCH 07/15] [PropertyInfo] Add test case for iterable type --- .../PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php | 1 + src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index ddaf5b9cffbd6..4fe14a76297b4 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -249,6 +249,7 @@ public function declaredTypeProvider() ['string', [new Type(Type::BUILTIN_TYPE_STRING, true)]], ['dummy', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]], ['optionalDummy', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], + ['iterable', [new Type(Type::BUILTIN_TYPE_ITERABLE, false)]], ]; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php index 9218dac02e640..185c4b33eba4b 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php @@ -22,4 +22,5 @@ class Php74Dummy public ?string $string; public Dummy $dummy; public ?Dummy $optionalDummy; + public iterable $iterable; } From 72ee4012ef412f0d146e348831e17f91a833a5e3 Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 07:51:28 -0300 Subject: [PATCH 08/15] [PropertyInfo] Add `self` and `parent` type --- .../Extractor/ReflectionExtractor.php | 31 ++++++++++--------- .../Extractor/ReflectionExtractorTest.php | 3 ++ .../Tests/Fixtures/Php74Dummy.php | 4 ++- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index c7f61001bbafe..a1592d9ebb9d9 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -209,13 +209,8 @@ private function extractFromDeclaredType(string $class, string $property) } $reflectionType = $reflectionProperty->getType(); - $type = $reflectionType->getName(); - if ($reflectionType->isBuiltIn()) { - return [new Type(static::MAP_TYPES[$type] ?? $type, $reflectionType->allowsNull())]; - } - - return [new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionType->allowsNull(), $type)]; + return [$this->extractFromReflectionType($reflectionType, null, $reflectionProperty)]; } /** @@ -234,7 +229,7 @@ private function extractFromMutator(string $class, string $property): ?array if (!$reflectionType = $reflectionParameter->getType()) { return null; } - $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod); + $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod, null); if (\in_array($prefix, $this->arrayMutatorPrefixes)) { $type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type); @@ -256,7 +251,7 @@ private function extractFromAccessor(string $class, string $property): ?array } if ($reflectionType = $reflectionMethod->getReturnType()) { - return [$this->extractFromReflectionType($reflectionType, $reflectionMethod)]; + return [$this->extractFromReflectionType($reflectionType, $reflectionMethod, null)]; } if (\in_array($prefix, ['is', 'can', 'has'])) { @@ -291,7 +286,7 @@ private function extractFromConstructor(string $class, string $property): ?array } $reflectionType = $parameter->getType(); - return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor)] : null; + return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor, null)] : null; } if ($parentClass = $reflectionClass->getParentClass()) { @@ -320,7 +315,7 @@ private function extractFromDefaultValue(string $class, string $property) return [new Type(static::MAP_TYPES[$type] ?? $type)]; } - private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod): Type + private function extractFromReflectionType(\ReflectionType $reflectionType, ?\ReflectionMethod $reflectionMethod, ?\ReflectionProperty $reflectionProperty): Type { $phpTypeOrClass = $reflectionType->getName(); $nullable = $reflectionType->allowsNull(); @@ -331,19 +326,27 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, \Ref $type = new Type(Type::BUILTIN_TYPE_NULL, $nullable); } elseif ($reflectionType->isBuiltin()) { $type = new Type($phpTypeOrClass, $nullable); + } elseif (null !== $reflectionMethod) { + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod, null)); + } elseif (null !== $reflectionProperty) { + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, null, $reflectionProperty)); } else { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod)); + throw new \BadMethodCallException('You should provide method or property reflection'); } return $type; } - private function resolveTypeName(string $name, \ReflectionMethod $reflectionMethod): string + private function resolveTypeName(string $name, ?\ReflectionMethod $reflectionMethod, ?\ReflectionProperty $reflectionProperty): string { + if (null === ($reflection = $reflectionMethod ?? $reflectionProperty)) { + throw new \BadMethodCallException('You should provide method or property reflection'); + } + if ('self' === $lcName = strtolower($name)) { - return $reflectionMethod->getDeclaringClass()->name; + return $reflection->getDeclaringClass()->name; } - if ('parent' === $lcName && $parent = $reflectionMethod->getDeclaringClass()->getParentClass()) { + if ('parent' === $lcName && $parent = $reflection->getDeclaringClass()->getParentClass()) { return $parent->name; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 4fe14a76297b4..d534831125aec 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -17,6 +17,7 @@ use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue; use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\NotInstantiable; +use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy; @@ -250,6 +251,8 @@ public function declaredTypeProvider() ['dummy', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]], ['optionalDummy', [new Type(Type::BUILTIN_TYPE_OBJECT, true, Dummy::class)]], ['iterable', [new Type(Type::BUILTIN_TYPE_ITERABLE, false)]], + ['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Php74Dummy::class)]], + ['parent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)]], ]; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php index 185c4b33eba4b..3aa187e4d39f1 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php74Dummy.php @@ -16,11 +16,13 @@ * * @author Tales Santos */ -class Php74Dummy +class Php74Dummy extends ParentDummy { public int $int; public ?string $string; public Dummy $dummy; + public parent $parent; + public self $self; public ?Dummy $optionalDummy; public iterable $iterable; } From 2a273c11bf03dca98d09557dd741710d057df834 Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 07:52:48 -0300 Subject: [PATCH 09/15] [PropertyInfo] Prevent exception in case the property doesn't exist --- .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index a1592d9ebb9d9..7bff2b77d33f0 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -198,11 +198,11 @@ private function extractFromDeclaredType(string $class, string $property) try { $reflectionClass = new \ReflectionClass($class); + $reflectionProperty = $reflectionClass->getProperty($property); } catch (\ReflectionException $e) { return null; } - $reflectionProperty = $reflectionClass->getProperty($property); if (!$reflectionProperty->hasType()) { return null; From 4e5bfe14790568cd25f4dddd4f8c9e0bdfe0da2f Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 07:58:02 -0300 Subject: [PATCH 10/15] [PropertyInfo] Fix code standard --- .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 7bff2b77d33f0..9249977e585b4 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -203,7 +203,6 @@ private function extractFromDeclaredType(string $class, string $property) return null; } - if (!$reflectionProperty->hasType()) { return null; } From 2f8b2fed7000ce085740e5b517895012dcfef8d3 Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 09:34:49 -0300 Subject: [PATCH 11/15] [PropertyInfo] Fix PHP version comparison --- .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 9249977e585b4..f61fe69fbb1e2 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -191,8 +191,7 @@ public function isInitializable(string $class, string $property, array $context private function extractFromDeclaredType(string $class, string $property) { - // to be removed as soon as Symfony bumps the minimum PHP Version to 7.4 - if (version_compare(PHP_VERSION, '7.4.0-dev', '<')) { + if (version_compare(PHP_VERSION_ID, 70400, '<')) { return null; } From 7f1095d2665d908a8124baf576898469c23d8bf7 Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 09:51:27 -0300 Subject: [PATCH 12/15] [PropertyInfo] Unifying $reflector argument to keep code cleaner --- .../Extractor/ReflectionExtractor.php | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index f61fe69fbb1e2..a73e4c4186814 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -208,7 +208,7 @@ private function extractFromDeclaredType(string $class, string $property) $reflectionType = $reflectionProperty->getType(); - return [$this->extractFromReflectionType($reflectionType, null, $reflectionProperty)]; + return [$this->extractFromReflectionType($reflectionType, $reflectionProperty)]; } /** @@ -227,7 +227,7 @@ private function extractFromMutator(string $class, string $property): ?array if (!$reflectionType = $reflectionParameter->getType()) { return null; } - $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod, null); + $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod); if (\in_array($prefix, $this->arrayMutatorPrefixes)) { $type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type); @@ -249,7 +249,7 @@ private function extractFromAccessor(string $class, string $property): ?array } if ($reflectionType = $reflectionMethod->getReturnType()) { - return [$this->extractFromReflectionType($reflectionType, $reflectionMethod, null)]; + return [$this->extractFromReflectionType($reflectionType, $reflectionMethod)]; } if (\in_array($prefix, ['is', 'can', 'has'])) { @@ -284,7 +284,7 @@ private function extractFromConstructor(string $class, string $property): ?array } $reflectionType = $parameter->getType(); - return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor, null)] : null; + return $reflectionType ? [$this->extractFromReflectionType($reflectionType, $constructor)] : null; } if ($parentClass = $reflectionClass->getParentClass()) { @@ -313,7 +313,12 @@ private function extractFromDefaultValue(string $class, string $property) return [new Type(static::MAP_TYPES[$type] ?? $type)]; } - private function extractFromReflectionType(\ReflectionType $reflectionType, ?\ReflectionMethod $reflectionMethod, ?\ReflectionProperty $reflectionProperty): Type + /** + * @param \ReflectionType $reflectionType + * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * @return Type + */ + private function extractFromReflectionType(\ReflectionType $reflectionType, object $reflector): Type { $phpTypeOrClass = $reflectionType->getName(); $nullable = $reflectionType->allowsNull(); @@ -324,27 +329,36 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, ?\Re $type = new Type(Type::BUILTIN_TYPE_NULL, $nullable); } elseif ($reflectionType->isBuiltin()) { $type = new Type($phpTypeOrClass, $nullable); - } elseif (null !== $reflectionMethod) { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod, null)); - } elseif (null !== $reflectionProperty) { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, null, $reflectionProperty)); - } else { - throw new \BadMethodCallException('You should provide method or property reflection'); + } elseif ($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty) { + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflector)); + } else { + throw new \BadMethodCallException( + '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' + . get_class($reflector) . ' given' + ); } return $type; } - private function resolveTypeName(string $name, ?\ReflectionMethod $reflectionMethod, ?\ReflectionProperty $reflectionProperty): string + /** + * @param string $name + * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * @return string + */ + private function resolveTypeName(string $name, object $reflector): string { - if (null === ($reflection = $reflectionMethod ?? $reflectionProperty)) { - throw new \BadMethodCallException('You should provide method or property reflection'); + if (!($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty)) { + throw new \BadMethodCallException( + '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' + . get_class($reflector) . ' given' + ); } if ('self' === $lcName = strtolower($name)) { - return $reflection->getDeclaringClass()->name; + return $reflector->getDeclaringClass()->name; } - if ('parent' === $lcName && $parent = $reflection->getDeclaringClass()->getParentClass()) { + if ('parent' === $lcName && $parent = $reflector->getDeclaringClass()->getParentClass()) { return $parent->name; } From 92e8be6ced92d4562ef1c5f4e2ba8732cf24e01a Mon Sep 17 00:00:00 2001 From: tsantos Date: Fri, 7 Jun 2019 09:53:04 -0300 Subject: [PATCH 13/15] [PropertyInfo] Fix code standard --- .../PropertyInfo/Extractor/ReflectionExtractor.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index a73e4c4186814..ed87e37944ecb 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -191,7 +191,7 @@ public function isInitializable(string $class, string $property, array $context private function extractFromDeclaredType(string $class, string $property) { - if (version_compare(PHP_VERSION_ID, 70400, '<')) { + if (version_compare(\PHP_VERSION_ID, 70400, '<')) { return null; } @@ -314,8 +314,9 @@ private function extractFromDefaultValue(string $class, string $property) } /** - * @param \ReflectionType $reflectionType + * @param \ReflectionType $reflectionType * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * * @return Type */ private function extractFromReflectionType(\ReflectionType $reflectionType, object $reflector): Type @@ -331,10 +332,10 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, obje $type = new Type($phpTypeOrClass, $nullable); } elseif ($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty) { $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflector)); - } else { + } else { throw new \BadMethodCallException( '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' - . get_class($reflector) . ' given' + .\get_class($reflector).' given' ); } @@ -342,8 +343,9 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, obje } /** - * @param string $name + * @param string $name * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * * @return string */ private function resolveTypeName(string $name, object $reflector): string @@ -351,7 +353,7 @@ private function resolveTypeName(string $name, object $reflector): string if (!($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty)) { throw new \BadMethodCallException( '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' - . get_class($reflector) . ' given' + .\get_class($reflector).' given' ); } From d6c3e5a0d70b7fb1858dcd01047f0f784c8b24b4 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sat, 8 Jun 2019 20:09:29 -0300 Subject: [PATCH 14/15] [PropertyInfo] Remove typehint for $resolver argument --- .../PropertyInfo/Extractor/ReflectionExtractor.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index ed87e37944ecb..a76c486bfb93a 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -315,11 +315,11 @@ private function extractFromDefaultValue(string $class, string $property) /** * @param \ReflectionType $reflectionType - * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * @param \ReflectionMethod|\ReflectionProperty $reflector * * @return Type */ - private function extractFromReflectionType(\ReflectionType $reflectionType, object $reflector): Type + private function extractFromReflectionType(\ReflectionType $reflectionType, $reflector): Type { $phpTypeOrClass = $reflectionType->getName(); $nullable = $reflectionType->allowsNull(); @@ -344,11 +344,11 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, obje /** * @param string $name - * @param object|\ReflectionMethod|\ReflectionProperty $reflector + * @param \ReflectionMethod|\ReflectionProperty $reflector * * @return string */ - private function resolveTypeName(string $name, object $reflector): string + private function resolveTypeName(string $name, $reflector): string { if (!($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty)) { throw new \BadMethodCallException( From bc8d70cfa744cd625306f50ad2d7dfeeec86fe13 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sat, 8 Jun 2019 22:00:53 -0300 Subject: [PATCH 15/15] [PropertyInfo] Change exception --- .../PropertyInfo/Extractor/ReflectionExtractor.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index a76c486bfb93a..88adb8ecf1862 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -314,7 +314,7 @@ private function extractFromDefaultValue(string $class, string $property) } /** - * @param \ReflectionType $reflectionType + * @param \ReflectionType $reflectionType * @param \ReflectionMethod|\ReflectionProperty $reflector * * @return Type @@ -333,9 +333,9 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, $ref } elseif ($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty) { $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflector)); } else { - throw new \BadMethodCallException( + throw new \InvalidArgumentException( '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' - .\get_class($reflector).' given' + .(\is_object($reflector) ? \get_class($reflector) : \gettype($reflector)).' given' ); } @@ -343,7 +343,7 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, $ref } /** - * @param string $name + * @param string $name * @param \ReflectionMethod|\ReflectionProperty $reflector * * @return string @@ -351,9 +351,9 @@ private function extractFromReflectionType(\ReflectionType $reflectionType, $ref private function resolveTypeName(string $name, $reflector): string { if (!($reflector instanceof \ReflectionMethod || $reflector instanceof \ReflectionProperty)) { - throw new \BadMethodCallException( + throw new \InvalidArgumentException( '$reflector should be an instance of ReflectionMethod or ReflectionProperty, ' - .\get_class($reflector).' given' + .(\is_object($reflector) ? \get_class($reflector) : \gettype($reflector)).' given' ); }