Skip to content

Commit

Permalink
feature #27570 [PropertyInfo] Added support for extract type from def…
Browse files Browse the repository at this point in the history
…ault 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
-------

f6510cd [PropertyInfo] Added support for extract type from default value
  • Loading branch information
fabpot committed Feb 21, 2019
2 parents 4e1ad10 + f6510cd commit 5a3e894
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 0 deletions.
5 changes: 5 additions & 0 deletions 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
-----

Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -117,6 +123,10 @@ public function getTypes($class, $property, array $context = [])
) {
return $fromConstructor;
}

if ($fromDefaultValue = $this->extractFromDefaultValue($class, $property)) {
return $fromDefaultValue;
}
}

/**
Expand Down Expand Up @@ -258,6 +268,25 @@ private function extractFromConstructor(string $class, string $property): ?array
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();
Expand Down
Expand Up @@ -14,6 +14,7 @@
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;
Expand Down Expand Up @@ -208,6 +209,25 @@ public function php71TypesProvider()
];
}

/**
* @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
*/
Expand Down
26 changes: 26 additions & 0 deletions src/Symfony/Component/PropertyInfo/Tests/Fixtures/DefaultValue.php
@@ -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;
}

0 comments on commit 5a3e894

Please sign in to comment.