Merge branch '4.4'

* 4.4:
  [Serializer] Use context to compute MetadataAwareNameConverter cache
  [VarDumper] Mark StubCaster as @final
This commit is contained in:
Nicolas Grekas 2019-11-06 17:13:58 +01:00
commit d4ae37457a
3 changed files with 50 additions and 14 deletions

View File

@ -26,11 +26,11 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
*/ */
private $fallbackNameConverter; private $fallbackNameConverter;
private $normalizeCache = []; private static $normalizeCache = [];
private $denormalizeCache = []; private static $denormalizeCache = [];
private $attributesMetadataCache = []; private static $attributesMetadataCache = [];
public function __construct(ClassMetadataFactoryInterface $metadataFactory, NameConverterInterface $fallbackNameConverter = null) public function __construct(ClassMetadataFactoryInterface $metadataFactory, NameConverterInterface $fallbackNameConverter = null)
{ {
@ -47,11 +47,11 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $this->normalizeFallback($propertyName, $class, $format, $context); return $this->normalizeFallback($propertyName, $class, $format, $context);
} }
if (!isset($this->normalizeCache[$class][$propertyName])) { if (!isset(self::$normalizeCache[$class][$propertyName])) {
$this->normalizeCache[$class][$propertyName] = $this->getCacheValueForNormalization($propertyName, $class); self::$normalizeCache[$class][$propertyName] = $this->getCacheValueForNormalization($propertyName, $class);
} }
return $this->normalizeCache[$class][$propertyName] ?? $this->normalizeFallback($propertyName, $class, $format, $context); return self::$normalizeCache[$class][$propertyName] ?? $this->normalizeFallback($propertyName, $class, $format, $context);
} }
/** /**
@ -63,11 +63,12 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $this->denormalizeFallback($propertyName, $class, $format, $context); return $this->denormalizeFallback($propertyName, $class, $format, $context);
} }
if (!isset($this->denormalizeCache[$class][$propertyName])) { $cacheKey = $this->getCacheKey($class, $context);
$this->denormalizeCache[$class][$propertyName] = $this->getCacheValueForDenormalization($propertyName, $class, $context); if (!isset(self::$denormalizeCache[$cacheKey][$propertyName])) {
self::$denormalizeCache[$cacheKey][$propertyName] = $this->getCacheValueForDenormalization($propertyName, $class, $context);
} }
return $this->denormalizeCache[$class][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context); return self::$denormalizeCache[$cacheKey][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context);
} }
private function getCacheValueForNormalization(string $propertyName, string $class): ?string private function getCacheValueForNormalization(string $propertyName, string $class): ?string
@ -89,13 +90,14 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName; return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName;
} }
private function getCacheValueForDenormalization(string $propertyName, string $class, $context): ?string private function getCacheValueForDenormalization(string $propertyName, string $class, array $context): ?string
{ {
if (!isset($this->attributesMetadataCache[$class])) { $cacheKey = $this->getCacheKey($class, $context);
$this->attributesMetadataCache[$class] = $this->getCacheValueForAttributesMetadata($class, $context); if (!isset(self::$attributesMetadataCache[$cacheKey])) {
self::$attributesMetadataCache[$cacheKey] = $this->getCacheValueForAttributesMetadata($class, $context);
} }
return $this->attributesMetadataCache[$class][$propertyName] ?? null; return self::$attributesMetadataCache[$cacheKey][$propertyName] ?? null;
} }
private function denormalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string private function denormalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string
@ -103,7 +105,7 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName; return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName;
} }
private function getCacheValueForAttributesMetadata(string $class, $context): array private function getCacheValueForAttributesMetadata(string $class, array $context): array
{ {
if (!$this->metadataFactory->hasMetadataFor($class)) { if (!$this->metadataFactory->hasMetadataFor($class)) {
return []; return [];
@ -130,4 +132,13 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $cache; return $cache;
} }
private function getCacheKey(string $class, array $context): string
{
if (isset($context['cache_key'])) {
return $class.'-'.$context['cache_key'];
}
return $class.md5(serialize($context[AbstractNormalizer::GROUPS] ?? []));
}
} }

View File

@ -117,6 +117,18 @@ final class MetadataAwareNameConverterTest extends TestCase
]; ];
} }
/**
* @dataProvider attributeAndContextProvider
*/
public function testNormalizeWithGroups($propertyName, $expected, $context = [])
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$nameConverter = new MetadataAwareNameConverter($classMetadataFactory);
$this->assertEquals($expected, $nameConverter->normalize($propertyName, OtherSerializedNameDummy::class, null, $context));
}
/** /**
* @dataProvider attributeAndContextProvider * @dataProvider attributeAndContextProvider
*/ */
@ -138,4 +150,15 @@ final class MetadataAwareNameConverterTest extends TestCase
['buz', 'buz', []], ['buz', 'buz', []],
]; ];
} }
public function testDenormalizeWithCacheContext()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$nameConverter = new MetadataAwareNameConverter($classMetadataFactory);
$this->assertEquals('buz', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class, null, ['groups' => ['a']]));
$this->assertEquals('buzForExport', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class, null, ['groups' => ['b']]));
$this->assertEquals('buz', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class));
}
} }

View File

@ -17,6 +17,8 @@ use Symfony\Component\VarDumper\Cloner\Stub;
* Casts a caster's Stub. * Casts a caster's Stub.
* *
* @author Nicolas Grekas <p@tchwork.com> * @author Nicolas Grekas <p@tchwork.com>
*
* @final since Symfony 4.4
*/ */
class StubCaster class StubCaster
{ {