From a6586923e775f107bdc840cc53c3e6c918b1d343 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 22 Aug 2023 16:39:24 +0200 Subject: [PATCH] [FrameworkBundle][Serializer] Deprecate annotations --- UPGRADE-6.4.md | 2 +- .../Extension/SerializerExtensionTest.php | 4 +- src/Symfony/Bridge/Twig/composer.json | 4 +- .../FrameworkExtension.php | 4 +- .../FrameworkExtensionTestCase.php | 4 +- .../Bundle/SecurityBundle/composer.json | 2 +- .../Component/HttpKernel/composer.json | 2 +- .../Extractor/SerializerExtractorTest.php | 4 +- .../Component/PropertyInfo/composer.json | 4 +- src/Symfony/Component/Serializer/CHANGELOG.md | 2 +- .../Mapping/Loader/AnnotationLoader.php | 283 +--------------- .../Mapping/Loader/AttributeLoader.php | 313 ++++++++++++++++++ .../Tests/Command/DebugCommandTest.php | 4 +- .../ClassMetadataFactoryCompilerTest.php | 4 +- .../Factory/ClassMetadataFactoryTest.php | 6 +- ...ationLoaderWithDoctrineAnnotationsTest.php | 7 +- ...stCase.php => AttributeLoaderTestCase.php} | 16 +- ... => AttributeLoaderWithAttributesTest.php} | 8 +- .../MetadataAwareNameConverterTest.php | 20 +- .../AbstractObjectNormalizerTest.php | 34 +- .../Features/ContextMetadataTestTrait.php | 8 +- .../Normalizer/GetSetMethodNormalizerTest.php | 28 +- .../Normalizer/MapDenormalizationTest.php | 4 +- .../Tests/Normalizer/ObjectNormalizerTest.php | 26 +- .../Normalizer/PropertyNormalizerTest.php | 18 +- .../Serializer/Tests/SerializerTest.php | 12 +- .../Component/Serializer/composer.json | 3 +- 27 files changed, 440 insertions(+), 386 deletions(-) create mode 100644 src/Symfony/Component/Serializer/Mapping/Loader/AttributeLoader.php rename src/Symfony/Component/Serializer/Tests/Mapping/Loader/{AnnotationLoaderTestCase.php => AttributeLoaderTestCase.php} (92%) rename src/Symfony/Component/Serializer/Tests/Mapping/Loader/{AnnotationLoaderWithAttributesTest.php => AttributeLoaderWithAttributesTest.php} (81%) diff --git a/UPGRADE-6.4.md b/UPGRADE-6.4.md index 3ad780886dd92..a0518848e1d58 100644 --- a/UPGRADE-6.4.md +++ b/UPGRADE-6.4.md @@ -199,7 +199,7 @@ Serializer ---------- * Deprecate Doctrine annotations support in favor of native attributes - * Deprecate passing an annotation reader to the constructor of `AnnotationLoader` + * Deprecate `AnnotationLoader`, use `AttributeLoader` instead Templating ---------- diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php index 0115f867d8a80..610030cec5a9f 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php @@ -18,7 +18,7 @@ use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\YamlEncoder; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Twig\Environment; @@ -49,7 +49,7 @@ public static function serializerDataProvider(): \Generator private function getTwig(string $template): Environment { - $meta = new ClassMetadataFactory(new AnnotationLoader()); + $meta = new ClassMetadataFactory(new AttributeLoader()); $runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()])); $mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class); diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index a982bf4f92289..9a3449bd44887 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -43,7 +43,7 @@ "symfony/security-core": "^5.4|^6.0|^7.0", "symfony/security-csrf": "^5.4|^6.0|^7.0", "symfony/security-http": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.2|^7.0", + "symfony/serializer": "^6.4|^7.0", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/console": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", @@ -61,7 +61,7 @@ "symfony/http-foundation": "<5.4", "symfony/http-kernel": "<6.4", "symfony/mime": "<6.2", - "symfony/serializer": "<6.2", + "symfony/serializer": "<6.4", "symfony/translation": "<5.4", "symfony/workflow": "<5.4" }, diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index bd258c850fc01..c48de2eee652f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -156,7 +156,7 @@ use Symfony\Component\Semaphore\Store\StoreFactory as SemaphoreStoreFactory; use Symfony\Component\Serializer\Encoder\DecoderInterface; use Symfony\Component\Serializer\Encoder\EncoderInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader; use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; @@ -1926,7 +1926,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $serializerLoaders = []; if (isset($config['enable_attributes']) && $config['enable_attributes']) { $annotationLoader = new Definition( - AnnotationLoader::class, + AttributeLoader::class, [new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE)] ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 5f020a0abc916..8a26d72ea5b70 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -65,7 +65,7 @@ use Symfony\Component\Notifier\TexterInterface; use Symfony\Component\PropertyAccess\PropertyAccessor; use Symfony\Component\Security\Core\AuthenticationEvents; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader; use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader; use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer; @@ -1489,7 +1489,7 @@ public function testSerializerEnabled() $argument = $container->getDefinition('serializer.mapping.chain_loader')->getArgument(0); $this->assertCount(2, $argument); - $this->assertEquals(AnnotationLoader::class, $argument[0]->getClass()); + $this->assertEquals(AttributeLoader::class, $argument[0]->getClass()); $this->assertEquals(new Reference('serializer.name_converter.camel_case_to_snake_case'), $container->getDefinition('serializer.name_converter.metadata_aware')->getArgument(1)); $this->assertEquals(new Reference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $container->getDefinition('serializer.normalizer.object')->getArgument(3)); $this->assertArrayHasKey('circular_reference_handler', $container->getDefinition('serializer.normalizer.object')->getArgument(6)); diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index fd804b9d7a6bb..c91d3b103b5fd 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -45,7 +45,7 @@ "symfony/ldap": "^5.4|^6.0|^7.0", "symfony/process": "^5.4|^6.0|^7.0", "symfony/rate-limiter": "^5.4|^6.0|^7.0", - "symfony/serializer": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", "symfony/translation": "^5.4|^6.0|^7.0", "symfony/twig-bundle": "^5.4|^6.0|^7.0", "symfony/twig-bridge": "^5.4|^6.0|^7.0", diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 3a8ecf5cd7cb9..142fffa506334 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -66,7 +66,7 @@ "symfony/translation": "<5.4", "symfony/translation-contracts": "<2.5", "symfony/twig-bridge": "<5.4", - "symfony/validator": "<5.4", + "symfony/validator": "<6.4", "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php index 1aa57864d0927..ec3f949bbeb69 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php @@ -17,7 +17,7 @@ use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\IgnorePropertyDummy; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; /** * @author Kévin Dunglas @@ -28,7 +28,7 @@ class SerializerExtractorTest extends TestCase protected function setUp(): void { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->extractor = new SerializerExtractor($classMetadataFactory); } diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index 0828727944070..0a9879ff98221 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -27,7 +27,7 @@ "symfony/string": "^5.4|^6.0|^7.0" }, "require-dev": { - "symfony/serializer": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/dependency-injection": "^5.4|^6.0|^7.0", "phpdocumentor/reflection-docblock": "^5.2", @@ -37,7 +37,7 @@ "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", "symfony/dependency-injection": "<5.4", - "symfony/serializer": "<5.4" + "symfony/serializer": "<6.4" }, "autoload": { "psr-4": { "Symfony\\Component\\PropertyInfo\\": "" }, diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 19e57fc59af50..fdefebdc07e58 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -6,11 +6,11 @@ CHANGELOG * Allow `Context` attribute to target classes * Deprecate Doctrine annotations support in favor of native attributes - * Deprecate passing an annotation reader to the constructor of `AnnotationLoader` * Allow the `Groups` attribute/annotation on classes * JsonDecode: Add `json_decode_detailed_errors` option * Make `ProblemNormalizer` give details about Messenger's `ValidationFailedException` * Add `XmlEncoder::CDATA_WRAPPING` context option + * Deprecate `AnnotationLoader`, use `AttributeLoader` instead 6.3 --- diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php index 345e250541c05..f5c8f9ccc12bc 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php @@ -11,288 +11,15 @@ namespace Symfony\Component\Serializer\Mapping\Loader; -use Doctrine\Common\Annotations\Reader; -use Symfony\Component\Serializer\Annotation\Context; -use Symfony\Component\Serializer\Annotation\DiscriminatorMap; -use Symfony\Component\Serializer\Annotation\Groups; -use Symfony\Component\Serializer\Annotation\Ignore; -use Symfony\Component\Serializer\Annotation\MaxDepth; -use Symfony\Component\Serializer\Annotation\SerializedName; -use Symfony\Component\Serializer\Annotation\SerializedPath; -use Symfony\Component\Serializer\Exception\MappingException; -use Symfony\Component\Serializer\Mapping\AttributeMetadata; -use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; -use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping; -use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; +trigger_deprecation('symfony/serializer', '6.4', 'The "%s" class is deprecated, use "%s" instead.', AnnotationLoader::class, AttributeLoader::class); -/** - * Loader for Doctrine annotations and PHP 8 attributes. - * - * @author Kévin Dunglas - * @author Alexander M. Turek - */ -class AnnotationLoader implements LoaderInterface -{ - private const KNOWN_ANNOTATIONS = [ - DiscriminatorMap::class, - Groups::class, - Ignore::class, - MaxDepth::class, - SerializedName::class, - SerializedPath::class, - Context::class, - ]; - - public function __construct( - private readonly ?Reader $reader = null, - ) { - if ($reader) { - trigger_deprecation('symfony/serializer', '6.4', 'Passing a "%s" instance as argument 1 to "%s()" is deprecated, pass null or omit the parameter instead.', get_debug_type($reader), __METHOD__); - } - } - - public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool - { - $reflectionClass = $classMetadata->getReflectionClass(); - $className = $reflectionClass->name; - $loaded = false; - $classGroups = []; - $classContextAnnotation = null; - - $attributesMetadata = $classMetadata->getAttributesMetadata(); - - foreach ($this->loadAnnotations($reflectionClass) as $annotation) { - if ($annotation instanceof DiscriminatorMap) { - $classMetadata->setClassDiscriminatorMapping(new ClassDiscriminatorMapping( - $annotation->getTypeProperty(), - $annotation->getMapping() - )); - continue; - } - - if ($annotation instanceof Groups) { - $classGroups = $annotation->getGroups(); - - continue; - } - - if ($annotation instanceof Context) { - $classContextAnnotation = $annotation; - } - } - - foreach ($reflectionClass->getProperties() as $property) { - if (!isset($attributesMetadata[$property->name])) { - $attributesMetadata[$property->name] = new AttributeMetadata($property->name); - $classMetadata->addAttributeMetadata($attributesMetadata[$property->name]); - } - - if ($property->getDeclaringClass()->name === $className) { - if ($classContextAnnotation) { - $this->setAttributeContextsForGroups($classContextAnnotation, $attributesMetadata[$property->name]); - } - - foreach ($classGroups as $group) { - $attributesMetadata[$property->name]->addGroup($group); - } - - foreach ($this->loadAnnotations($property) as $annotation) { - if ($annotation instanceof Groups) { - foreach ($annotation->getGroups() as $group) { - $attributesMetadata[$property->name]->addGroup($group); - } - } elseif ($annotation instanceof MaxDepth) { - $attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth()); - } elseif ($annotation instanceof SerializedName) { - $attributesMetadata[$property->name]->setSerializedName($annotation->getSerializedName()); - } elseif ($annotation instanceof SerializedPath) { - $attributesMetadata[$property->name]->setSerializedPath($annotation->getSerializedPath()); - } elseif ($annotation instanceof Ignore) { - $attributesMetadata[$property->name]->setIgnore(true); - } elseif ($annotation instanceof Context) { - $this->setAttributeContextsForGroups($annotation, $attributesMetadata[$property->name]); - } - - $loaded = true; - } - } - } - - foreach ($reflectionClass->getMethods() as $method) { - if ($method->getDeclaringClass()->name !== $className) { - continue; - } - - if (0 === stripos($method->name, 'get') && $method->getNumberOfRequiredParameters()) { - continue; /* matches the BC behavior in `Symfony\Component\Serializer\Normalizer\ObjectNormalizer::extractAttributes` */ - } - - $accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches); - if ($accessorOrMutator) { - $attributeName = lcfirst($matches[2]); - - if (isset($attributesMetadata[$attributeName])) { - $attributeMetadata = $attributesMetadata[$attributeName]; - } else { - $attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName); - $classMetadata->addAttributeMetadata($attributeMetadata); - } - } - - foreach ($this->loadAnnotations($method) as $annotation) { - if ($annotation instanceof Groups) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('Groups on "%s::%s()" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - foreach ($annotation->getGroups() as $group) { - $attributeMetadata->addGroup($group); - } - } elseif ($annotation instanceof MaxDepth) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('MaxDepth on "%s::%s()" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - $attributeMetadata->setMaxDepth($annotation->getMaxDepth()); - } elseif ($annotation instanceof SerializedName) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('SerializedName on "%s::%s()" cannot be added. SerializedName can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - $attributeMetadata->setSerializedName($annotation->getSerializedName()); - } elseif ($annotation instanceof SerializedPath) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('SerializedPath on "%s::%s()" cannot be added. SerializedPath can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - $attributeMetadata->setSerializedPath($annotation->getSerializedPath()); - } elseif ($annotation instanceof Ignore) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('Ignore on "%s::%s()" cannot be added. Ignore can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - $attributeMetadata->setIgnore(true); - } elseif ($annotation instanceof Context) { - if (!$accessorOrMutator) { - throw new MappingException(sprintf('Context on "%s::%s()" cannot be added. Context can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } - - $this->setAttributeContextsForGroups($annotation, $attributeMetadata); - } - - $loaded = true; - } - } - - return $loaded; - } - - public function loadAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable - { - foreach ($reflector->getAttributes() as $attribute) { - if ($this->isKnownAttribute($attribute->getName())) { - try { - yield $attribute->newInstance(); - } catch (\Error $e) { - if (\Error::class !== $e::class) { - throw $e; - } - $on = match (true) { - $reflector instanceof \ReflectionClass => ' on class '.$reflector->name, - $reflector instanceof \ReflectionMethod => sprintf(' on "%s::%s()"', $reflector->getDeclaringClass()->name, $reflector->name), - $reflector instanceof \ReflectionProperty => sprintf(' on "%s::$%s"', $reflector->getDeclaringClass()->name, $reflector->name), - default => '', - }; - - throw new MappingException(sprintf('Could not instantiate attribute "%s"%s.', $attribute->getName(), $on), 0, $e); - } - } - } - - if (null === $this->reader) { - return; - } - - if ($reflector instanceof \ReflectionClass) { - yield from $this->getClassAnnotations($reflector); - } - if ($reflector instanceof \ReflectionMethod) { - yield from $this->getMethodAnnotations($reflector); - } - if ($reflector instanceof \ReflectionProperty) { - yield from $this->getPropertyAnnotations($reflector); - } - } - - private function setAttributeContextsForGroups(Context $annotation, AttributeMetadataInterface $attributeMetadata): void - { - if ($annotation->getContext()) { - $attributeMetadata->setNormalizationContextForGroups($annotation->getContext(), $annotation->getGroups()); - $attributeMetadata->setDenormalizationContextForGroups($annotation->getContext(), $annotation->getGroups()); - } - - if ($annotation->getNormalizationContext()) { - $attributeMetadata->setNormalizationContextForGroups($annotation->getNormalizationContext(), $annotation->getGroups()); - } - - if ($annotation->getDenormalizationContext()) { - $attributeMetadata->setDenormalizationContextForGroups($annotation->getDenormalizationContext(), $annotation->getGroups()); - } - } - - private function isKnownAttribute(string $attributeName): bool - { - foreach (self::KNOWN_ANNOTATIONS as $knownAnnotation) { - if (is_a($attributeName, $knownAnnotation, true)) { - return true; - } - } - - return false; - } - - /** - * @return object[] - */ - private function getClassAnnotations(\ReflectionClass $reflector): array - { - if ($annotations = array_filter( - $this->reader->getClassAnnotations($reflector), - fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), - )) { - trigger_deprecation('symfony/serializer', '6.4', 'Class "%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getName()); - } - - return $annotations; - } +class_exists(AttributeLoader::class); +if (false) { /** - * @return object[] + * @deprecated since Symfony 6.4, to be removed in 7.0, use {@link AttributeLoader} instead */ - private function getMethodAnnotations(\ReflectionMethod $reflector): array + class AnnotationLoader { - if ($annotations = array_filter( - $this->reader->getMethodAnnotations($reflector), - fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), - )) { - trigger_deprecation('symfony/serializer', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); - } - - return $annotations; - } - - /** - * @return object[] - */ - private function getPropertyAnnotations(\ReflectionProperty $reflector): array - { - if ($annotations = array_filter( - $this->reader->getPropertyAnnotations($reflector), - fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), - )) { - trigger_deprecation('symfony/serializer', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); - } - - return $annotations; } } diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/AttributeLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/AttributeLoader.php new file mode 100644 index 0000000000000..9b379bdee45bb --- /dev/null +++ b/src/Symfony/Component/Serializer/Mapping/Loader/AttributeLoader.php @@ -0,0 +1,313 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Mapping\Loader; + +use Doctrine\Common\Annotations\Reader; +use Symfony\Component\Serializer\Annotation\Context; +use Symfony\Component\Serializer\Annotation\DiscriminatorMap; +use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Annotation\Ignore; +use Symfony\Component\Serializer\Annotation\MaxDepth; +use Symfony\Component\Serializer\Annotation\SerializedName; +use Symfony\Component\Serializer\Annotation\SerializedPath; +use Symfony\Component\Serializer\Exception\MappingException; +use Symfony\Component\Serializer\Mapping\AttributeMetadata; +use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; +use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping; +use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; + +/** + * Loader for PHP attributes. + * + * @author Kévin Dunglas + * @author Alexander M. Turek + * @author Alexandre Daubois + */ +class AttributeLoader implements LoaderInterface +{ + private const KNOWN_ATTRIBUTES = [ + DiscriminatorMap::class, + Groups::class, + Ignore::class, + MaxDepth::class, + SerializedName::class, + SerializedPath::class, + Context::class, + ]; + + public function __construct( + private readonly ?Reader $reader = null, + ) { + if ($reader) { + trigger_deprecation('symfony/serializer', '6.4', 'Passing a "%s" instance as argument 1 to "%s()" is deprecated, pass null or omit the parameter instead.', get_debug_type($reader), __METHOD__); + } + } + + public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool + { + $reflectionClass = $classMetadata->getReflectionClass(); + $className = $reflectionClass->name; + $loaded = false; + $classGroups = []; + $classContextAnnotation = null; + + $attributesMetadata = $classMetadata->getAttributesMetadata(); + + foreach ($this->loadAttributes($reflectionClass) as $annotation) { + if ($annotation instanceof DiscriminatorMap) { + $classMetadata->setClassDiscriminatorMapping(new ClassDiscriminatorMapping( + $annotation->getTypeProperty(), + $annotation->getMapping() + )); + continue; + } + + if ($annotation instanceof Groups) { + $classGroups = $annotation->getGroups(); + + continue; + } + + if ($annotation instanceof Context) { + $classContextAnnotation = $annotation; + } + } + + foreach ($reflectionClass->getProperties() as $property) { + if (!isset($attributesMetadata[$property->name])) { + $attributesMetadata[$property->name] = new AttributeMetadata($property->name); + $classMetadata->addAttributeMetadata($attributesMetadata[$property->name]); + } + + if ($property->getDeclaringClass()->name === $className) { + if ($classContextAnnotation) { + $this->setAttributeContextsForGroups($classContextAnnotation, $attributesMetadata[$property->name]); + } + + foreach ($classGroups as $group) { + $attributesMetadata[$property->name]->addGroup($group); + } + + foreach ($this->loadAttributes($property) as $annotation) { + if ($annotation instanceof Groups) { + foreach ($annotation->getGroups() as $group) { + $attributesMetadata[$property->name]->addGroup($group); + } + } elseif ($annotation instanceof MaxDepth) { + $attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth()); + } elseif ($annotation instanceof SerializedName) { + $attributesMetadata[$property->name]->setSerializedName($annotation->getSerializedName()); + } elseif ($annotation instanceof SerializedPath) { + $attributesMetadata[$property->name]->setSerializedPath($annotation->getSerializedPath()); + } elseif ($annotation instanceof Ignore) { + $attributesMetadata[$property->name]->setIgnore(true); + } elseif ($annotation instanceof Context) { + $this->setAttributeContextsForGroups($annotation, $attributesMetadata[$property->name]); + } + + $loaded = true; + } + } + } + + foreach ($reflectionClass->getMethods() as $method) { + if ($method->getDeclaringClass()->name !== $className) { + continue; + } + + if (0 === stripos($method->name, 'get') && $method->getNumberOfRequiredParameters()) { + continue; /* matches the BC behavior in `Symfony\Component\Serializer\Normalizer\ObjectNormalizer::extractAttributes` */ + } + + $accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches); + if ($accessorOrMutator) { + $attributeName = lcfirst($matches[2]); + + if (isset($attributesMetadata[$attributeName])) { + $attributeMetadata = $attributesMetadata[$attributeName]; + } else { + $attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName); + $classMetadata->addAttributeMetadata($attributeMetadata); + } + } + + foreach ($this->loadAttributes($method) as $annotation) { + if ($annotation instanceof Groups) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('Groups on "%s::%s()" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + foreach ($annotation->getGroups() as $group) { + $attributeMetadata->addGroup($group); + } + } elseif ($annotation instanceof MaxDepth) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('MaxDepth on "%s::%s()" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $attributeMetadata->setMaxDepth($annotation->getMaxDepth()); + } elseif ($annotation instanceof SerializedName) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('SerializedName on "%s::%s()" cannot be added. SerializedName can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $attributeMetadata->setSerializedName($annotation->getSerializedName()); + } elseif ($annotation instanceof SerializedPath) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('SerializedPath on "%s::%s()" cannot be added. SerializedPath can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $attributeMetadata->setSerializedPath($annotation->getSerializedPath()); + } elseif ($annotation instanceof Ignore) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('Ignore on "%s::%s()" cannot be added. Ignore can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $attributeMetadata->setIgnore(true); + } elseif ($annotation instanceof Context) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('Context on "%s::%s()" cannot be added. Context can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $this->setAttributeContextsForGroups($annotation, $attributeMetadata); + } + + $loaded = true; + } + } + + return $loaded; + } + + private function loadAttributes(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable + { + foreach ($reflector->getAttributes() as $attribute) { + if ($this->isKnownAttribute($attribute->getName())) { + try { + yield $attribute->newInstance(); + } catch (\Error $e) { + if (\Error::class !== $e::class) { + throw $e; + } + $on = match (true) { + $reflector instanceof \ReflectionClass => ' on class '.$reflector->name, + $reflector instanceof \ReflectionMethod => sprintf(' on "%s::%s()"', $reflector->getDeclaringClass()->name, $reflector->name), + $reflector instanceof \ReflectionProperty => sprintf(' on "%s::$%s"', $reflector->getDeclaringClass()->name, $reflector->name), + default => '', + }; + + throw new MappingException(sprintf('Could not instantiate attribute "%s"%s.', $attribute->getName(), $on), 0, $e); + } + } + } + + if (null === $this->reader) { + return; + } + + if ($reflector instanceof \ReflectionClass) { + yield from $this->getClassAnnotations($reflector); + } + if ($reflector instanceof \ReflectionMethod) { + yield from $this->getMethodAnnotations($reflector); + } + if ($reflector instanceof \ReflectionProperty) { + yield from $this->getPropertyAnnotations($reflector); + } + } + + /** + * @deprecated since Symfony 6.4 without replacement + */ + public function loadAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable + { + trigger_deprecation('symfony/serializer', '6.4', 'Method "%s()" is deprecated without replacement.', __METHOD__); + + return $this->loadAttributes($reflector); + } + + private function setAttributeContextsForGroups(Context $annotation, AttributeMetadataInterface $attributeMetadata): void + { + if ($annotation->getContext()) { + $attributeMetadata->setNormalizationContextForGroups($annotation->getContext(), $annotation->getGroups()); + $attributeMetadata->setDenormalizationContextForGroups($annotation->getContext(), $annotation->getGroups()); + } + + if ($annotation->getNormalizationContext()) { + $attributeMetadata->setNormalizationContextForGroups($annotation->getNormalizationContext(), $annotation->getGroups()); + } + + if ($annotation->getDenormalizationContext()) { + $attributeMetadata->setDenormalizationContextForGroups($annotation->getDenormalizationContext(), $annotation->getGroups()); + } + } + + private function isKnownAttribute(string $attributeName): bool + { + foreach (self::KNOWN_ATTRIBUTES as $knownAttribute) { + if (is_a($attributeName, $knownAttribute, true)) { + return true; + } + } + + return false; + } + + /** + * @return object[] + */ + private function getClassAnnotations(\ReflectionClass $reflector): array + { + if ($annotations = array_filter( + $this->reader->getClassAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Class "%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getName()); + } + + return $annotations; + } + + /** + * @return object[] + */ + private function getMethodAnnotations(\ReflectionMethod $reflector): array + { + if ($annotations = array_filter( + $this->reader->getMethodAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); + } + + return $annotations; + } + + /** + * @return object[] + */ + private function getPropertyAnnotations(\ReflectionProperty $reflector): array + { + if ($annotations = array_filter( + $this->reader->getPropertyAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); + } + + return $annotations; + } +} + +if (!class_exists(AnnotationLoader::class, false)) { + class_alias(AttributeLoader::class, AnnotationLoader::class); +} diff --git a/src/Symfony/Component/Serializer/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Serializer/Tests/Command/DebugCommandTest.php index a92e73f335dca..879231160fe9d 100644 --- a/src/Symfony/Component/Serializer/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Serializer/Tests/Command/DebugCommandTest.php @@ -16,7 +16,7 @@ use Symfony\Component\Serializer\Command\DebugCommand; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Tests\Dummy\DummyClassOne; /** @@ -26,7 +26,7 @@ class DebugCommandTest extends TestCase { public function testOutputWithClassArgument() { - $command = new DebugCommand(new ClassMetadataFactory(new AnnotationLoader())); + $command = new DebugCommand(new ClassMetadataFactory(new AttributeLoader())); $tester = new CommandTester($command); $tester->execute(['class' => DummyClassOne::class], ['decorated' => false]); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php index fc61b3752341c..1826d3dc4d116 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php @@ -14,7 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryCompiler; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathDummy; @@ -37,7 +37,7 @@ protected function tearDown(): void public function testItDumpMetadata() { - $classMetatadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetatadataFactory = new ClassMetadataFactory(new AttributeLoader()); $dummyMetadata = $classMetatadataFactory->getMetadataFor(Dummy::class); $maxDepthDummyMetadata = $classMetatadataFactory->getMetadataFor(MaxDepthDummy::class); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php index d034a06c64f01..140623ab07ed4 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php @@ -14,7 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Mapping\Loader\LoaderChain; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummyInterface; @@ -34,7 +34,7 @@ public function testInterface() public function testGetMetadataFor() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $classMetadata = $factory->getMetadataFor(GroupDummy::class); $this->assertEquals(TestClassMetadataFactory::createClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Attributes', true, true), $classMetadata); @@ -42,7 +42,7 @@ public function testGetMetadataFor() public function testHasMetadataFor() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $this->assertTrue($factory->hasMetadataFor(GroupDummy::class)); $this->assertTrue($factory->hasMetadataFor(GroupDummyParent::class)); $this->assertTrue($factory->hasMetadataFor(GroupDummyInterface::class)); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php index 67212ee4b7ff4..9d786bde58346 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php @@ -14,17 +14,18 @@ use Doctrine\Common\Annotations\AnnotationReader; use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; /** * @group legacy */ -class AnnotationLoaderWithDoctrineAnnotationsTest extends AnnotationLoaderTestCase +class AnnotationLoaderWithDoctrineAnnotationsTest extends AttributeLoaderTestCase { use ExpectDeprecationTrait; protected function setUp(): void { - $this->expectDeprecation('Since symfony/serializer 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Serializer\Mapping\Loader\AttributeLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); parent::setUp(); } @@ -158,7 +159,7 @@ public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsUsed() parent::testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsUsed(); } - protected function createLoader(): AnnotationLoader + protected function createLoader(): AttributeLoader { return new AnnotationLoader(new AnnotationReader()); } diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderTestCase.php similarity index 92% rename from src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php rename to src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderTestCase.php index 69b486177712c..3fa3fc4335e53 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderTestCase.php @@ -12,12 +12,14 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Loader; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Serializer\Exception\MappingException; use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping; use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface; use Symfony\Component\Serializer\Tests\Mapping\Loader\Features\ContextMappingTestTrait; use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory; @@ -25,9 +27,10 @@ /** * @author Kévin Dunglas */ -abstract class AnnotationLoaderTestCase extends TestCase +abstract class AttributeLoaderTestCase extends TestCase { use ContextMappingTestTrait; + use ExpectDeprecationTrait; protected AnnotationLoader $loader; @@ -210,7 +213,16 @@ public function testLoadGroupsOnClass() self::assertSame(['a'], $attributesMetadata['baz']->getGroups()); } - abstract protected function createLoader(): AnnotationLoader; + /** + * @group legacy + */ + public function testExpectedDeprecationOnLoadAnnotationsCall() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Mapping\Loader\AttributeLoader::loadAnnotations()" is deprecated without replacement.'); + $this->loader->loadAnnotations(new \ReflectionClass(\stdClass::class)); + } + + abstract protected function createLoader(): AttributeLoader; abstract protected function getNamespace(): string; diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithAttributesTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderWithAttributesTest.php similarity index 81% rename from src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithAttributesTest.php rename to src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderWithAttributesTest.php index 89e94b66302b8..c696b8c24ee80 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithAttributesTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AttributeLoaderWithAttributesTest.php @@ -13,13 +13,13 @@ use Symfony\Component\Serializer\Exception\MappingException; use Symfony\Component\Serializer\Mapping\ClassMetadata; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; -class AnnotationLoaderWithAttributesTest extends AnnotationLoaderTestCase +class AttributeLoaderWithAttributesTest extends AttributeLoaderTestCase { - protected function createLoader(): AnnotationLoader + protected function createLoader(): AttributeLoader { - return new AnnotationLoader(); + return new AttributeLoader(); } protected function getNamespace(): string diff --git a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php index f117378b096f9..883c30a558279 100644 --- a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php +++ b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php @@ -17,7 +17,7 @@ use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; @@ -40,7 +40,7 @@ public function testInterface() */ public function testNormalize(string|int $propertyName, string|int $expected) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -52,7 +52,7 @@ public function testNormalize(string|int $propertyName, string|int $expected) */ public function testNormalizeWithFallback(string|int $propertyName, string|int $expected) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $fallback = $this->createMock(NameConverterInterface::class); $fallback @@ -70,7 +70,7 @@ public function testNormalizeWithFallback(string|int $propertyName, string|int $ */ public function testDenormalize(string|int $expected, string|int $propertyName) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -82,7 +82,7 @@ public function testDenormalize(string|int $expected, string|int $propertyName) */ public function testDenormalizeWithFallback(string|int $expected, string|int $propertyName) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $fallback = $this->createMock(NameConverterInterface::class); $fallback @@ -120,7 +120,7 @@ public static function fallbackAttributeProvider(): array */ public function testNormalizeWithGroups(string $propertyName, string $expected, array $context = []) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -132,7 +132,7 @@ public function testNormalizeWithGroups(string $propertyName, string $expected, */ public function testDenormalizeWithGroups(string $expected, string $propertyName, array $context = []) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -154,7 +154,7 @@ public static function attributeAndContextProvider(): array public function testDenormalizeWithCacheContext() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -165,7 +165,7 @@ public function testDenormalizeWithCacheContext() public function testDenormalizeWithNestedPathAndName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); $this->expectException(LogicException::class); $this->expectExceptionMessage('Found SerializedName and SerializedPath annotations on property "foo" of class "Symfony\Component\Serializer\Tests\NameConverter\NestedPathAndName".'); @@ -174,7 +174,7 @@ public function testDenormalizeWithNestedPathAndName() public function testNormalizeWithNestedPathAndName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); $this->expectException(LogicException::class); $this->expectExceptionMessage('Found SerializedName and SerializedPath annotations on property "foo" of class "Symfony\Component\Serializer\Tests\NameConverter\NestedPathAndName".'); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index 00f2de877710a..4ecd0ed9d7d2f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -31,7 +31,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; @@ -77,7 +77,7 @@ public function testDenormalizeWithExtraAttribute() { $this->expectException(ExtraAttributesException::class); $this->expectExceptionMessage('Extra attributes are not allowed ("fooFoo" is unknown).'); - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new AbstractObjectNormalizerDummy($factory); $normalizer->denormalize( ['fooFoo' => 'foo'], @@ -91,7 +91,7 @@ public function testDenormalizeWithExtraAttributes() { $this->expectException(ExtraAttributesException::class); $this->expectExceptionMessage('Extra attributes are not allowed ("fooFoo", "fooBar" are unknown).'); - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new AbstractObjectNormalizerDummy($factory); $normalizer->denormalize( ['fooFoo' => 'foo', 'fooBar' => 'bar'], @@ -143,7 +143,7 @@ public function testDenormalizeWithNestedAttributesWithoutMetadata() public function testDenormalizeWithSnakeCaseNestedAttributes() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($factory, new CamelCaseToSnakeCaseNameConverter()); $data = [ 'one' => [ @@ -156,7 +156,7 @@ public function testDenormalizeWithSnakeCaseNestedAttributes() public function testNormalizeWithSnakeCaseNestedAttributes() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($factory, new CamelCaseToSnakeCaseNameConverter()); $dummy = new SnakeCaseNestedDummy(); $dummy->fooBar = 'fooBar'; @@ -252,7 +252,7 @@ public function testNormalizeWithNestedAttributesMixingArrayTypes() $foobar = new AlreadyPopulatedNestedDummy(); $foobar->foo = 'foo'; $foobar->bar = 'bar'; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $normalizer->normalize($foobar, 'any'); } @@ -264,7 +264,7 @@ public function testNormalizeWithNestedAttributesElementAlreadySet() $foobar = new DuplicateValueNestedDummy(); $foobar->foo = 'foo'; $foobar->bar = 'bar'; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $normalizer->normalize($foobar, 'any'); } @@ -286,7 +286,7 @@ public function testNormalizeWithNestedAttributes() 'foo' => 'notfoo', 'baz' => 'baz', ]; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test = $normalizer->normalize($foobar, 'any'); $this->assertSame($data, $test); @@ -312,7 +312,7 @@ public function testNormalizeWithNestedAttributesWithoutMetadata() public function testNormalizeWithNestedAttributesInConstructor() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test = $normalizer->normalize(new NestedDummyWithConstructor('foo', 'quux', 'notfoo', 'baz'), 'any'); @@ -330,7 +330,7 @@ public function testNormalizeWithNestedAttributesInConstructor() public function testNormalizeWithNestedAttributesInConstructorAndDiscriminatorMap() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test1 = $normalizer->normalize(new FirstNestedDummyWithConstructorAndDiscriminator('foo', 'notfoo', 'baz'), 'any'); @@ -473,7 +473,7 @@ private function getDenormalizerForStringCollection() public function testDenormalizeWithDiscriminatorMapUsesCorrectClassname() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $loaderMock = new class() implements ClassMetadataFactoryInterface { public function getMetadataFor($value): ClassMetadataInterface @@ -508,7 +508,7 @@ public function hasMetadataFor($value): bool public function testDenormalizeWithDiscriminatorMapAndObjectToPopulateUsesCorrectClassname() { - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $loaderMock = new class() implements ClassMetadataFactoryInterface { public function getMetadataFor($value): ClassMetadataInterface @@ -707,7 +707,7 @@ public function testDenormalizeRecursiveWithObjectAttributeWithStringValue() public function testDenormalizeUsesContextAttributeForPropertiesInConstructorWithSeralizedName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -721,7 +721,7 @@ public function testDenormalizeUsesContextAttributeForPropertiesInConstructorWit public function testNormalizeUsesContextAttributeForPropertiesInConstructorWithSerializedPath() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -736,7 +736,7 @@ public function testNormalizeUsesContextAttributeForPropertiesInConstructorWithS public function testNormalizeUsesContextAttributeForProperties() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -775,7 +775,7 @@ public function testDenormalizeUnionOfEnums() $serializer = new Serializer([ new BackedEnumNormalizer(), new ObjectNormalizer( - classMetadataFactory: new ClassMetadataFactory(new AnnotationLoader()), + classMetadataFactory: new ClassMetadataFactory(new AttributeLoader()), propertyTypeExtractor: new PropertyInfoExtractor([], [new ReflectionExtractor()]), ), ]); @@ -1003,7 +1003,7 @@ class AbstractObjectNormalizerWithMetadata extends AbstractObjectNormalizer { public function __construct() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); parent::__construct($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php index 7375b530dfb27..3c9b18e95ae5c 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php @@ -15,7 +15,7 @@ use Symfony\Component\Serializer\Annotation\Context; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -33,7 +33,7 @@ trait ContextMetadataTestTrait */ public function testContextMetadataNormalize(string $contextMetadataDummyClass) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); @@ -56,7 +56,7 @@ public function testContextMetadataNormalize(string $contextMetadataDummyClass) */ public function testContextMetadataContextDenormalize(string $contextMetadataDummyClass) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); @@ -88,7 +88,7 @@ public function contextMetadataDummyProvider(): array public function testContextDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter(), null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index 5261b95e1464f..df99b4a86b4b7 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -18,7 +18,7 @@ use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; @@ -227,21 +227,21 @@ public function testConstructorWArgWithPrivateMutator() protected function getNormalizerForCallbacksWithPropertyTypeExtractor(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), $this->getCallbackPropertyTypeExtractor()); } protected function getNormalizerForCallbacks(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); } protected function getNormalizerForCircularReference(array $defaultContext): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, null, null, $defaultContext); new Serializer([$normalizer]); @@ -255,7 +255,7 @@ protected function getSelfReferencingModel() protected function getDenormalizerForConstructArguments(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $denormalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); new Serializer([$denormalizer]); @@ -264,21 +264,21 @@ protected function getDenormalizerForConstructArguments(): GetSetMethodNormalize protected function getNormalizerForGroups(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new GetSetMethodNormalizer($classMetadataFactory); } protected function getDenormalizerForGroups(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new GetSetMethodNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -299,7 +299,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -320,7 +320,7 @@ public function testGroupsDenormalizeWithNameConverter() protected function getNormalizerForMaxDepth(): NormalizerInterface { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -330,7 +330,7 @@ protected function getNormalizerForMaxDepth(): NormalizerInterface protected function getDenormalizerForObjectToPopulate(): DenormalizerInterface { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -354,7 +354,7 @@ public function testRejectInvalidKey() protected function getNormalizerForIgnoredAttributes(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -363,7 +363,7 @@ protected function getNormalizerForIgnoredAttributes(): GetSetMethodNormalizer protected function getDenormalizerForIgnoredAttributes(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -487,7 +487,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): GetSetMethod protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface { - return new GetSetMethodNormalizer(new ClassMetadataFactory(new AnnotationLoader())); + return new GetSetMethodNormalizer(new ClassMetadataFactory(new AttributeLoader())); } } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php index 8131e9707a5f8..ea45159557206 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php @@ -21,7 +21,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; @@ -209,7 +209,7 @@ public function hasMetadataFor($value): bool } }; - $factory = new ClassMetadataFactory(new AnnotationLoader()); + $factory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($factory, null, null, new PhpDocExtractor(), new ClassDiscriminatorFromClassMetadata($loaderMock)); $serializer = new Serializer([$normalizer, new ArrayDenormalizer()]); $normalizer->setSerializer($serializer); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index ffa029fa5b790..30bbecbc84a46 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -23,7 +23,7 @@ use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\AdvancedNameConverterInterface; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; @@ -336,7 +336,7 @@ protected function getNormalizerForAttributes(): ObjectNormalizer protected function getDenormalizerForAttributes(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor()); new Serializer([$normalizer]); @@ -362,7 +362,7 @@ public function testAttributesContextDenormalizeConstructor() public function testNormalizeSameObjectWithDifferentAttributes() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer([$this->normalizer]); $this->normalizer->setSerializer($serializer); @@ -437,7 +437,7 @@ public function testSiblingReference() protected function getDenormalizerForConstructArguments(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $denormalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $serializer = new Serializer([$denormalizer]); $denormalizer->setSerializer($serializer); @@ -449,7 +449,7 @@ protected function getDenormalizerForConstructArguments(): ObjectNormalizer protected function getNormalizerForGroups(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory); // instantiate a serializer with the normalizer to handle normalizing recursive structures new Serializer([$normalizer]); @@ -459,14 +459,14 @@ protected function getNormalizerForGroups(): ObjectNormalizer protected function getDenormalizerForGroups(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new ObjectNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -487,7 +487,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -508,7 +508,7 @@ public function testGroupsDenormalizeWithNameConverter() public function testGroupsDenormalizeWithMetaDataNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $this->normalizer->setSerializer($this->serializer); @@ -536,7 +536,7 @@ protected function getNormalizerForIgnoredAttributes(): ObjectNormalizer protected function getDenormalizerForIgnoredAttributes(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor()); new Serializer([$normalizer]); @@ -547,7 +547,7 @@ protected function getDenormalizerForIgnoredAttributes(): ObjectNormalizer protected function getNormalizerForMaxDepth(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -559,7 +559,7 @@ protected function getNormalizerForMaxDepth(): ObjectNormalizer protected function getDenormalizerForObjectToPopulate(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -577,7 +577,7 @@ protected function getNormalizerForSkipNullValues(): ObjectNormalizer protected function getNormalizerForSkipUninitializedValues(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new ObjectNormalizer($classMetadataFactory); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php index b424e41564065..178087be4df7f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php @@ -17,7 +17,7 @@ use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; @@ -264,7 +264,7 @@ public function testSiblingReference() protected function getDenormalizerForConstructArguments(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $denormalizer = new PropertyNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $serializer = new Serializer([$denormalizer]); $denormalizer->setSerializer($serializer); @@ -274,21 +274,21 @@ protected function getDenormalizerForConstructArguments(): PropertyNormalizer protected function getNormalizerForGroups(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new PropertyNormalizer($classMetadataFactory); } protected function getDenormalizerForGroups(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new PropertyNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -309,7 +309,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -353,7 +353,7 @@ public function testIgnoredAttributesContextDenormalizeInherit() protected function getNormalizerForMaxDepth(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new PropertyNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -363,7 +363,7 @@ protected function getNormalizerForMaxDepth(): PropertyNormalizer protected function getDenormalizerForObjectToPopulate(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $normalizer = new PropertyNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -492,7 +492,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): AbstractObje protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface { - return new PropertyNormalizer(new ClassMetadataFactory(new AnnotationLoader())); + return new PropertyNormalizer(new ClassMetadataFactory(new AttributeLoader())); } } diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 4bb6fded7b6d2..b95890b9f66aa 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -29,7 +29,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; -use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; @@ -751,7 +751,7 @@ public function testDeserializeWrappedScalar() public function testUnionTypeDeserializable() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $serializer = new Serializer( [ @@ -783,7 +783,7 @@ public function testUnionTypeDeserializable() public function testUnionTypeDeserializableWithoutAllowedExtraAttributes() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $serializer = new Serializer( [ @@ -844,7 +844,7 @@ public function testTrueBuiltInTypes() private function serializerWithClassDiscriminator() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); return new Serializer([new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor(), new ClassDiscriminatorFromClassMetadata($classMetadataFactory))], ['json' => new JsonEncoder()]); } @@ -1330,7 +1330,7 @@ public function testCollectDenormalizationErrorsWithEnumConstructor() public function testCollectDenormalizationErrorsWithWrongPropertyWithoutConstruct() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader()); $reflectionExtractor = new ReflectionExtractor(); $propertyInfoExtractor = new PropertyInfoExtractor([], [$reflectionExtractor], [], [], []); @@ -1415,7 +1415,7 @@ public static function provideCollectDenormalizationErrors(): array { return [ [null], - [new ClassMetadataFactory(new AnnotationLoader())], + [new ClassMetadataFactory(new AttributeLoader())], ]; } diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index 407fe6a34720a..356436c29c25e 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -39,7 +39,7 @@ "symfony/property-info": "^5.4.24|^6.2.11|^7.0", "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0|^7.0", - "symfony/validator": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0", "symfony/var-exporter": "^5.4|^6.0|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0" @@ -51,6 +51,7 @@ "symfony/dependency-injection": "<5.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4.24|>=6,<6.2.11", + "symfony/validator": "<6.4", "symfony/uid": "<5.4", "symfony/yaml": "<5.4" },