Skip to content

Commit

Permalink
[Serializer] Deprecate annotations in favor of attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus committed Jul 20, 2023
1 parent 0458c9b commit 4c78f50
Show file tree
Hide file tree
Showing 43 changed files with 537 additions and 358 deletions.
6 changes: 6 additions & 0 deletions UPGRADE-6.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,9 @@ Security
* `UserValueResolver` no longer implements `ArgumentValueResolverInterface`
* Make `PersistentToken` immutable
* Deprecate accepting only `DateTime` for `TokenProviderInterface::updateToken()`, use `DateTimeInterface` instead

Serializer
----------

* Deprecate Doctrine annotations support in favor of native attributes
* Deprecate passing an annotation reader to the constructor of `AnnotationLoader`
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
*/
class SerializerModelFixture
{
/**
* @Groups({"read"})
*/
#[Groups(['read'])]
public $name = 'howdy';

public $title = 'fixture';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace Symfony\Bridge\Twig\Tests\Extension;

use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Twig\Extension\SerializerExtension;
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
Expand Down Expand Up @@ -50,7 +49,7 @@ public static function serializerDataProvider(): \Generator

private function getTwig(string $template): Environment
{
$meta = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$meta = new ClassMetadataFactory(new AnnotationLoader());
$runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()]));

$mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class);
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bridge/Twig/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"twig/twig": "^2.13|^3.0.4"
},
"require-dev": {
"doctrine/annotations": "^1.12|^2",
"egulias/email-validator": "^2.1.10|^3|^4",
"league/html-to-markdown": "^5.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
Expand Down Expand Up @@ -62,6 +61,7 @@
"symfony/http-foundation": "<5.4",
"symfony/http-kernel": "<6.2",
"symfony/mime": "<6.2",
"symfony/serializer": "<6.2",
"symfony/translation": "<5.4",
"symfony/workflow": "<5.4"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

namespace Symfony\Component\PropertyInfo\Tests\Extractor;

use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\SerializerExtractor;
use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy;
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;
Expand All @@ -24,22 +24,19 @@
*/
class SerializerExtractorTest extends TestCase
{
/**
* @var SerializerExtractor
*/
private $extractor;
private SerializerExtractor $extractor;

protected function setUp(): void
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader());
$this->extractor = new SerializerExtractor($classMetadataFactory);
}

public function testGetProperties()
{
$this->assertEquals(
['collection'],
$this->extractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', ['serializer_groups' => ['a']])
$this->extractor->getProperties(Dummy::class, ['serializer_groups' => ['a']])
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class Dummy extends ParentDummy

/**
* @var \DateTimeImmutable[]
* @Groups({"a", "b"})
*/
#[Groups(['a', 'b'])]
public $collection;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,9 @@
*/
class IgnorePropertyDummy
{
/**
* @Groups({"a"})
*/
#[Groups(['a'])]
public $visibleProperty;

/**
* @Groups({"a"})
* @Ignore
*/
#[Groups(['a']), Ignore]
private $ignoredProperty;
}
6 changes: 3 additions & 3 deletions src/Symfony/Component/PropertyInfo/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
"symfony/cache": "^5.4|^6.0|^7.0",
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
"phpdocumentor/reflection-docblock": "^5.2",
"phpstan/phpdoc-parser": "^1.0",
"doctrine/annotations": "^1.10.4|^2"
"phpstan/phpdoc-parser": "^1.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<5.2",
"phpdocumentor/type-resolver": "<1.5.1",
"symfony/dependency-injection": "<5.4"
"symfony/dependency-injection": "<5.4",
"symfony/serializer": "<5.4"
},
"autoload": {
"psr-4": { "Symfony\\Component\\PropertyInfo\\": "" },
Expand Down
6 changes: 6 additions & 0 deletions src/Symfony/Component/Serializer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
CHANGELOG
=========

6.4
---

* Deprecate Doctrine annotations support in favor of native attributes
* Deprecate passing an annotation reader to the constructor of `AnnotationLoader`

6.3
---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class AnnotationLoader implements LoaderInterface
public function __construct(
private readonly ?Reader $reader = null,
) {
if ($reader) {
trigger_deprecation('symfony/validator', '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
Expand Down Expand Up @@ -163,10 +166,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
return $loaded;
}

/**
* @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflector
*/
public function loadAnnotations(object $reflector): iterable
public function loadAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable
{
foreach ($reflector->getAttributes() as $attribute) {
if ($this->isKnownAttribute($attribute->getName())) {
Expand All @@ -193,13 +193,13 @@ public function loadAnnotations(object $reflector): iterable
}

if ($reflector instanceof \ReflectionClass) {
yield from $this->reader->getClassAnnotations($reflector);
yield from $this->getClassAnnotations($reflector);
}
if ($reflector instanceof \ReflectionMethod) {
yield from $this->reader->getMethodAnnotations($reflector);
yield from $this->getMethodAnnotations($reflector);
}
if ($reflector instanceof \ReflectionProperty) {
yield from $this->reader->getPropertyAnnotations($reflector);
yield from $this->getPropertyAnnotations($reflector);
}
}

Expand Down Expand Up @@ -229,4 +229,49 @@ private function isKnownAttribute(string $attributeName): bool

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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Tests\Fixtures\ChildOfGroupsAnnotationDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyInterface;
use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyInterface;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Serializer\Tests\Fixtures;
namespace Symfony\Component\Serializer\Tests\Fixtures\Annotations;

use Symfony\Component\Serializer\Annotation\Groups;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Tests\Fixtures\ChildOfGroupsAnnotationDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyInterface;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Serializer\Tests\Fixtures\Annotations;
namespace Symfony\Component\Serializer\Tests\Fixtures\Attributes;

class GroupDummyChild extends GroupDummy
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?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\Serializer\Tests\Fixtures\Attributes;

use Symfony\Component\Serializer\Annotation\Groups;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface GroupDummyInterface
{
#[Groups(['a', 'name_converter'])]
public function getSymfony();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;

/**
* @DiscriminatorMap(typeProperty="type", mapping={
* "one"="Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberOne",
* "two"="Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberTwo"
* })
*
* @author Samuel Roze <samuel.roze@gmail.com>
*/
#[DiscriminatorMap(typeProperty: 'type', mapping: [
'one' => DummyMessageNumberOne::class,
'two' => DummyMessageNumberTwo::class,
])]
interface DummyMessageInterface
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class DummyMessageNumberOne implements DummyMessageInterface
{
public $one;

/**
* @Groups({"two"})
*/
#[Groups(['two'])]
public $two;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
*/
class OtherSerializedNameDummy
{
/**
* @Groups({"a"})
*/
#[Groups(['a'])]
private $buz;

public function setBuz($buz)
Expand All @@ -34,10 +32,7 @@ public function getBuz()
return $this->buz;
}

/**
* @Groups({"b"})
* @SerializedName("buz")
*/
#[Groups(['b']), SerializedName('buz')]
public function getBuzForExport()
{
return $this->buz.' Rocks';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy':
'Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy':
attributes:
ignored1:
ignore: foo

0 comments on commit 4c78f50

Please sign in to comment.