Skip to content

Commit

Permalink
convert legacy types to TypeInfo types if getType() is not implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Jun 19, 2024
1 parent 7abc106 commit 16f5b89
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\PropertyInfo;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\PropertyInfo\Util\LegacyTypeConverter;
use Symfony\Component\TypeInfo\Type;

/**
Expand Down Expand Up @@ -61,7 +62,37 @@ public function getProperties(string $class, array $context = []): ?array
*/
public function getType(string $class, string $property, array $context = []): ?Type
{
return $this->extract('getType', [$class, $property, $context]);
try {
$serializedArguments = serialize([$class, $property, $context]);
} catch (\Exception) {
// If arguments are not serializable, skip the cache
return $this->propertyInfoExtractor->{$method}(...$arguments);
}

// Calling rawurlencode escapes special characters not allowed in PSR-6's keys
$key = rawurlencode('getType.'.$serializedArguments);

if (\array_key_exists($key, $this->arrayCache)) {
return $this->arrayCache[$key];
}

$item = $this->cacheItemPool->getItem($key);

if ($item->isHit()) {
return $this->arrayCache[$key] = $item->get();
}

if (method_exists($this->propertyInfoExtractor, 'getType')) {
$value = $this->propertyInfoExtractor->getType($class, $property, $context);
} else {
$legacyTypes = $this->propertyInfoExtractor->getTypes($class, $property, $context);
$value = LegacyTypeConverter::toTypeInfoType($legacyTypes);
}

$item->set($value);
$this->cacheItemPool->save($item);

return $this->arrayCache[$key] = $value;
}

public function getTypes(string $class, string $property, array $context = []): ?array
Expand Down
19 changes: 18 additions & 1 deletion src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\PropertyInfo;

use Symfony\Component\PropertyInfo\Util\LegacyTypeConverter;
use Symfony\Component\TypeInfo\Type;

/**
Expand Down Expand Up @@ -58,7 +59,23 @@ public function getLongDescription(string $class, string $property, array $conte
*/
public function getType(string $class, string $property, array $context = []): ?Type
{
return $this->extract($this->typeExtractors, 'getType', [$class, $property, $context]);
foreach ($this->typeExtractors as $extractor) {
if (!method_exists($extractor, 'getType')) {
$legacyTypes = $extractor->getTypes($class, $property, $context);

if (null !== $legacyTypes) {
return LegacyTypeConverter::toTypeInfoType($legacyTypes);
}

continue;
}

if (null !== $value = $extractor->getType($class, $property, $context)) {
return $value;
}
}

return null;
}

public function getTypes(string $class, string $property, array $context = []): ?array
Expand Down
62 changes: 62 additions & 0 deletions src/Symfony/Component/PropertyInfo/Util/LegacyTypeConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* 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\Util;

use Symfony\Component\PropertyInfo\Type as LegacyType;
use Symfony\Component\TypeInfo\Type;

/**
* @internal
*/
class LegacyTypeConverter
{
/**
* @param LegacyType[]|null $legacyTypes
*/
public static function toTypeInfoType(?array $legacyTypes): ?Type
{
if (null === $legacyTypes) {
return null;
}

$types = [];

foreach ($legacyTypes as $legacyType) {
$typeInfoType = match ($legacyType->getBuiltinType()) {
LegacyType::BUILTIN_TYPE_ARRAY => Type::array(),
LegacyType::BUILTIN_TYPE_BOOL => Type::bool(),
LegacyType::BUILTIN_TYPE_CALLABLE => Type::callable(),
LegacyType::BUILTIN_TYPE_FALSE => Type::false(),
LegacyType::BUILTIN_TYPE_FLOAT => Type::float(),
LegacyType::BUILTIN_TYPE_INT => Type::int(),
LegacyType::BUILTIN_TYPE_ITERABLE => Type::iterable(),
LegacyType::BUILTIN_TYPE_NULL => Type::null(),
LegacyType::BUILTIN_TYPE_OBJECT => Type::object($legacyType->getClassName()),
LegacyType::BUILTIN_TYPE_RESOURCE => Type::resource(),
LegacyType::BUILTIN_TYPE_STRING => Type::string(),
LegacyType::BUILTIN_TYPE_TRUE => Type::true(),
};

if ($legacyType->isNullable()) {
$typeInfoType = Type::union($typeInfoType, Type::null());
}

$types[] = $typeInfoType;
}

if (1 === \count($types)) {
return $types[0];
}

return Type::union(...$types);
}
}

0 comments on commit 16f5b89

Please sign in to comment.