From f6510cda40193e9e586ca5c801594a286e3854f7 Mon Sep 17 00:00:00 2001 From: tsantos Date: Sat, 9 Jun 2018 20:32:40 -0300 Subject: [PATCH] [PropertyInfo] Added support for extract type from default value --- .../Component/PropertyInfo/CHANGELOG.md | 5 ++++ .../Extractor/ReflectionExtractor.php | 29 +++++++++++++++++++ .../Extractor/ReflectionExtractorTest.php | 20 +++++++++++++ .../Tests/Fixtures/DefaultValue.php | 26 +++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/DefaultValue.php diff --git a/src/Symfony/Component/PropertyInfo/CHANGELOG.md b/src/Symfony/Component/PropertyInfo/CHANGELOG.md index a81f3124a6..9db346c217 100644 --- a/src/Symfony/Component/PropertyInfo/CHANGELOG.md +++ b/src/Symfony/Component/PropertyInfo/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + +* Added the ability to extract property type based on its initial value + 4.2.0 ----- diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 0ed1e4e2af..83f14acb70 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -42,6 +42,12 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp */ public static $defaultArrayMutatorPrefixes = ['add', 'remove']; + private const MAP_TYPES = [ + 'integer' => Type::BUILTIN_TYPE_INT, + 'boolean' => Type::BUILTIN_TYPE_BOOL, + 'double' => Type::BUILTIN_TYPE_FLOAT, + ]; + private $mutatorPrefixes; private $accessorPrefixes; private $arrayMutatorPrefixes; @@ -117,6 +123,10 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp ) { return $fromConstructor; } + + if ($fromDefaultValue = $this->extractFromDefaultValue($class, $property)) { + return $fromDefaultValue; + } } /** @@ -258,6 +268,25 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp return null; } + private function extractFromDefaultValue(string $class, string $property) + { + try { + $reflectionClass = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + return null; + } + + $defaultValue = $reflectionClass->getDefaultProperties()[$property] ?? null; + + if (null === $defaultValue) { + return null; + } + + $type = \gettype($defaultValue); + + return [new Type(static::MAP_TYPES[$type] ?? $type)]; + } + private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod): Type { $phpTypeOrClass = $reflectionType->getName(); diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index e58c70d41d..7472d6ef21 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -14,6 +14,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Extractor; use PHPUnit\Framework\TestCase; 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\NotInstantiable; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2; @@ -208,6 +209,25 @@ class ReflectionExtractorTest extends TestCase ]; } + /** + * @dataProvider defaultValueProvider + */ + public function testExtractWithDefaultValue($property, $type) + { + $this->assertEquals($type, $this->extractor->getTypes(DefaultValue::class, $property, [])); + } + + public function defaultValueProvider() + { + return [ + ['defaultInt', [new Type(Type::BUILTIN_TYPE_INT, false)]], + ['defaultFloat', [new Type(Type::BUILTIN_TYPE_FLOAT, false)]], + ['defaultString', [new Type(Type::BUILTIN_TYPE_STRING, false)]], + ['defaultArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false)]], + ['defaultNull', null], + ]; + } + /** * @dataProvider getReadableProperties */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DefaultValue.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DefaultValue.php new file mode 100644 index 0000000000..f7a718e5c7 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DefaultValue.php @@ -0,0 +1,26 @@ + + * + * 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; + +/** + * @author Tales Santos + */ +class DefaultValue +{ + public $defaultInt = 30; + public $defaultFloat = 30.5; + public $defaultString = 'foo'; + public $defaultArray = []; + public $defaultNull = null; +}