From cd57768b0801ed380b372654a8db5edef5d38543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 14 Mar 2022 22:55:16 +0100 Subject: [PATCH] Implement colocated mapping driver This allows us to decouple further from doctrine/annotations, and to fix some static analysis issues. The assumption being made here is that the abstract class we are no longer extending is not used in type declarations and instanceof checks. --- UPGRADE.md | 10 +++ composer.json | 2 +- .../ORM/Mapping/Driver/AnnotationDriver.php | 65 ++++++++++++++++++- .../ORM/Mapping/Driver/AttributeDriver.php | 29 ++++++++- phpstan-baseline.neon | 10 --- psalm-baseline.xml | 7 -- 6 files changed, 101 insertions(+), 22 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 8e349c90204..61b6280261d 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,15 @@ # Upgrade to 2.12 +## BC Break: `AttributeDriver` and `AnnotationDriver` no longer extends parent class from `doctrine/persistence` + +Both these classes used to extend an abstract `AnnotationDriver` class defined +in `doctrine/persistence`, and no longer do. + +## Deprecate `AttributeDriver::getReader()` and `AnnotationDriver::getReader()` + +That method was inherited from the abstract `AnnotationDriver` class of +`doctrine/persistence`, and does not seem to serve any purpose. + ## Un-deprecate `Doctrine\ORM\Proxy\Proxy` Because no forward-compatible new proxy solution had been implemented yet, the diff --git a/composer.json b/composer.json index 6a238bffed6..49c906e43b4 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3", "doctrine/lexer": "^1.2.3", - "doctrine/persistence": "^2.2", + "doctrine/persistence": "^2.4", "psr/cache": "^1 || ^2 || ^3", "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", "symfony/polyfill-php72": "^1.23", diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index e9f09210ae2..bdd1784c7c8 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -5,13 +5,16 @@ namespace Doctrine\ORM\Mapping\Driver; use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Common\Annotations\Reader; +use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping; use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException; use Doctrine\Persistence\Mapping\ClassMetadata; -use Doctrine\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver; +use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; use ReflectionClass; use ReflectionMethod; use ReflectionProperty; @@ -29,8 +32,19 @@ /** * The AnnotationDriver reads the mapping metadata from docblock annotations. */ -class AnnotationDriver extends AbstractAnnotationDriver +class AnnotationDriver implements MappingDriver { + use ColocatedMappingDriver; + + /** + * The annotation reader. + * + * @internal this property will be private in 3.0 + * + * @var Reader + */ + protected $reader; + /** * @var int[] * @psalm-var array @@ -40,6 +54,20 @@ class AnnotationDriver extends AbstractAnnotationDriver Mapping\MappedSuperclass::class => 2, ]; + /** + * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading + * docblock annotations. + * + * @param Reader $reader The AnnotationReader to use + * @param string|string[]|null $paths One or multiple paths where mapping classes can be found. + */ + public function __construct($reader, $paths = null) + { + $this->reader = $reader; + + $this->addPaths((array) $paths); + } + /** * {@inheritDoc} */ @@ -786,6 +814,39 @@ private function columnToArray(string $fieldName, Mapping\Column $column): array return $mapping; } + /** + * Retrieve the current annotation reader + * + * @return Reader + */ + public function getReader() + { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/9587', + '%s is deprecated with no replacement', + __METHOD__ + ); + + return $this->reader; + } + + /** + * {@inheritDoc} + */ + public function isTransient($className) + { + $classAnnotations = $this->reader->getClassAnnotations(new ReflectionClass($className)); + + foreach ($classAnnotations as $annot) { + if (isset($this->entityAnnotationClasses[get_class($annot)])) { + return false; + } + } + + return true; + } + /** * Factory method for the Annotation Driver. * diff --git a/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php index a721e8d38f0..99d92a0534a 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php @@ -4,13 +4,15 @@ namespace Doctrine\ORM\Mapping\Driver; +use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping; use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException; use Doctrine\Persistence\Mapping\ClassMetadata; -use Doctrine\Persistence\Mapping\Driver\AnnotationDriver; +use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; use LogicException; use ReflectionClass; use ReflectionMethod; @@ -25,8 +27,10 @@ use const PHP_VERSION_ID; -class AttributeDriver extends AnnotationDriver +class AttributeDriver implements MappingDriver { + use ColocatedMappingDriver; + /** @var array */ // @phpcs:ignore protected $entityAnnotationClasses = [ @@ -37,6 +41,8 @@ class AttributeDriver extends AnnotationDriver /** * The annotation reader. * + * @internal this property will be private in 3.0 + * * @var AttributeReader */ protected $reader; @@ -57,6 +63,25 @@ public function __construct(array $paths) $this->addPaths($paths); } + /** + * Retrieve the current annotation reader + * + * @deprecated no replacement planned. + * + * @return AttributeReader + */ + public function getReader() + { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/9587', + '%s is deprecated with no replacement', + __METHOD__ + ); + + return $this->reader; + } + /** * {@inheritDoc} */ diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 66ed3c06148..684c90e6ba0 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -260,16 +260,6 @@ parameters: count: 1 path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php - - - message: "#^PHPDoc type Doctrine\\\\ORM\\\\Mapping\\\\Driver\\\\AttributeReader of property Doctrine\\\\ORM\\\\Mapping\\\\Driver\\\\AttributeDriver\\:\\:\\$reader is not covariant with PHPDoc type Doctrine\\\\Common\\\\Annotations\\\\Reader of overridden property Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\AnnotationDriver\\:\\:\\$reader\\.$#" - count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php - - - - message: "#^PHPDoc type array\\ of property Doctrine\\\\ORM\\\\Mapping\\\\Driver\\\\AttributeDriver\\:\\:\\$entityAnnotationClasses is not covariant with PHPDoc type array\\ of overridden property Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\AnnotationDriver\\:\\:\\$entityAnnotationClasses\\.$#" - count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php - - message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo&Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\ given\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 376fe2e32cb..d16abe18bd1 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -747,9 +747,6 @@ $mapping - - $entityAnnotationClasses - $listenerClassName @@ -782,10 +779,6 @@ $mapping - - $entityAnnotationClasses - $reader - $listenerClassName