diff --git a/composer.json b/composer.json index 70ac3221..0da82d9b 100644 --- a/composer.json +++ b/composer.json @@ -30,11 +30,11 @@ }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "phpstan/phpstan": "^0.12", - "doctrine/coding-standard": "^6.0 || ^8.0", + "phpstan/phpstan": "0.12.84", + "doctrine/coding-standard": "^6.0 || ^9.0", "doctrine/common": "^3.0", "phpunit/phpunit": "^7.5.20 || ^8.0 || ^9.0", - "vimeo/psalm": "^4.3.1" + "vimeo/psalm": "4.7.0" }, "conflict": { "doctrine/common": "<2.10@dev" diff --git a/lib/Doctrine/Persistence/ManagerRegistry.php b/lib/Doctrine/Persistence/ManagerRegistry.php index 6f89e0c6..38e36a96 100644 --- a/lib/Doctrine/Persistence/ManagerRegistry.php +++ b/lib/Doctrine/Persistence/ManagerRegistry.php @@ -72,12 +72,12 @@ public function getManagerNames(); * * @param string $persistentObject The name of the persistent object. * @param string $persistentManagerName The object manager name (null for the default one). + * @psalm-param class-string $persistentObject * * @return ObjectRepository + * @psalm-return ObjectRepository * * @template T - * @psalm-param class-string $persistentObject - * @psalm-return ObjectRepository */ public function getRepository($persistentObject, $persistentManagerName = null); diff --git a/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php b/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php index 0242ce0b..a9670e3c 100644 --- a/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -33,6 +33,9 @@ * to a relational database. * * This class was abstracted from the ORM ClassMetadataFactory. + * + * @template CMTemplate of ClassMetadata + * @template-implements ClassMetadataFactory */ abstract class AbstractClassMetadataFactory implements ClassMetadataFactory { @@ -49,7 +52,10 @@ abstract class AbstractClassMetadataFactory implements ClassMetadataFactory /** @var CacheItemPoolInterface|null */ private $cache; - /** @var ClassMetadata[] */ + /** + * @var ClassMetadata[] + * @psalm-var CMTemplate[] + */ private $loadedMetadata = []; /** @var bool */ @@ -116,6 +122,7 @@ final protected function getCache(): ?CacheItemPoolInterface * Returns an array of all the loaded metadata currently in memory. * * @return ClassMetadata[] + * @psalm-return CMTemplate[] */ public function getLoadedMetadata() { @@ -123,10 +130,7 @@ public function getLoadedMetadata() } /** - * Forces the factory to load the metadata of all classes known to the underlying - * mapping driver. - * - * @return ClassMetadata[] The ClassMetadata instances of all mapped classes. + * {@inheritDoc} */ public function getAllMetadata() { @@ -176,6 +180,8 @@ abstract protected function getDriver(); /** * Wakes up reflection after ClassMetadata gets unserialized from cache. * + * @psalm-param CMTemplate $class + * * @return void */ abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService); @@ -183,6 +189,8 @@ abstract protected function wakeupReflection(ClassMetadata $class, ReflectionSer /** * Initializes Reflection after ClassMetadata was constructed. * + * @psalm-param CMTemplate $class + * * @return void */ abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService); @@ -192,16 +200,14 @@ abstract protected function initializeReflection(ClassMetadata $class, Reflectio * * This method should return false for mapped superclasses or embedded classes. * + * @psalm-param CMTemplate $class + * * @return bool */ abstract protected function isEntity(ClassMetadata $class); /** - * Gets the class metadata descriptor for a class. - * - * @param string $className The name of the class. - * - * @return ClassMetadata + * {@inheritDoc} * * @throws ReflectionException * @throws MappingException @@ -232,6 +238,7 @@ public function getMetadataFor($className) if ($this->cache) { $cached = $this->cache->getItem($this->getCacheKey($realClassName))->get(); if ($cached instanceof ClassMetadata) { + /** @psalm-var CMTemplate $cached */ $this->loadedMetadata[$realClassName] = $cached; $this->wakeupReflection($cached, $this->getReflectionService()); @@ -275,11 +282,7 @@ public function getMetadataFor($className) } /** - * Checks whether the factory has the metadata for a class loaded already. - * - * @param string $className - * - * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + * {@inheritDoc} */ public function hasMetadataFor($className) { @@ -291,8 +294,7 @@ public function hasMetadataFor($className) * * NOTE: This is only useful in very special cases, like when generating proxy classes. * - * @param string $className - * @param ClassMetadata $class + * {@inheritDoc} * * @return void */ @@ -395,6 +397,7 @@ protected function loadMetadata($name) * @param string $className * * @return ClassMetadata|null + * @psalm-return CMTemplate|null */ protected function onNotFoundMetadata($className) { @@ -409,6 +412,8 @@ protected function onNotFoundMetadata($className) * @param bool $rootEntityFound * @param string[] $nonSuperclassParents All parent class names * that are not marked as mapped superclasses. + * @psalm-param CMTemplate $class + * @psalm-param CMTemplate|null $parent * * @return void */ @@ -420,6 +425,7 @@ abstract protected function doLoadMetadata($class, $parent, $rootEntityFound, ar * @param string $className * * @return ClassMetadata + * @psalm-return CMTemplate */ abstract protected function newClassMetadataInstance($className); @@ -473,9 +479,11 @@ protected function getCacheKey(string $realClassName): string /** * Gets the real class name of a class name that could be a proxy. * - * @template T of object * @psalm-param class-string>|class-string $class + * * @psalm-return class-string + * + * @template T of object */ private function getRealClass(string $class): string { @@ -490,9 +498,11 @@ private function createDefaultProxyClassNameResolver(): void { $this->proxyClassNameResolver = new class implements ProxyClassNameResolver { /** - * @template T of object * @psalm-param class-string>|class-string $className + * * @psalm-return class-string + * + * @template T of object */ public function resolveClassName(string $className): string { diff --git a/lib/Doctrine/Persistence/Mapping/ClassMetadata.php b/lib/Doctrine/Persistence/Mapping/ClassMetadata.php index 5b60d2cd..daaa0954 100644 --- a/lib/Doctrine/Persistence/Mapping/ClassMetadata.php +++ b/lib/Doctrine/Persistence/Mapping/ClassMetadata.php @@ -120,7 +120,6 @@ public function getTypeOfField($fieldName); * @param string $assocName * * @return string - * * @psalm-return class-string */ public function getAssociationTargetClass($assocName); diff --git a/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php b/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php index 8b78239f..f748f52e 100644 --- a/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php @@ -4,6 +4,8 @@ /** * Contract for a Doctrine persistence layer ClassMetadata class to implement. + * + * @template T of ClassMetadata */ interface ClassMetadataFactory { @@ -12,6 +14,7 @@ interface ClassMetadataFactory * mapping driver. * * @return ClassMetadata[] The ClassMetadata instances of all mapped classes. + * @psalm-return T[] */ public function getAllMetadata(); @@ -21,6 +24,7 @@ public function getAllMetadata(); * @param string $className The name of the class. * * @return ClassMetadata + * @psalm-return T */ public function getMetadataFor($className); @@ -38,6 +42,7 @@ public function hasMetadataFor($className); * * @param string $className * @param ClassMetadata $class + * @psalm-param T $class */ public function setMetadataFor($className, $class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php b/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php index 00cf4397..3f32aba3 100644 --- a/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php +++ b/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php @@ -141,7 +141,6 @@ public function getAllClassNames() * @param string $file The mapping file to load. * * @return ClassMetadata[] - * * @psalm-return array */ abstract protected function loadMappingFile($file); diff --git a/lib/Doctrine/Persistence/Mapping/ProxyClassNameResolver.php b/lib/Doctrine/Persistence/Mapping/ProxyClassNameResolver.php index bfb433ff..a8a3fcc8 100644 --- a/lib/Doctrine/Persistence/Mapping/ProxyClassNameResolver.php +++ b/lib/Doctrine/Persistence/Mapping/ProxyClassNameResolver.php @@ -7,9 +7,11 @@ interface ProxyClassNameResolver { /** - * @template T of object * @psalm-param class-string>|class-string $className + * * @psalm-return class-string + * + * @template T of object */ public function resolveClassName(string $className): string; } diff --git a/lib/Doctrine/Persistence/ObjectManager.php b/lib/Doctrine/Persistence/ObjectManager.php index 1d6dc0f3..70f9e431 100644 --- a/lib/Doctrine/Persistence/ObjectManager.php +++ b/lib/Doctrine/Persistence/ObjectManager.php @@ -17,12 +17,12 @@ interface ObjectManager * * @param string $className The class name of the object to find. * @param mixed $id The identity of the object to find. + * @psalm-param class-string $className * * @return object|null The found object. + * @psalm-return T|null * * @template T - * @psalm-param class-string $className - * @psalm-return T|null */ public function find($className, $id); @@ -115,12 +115,12 @@ public function flush(); * Gets the repository for a class. * * @param string $className + * @psalm-param class-string $className * * @return ObjectRepository + * @psalm-return ObjectRepository * * @template T - * @psalm-param class-string $className - * @psalm-return ObjectRepository */ public function getRepository($className); diff --git a/lib/Doctrine/Persistence/ObjectRepository.php b/lib/Doctrine/Persistence/ObjectRepository.php index dbfad989..e6a2f550 100644 --- a/lib/Doctrine/Persistence/ObjectRepository.php +++ b/lib/Doctrine/Persistence/ObjectRepository.php @@ -17,7 +17,6 @@ interface ObjectRepository * @param mixed $id The identifier. * * @return object|null The object. - * * @psalm-return T|null */ public function find($id); @@ -26,7 +25,6 @@ public function find($id); * Finds all objects in the repository. * * @return array The objects. - * * @psalm-return T[] */ public function findAll(); @@ -42,13 +40,12 @@ public function findAll(); * @param string[]|null $orderBy * @param int|null $limit * @param int|null $offset + * @psalm-param array $orderBy * * @return object[] The objects. + * @psalm-return T[] * * @throws UnexpectedValueException - * - * @psalm-param array $orderBy - * @psalm-return T[] */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null); @@ -58,7 +55,6 @@ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $ * @param mixed[] $criteria The criteria. * * @return object|null The object. - * * @psalm-return T|null */ public function findOneBy(array $criteria); diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 8f33cb41..1376d0e2 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -52,12 +52,4 @@ lib/Doctrine/Persistence/Mapping/MappingException.php - - - RuntimeReflectionServiceTest - - - - tests/Doctrine/Tests_PHP74/Persistence/Reflection/TypedNoDefaultReflectionPropertyTest.php - diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 02cdbc1d..ca4f755a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6,9 +6,3 @@ parameters: message: "#^Parameter \\#3 \\$nsSeparator of class Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\SymfonyFileLocator constructor expects string, null given\\.$#" count: 1 path: tests/Doctrine/Tests/Persistence/Mapping/SymfonyFileLocatorTest.php - - - - # Remove it when https://github.com/phpstan/phpstan/issues/4803 is solved - message: "#^Method Doctrine\\\\Persistence\\\\Mapping\\\\AbstractClassMetadataFactory\\:\\:getRealClass\\(\\) should return class\\-string\\ but returns class\\-string\\\\|T of object\\>\\.$#" - count: 1 - path: lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php