feature #27570 [PropertyInfo] Added support for extract type from default value (tsantos84)

This PR was squashed before being merged into the 4.3-dev branch (closes #27570).

Discussion
----------

[PropertyInfo] Added support for extract type from default value

| Q             | A
| ------------- | ---
| Branch?       | master |
| Bug fix?      | no
| New feature?  | yes |
| BC breaks?    | no   |
| Deprecations? | no |
| Tests pass?   | yes |
| Fixed tickets | - |
| License       | MIT |
| Doc PR        | - |

Added support for extract type from property's default value.

```php

class Dummy
{
    private $age = 30;
}

$types = $propertyInfo->getTypes('Dummy', 'age');

/*
  Example Result
  --------------
  array(1) {
    [0] =>
    class Symfony\Component\PropertyInfo\Type (6) {
      private $builtinType          => string(3) "int"
      private $nullable             => bool(false)
      private $class                => 'Dummy'
      private $collection           => bool(false)
      private $collectionKeyType    => NULL
      private $collectionValueType  => NULL
    }
  }
*/
```

Commits
-------

f6510cda40 [PropertyInfo] Added support for extract type from default value
This commit is contained in:
Fabien Potencier 2019-02-21 11:10:14 +01:00
commit 5a3e894203
4 changed files with 80 additions and 0 deletions

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
4.3.0
-----
* Added the ability to extract property type based on its initial value
4.2.0
-----

View File

@ -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();

View File

@ -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
*/

View File

@ -0,0 +1,26 @@
<?php
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <tales.augusto.santos@gmail.com>
*/
class DefaultValue
{
public $defaultInt = 30;
public $defaultFloat = 30.5;
public $defaultString = 'foo';
public $defaultArray = [];
public $defaultNull = null;
}