From 2910fcc20ad41035befb50b8c723a68924566a69 Mon Sep 17 00:00:00 2001 From: Fred Cox Date: Tue, 12 Feb 2019 10:27:04 +0200 Subject: [PATCH] ManagerRegistry::getRepository returns correct EntityRepository --- extension.neon | 6 +++ ...etRepositoryDynamicReturnTypeExtension.php | 48 +++++++++++++++++++ ...etRepositoryDynamicReturnTypeExtension.php | 13 +++++ ...etRepositoryDynamicReturnTypeExtension.php | 42 +--------------- .../ManagerRegistryIntegrationTest.php | 35 ++++++++++++++ ...agerRegistryRepositoryDynamicReturn-2.json | 7 +++ ...managerRegistryRepositoryDynamicReturn.php | 48 +++++++++++++++++++ .../Persistence/phpstan.neon | 2 + 8 files changed, 160 insertions(+), 41 deletions(-) create mode 100644 src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php create mode 100644 src/Type/Doctrine/ManagerRegistryGetRepositoryDynamicReturnTypeExtension.php create mode 100644 tests/DoctrineIntegration/Persistence/ManagerRegistryIntegrationTest.php create mode 100644 tests/DoctrineIntegration/Persistence/data/managerRegistryRepositoryDynamicReturn-2.json create mode 100644 tests/DoctrineIntegration/Persistence/data/managerRegistryRepositoryDynamicReturn.php create mode 100644 tests/DoctrineIntegration/Persistence/phpstan.neon diff --git a/extension.neon b/extension.neon index 87b2841a..4a8c5099 100644 --- a/extension.neon +++ b/extension.neon @@ -32,3 +32,9 @@ services: class: PHPStan\Type\Doctrine\ObjectRepositoryDynamicReturnTypeExtension tags: - phpstan.broker.dynamicMethodReturnTypeExtension + - + class: PHPStan\Type\Doctrine\ManagerRegistryGetRepositoryDynamicReturnTypeExtension + arguments: + repositoryClass: %doctrine.repositoryClass% + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension diff --git a/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php new file mode 100644 index 00000000..ffac342b --- /dev/null +++ b/src/Type/Doctrine/GetRepositoryDynamicReturnTypeExtension.php @@ -0,0 +1,48 @@ +repositoryClass = $repositoryClass; + } + + public function isMethodSupported(MethodReflection $methodReflection): bool + { + return $methodReflection->getName() === 'getRepository'; + } + + public function getTypeFromMethodCall( + MethodReflection $methodReflection, + MethodCall $methodCall, + Scope $scope + ): Type + { + if (count($methodCall->args) === 0) { + return ParametersAcceptorSelector::selectSingle( + $methodReflection->getVariants() + )->getReturnType(); + } + $argType = $scope->getType($methodCall->args[0]->value); + if (!$argType instanceof ConstantStringType) { + return new MixedType(); + } + + return new ObjectRepositoryType($argType->getValue(), $this->repositoryClass); + } + +} diff --git a/src/Type/Doctrine/ManagerRegistryGetRepositoryDynamicReturnTypeExtension.php b/src/Type/Doctrine/ManagerRegistryGetRepositoryDynamicReturnTypeExtension.php new file mode 100644 index 00000000..c0dad891 --- /dev/null +++ b/src/Type/Doctrine/ManagerRegistryGetRepositoryDynamicReturnTypeExtension.php @@ -0,0 +1,13 @@ +repositoryClass = $repositoryClass; - } - public function getClass(): string { return 'Doctrine\Common\Persistence\ObjectManager'; } - public function isMethodSupported(MethodReflection $methodReflection): bool - { - return $methodReflection->getName() === 'getRepository'; - } - - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type - { - if (count($methodCall->args) === 0) { - return ParametersAcceptorSelector::selectSingle( - $methodReflection->getVariants() - )->getReturnType(); - } - $argType = $scope->getType($methodCall->args[0]->value); - if (!$argType instanceof ConstantStringType) { - return new MixedType(); - } - - return new ObjectRepositoryType($argType->getValue(), $this->repositoryClass); - } - } diff --git a/tests/DoctrineIntegration/Persistence/ManagerRegistryIntegrationTest.php b/tests/DoctrineIntegration/Persistence/ManagerRegistryIntegrationTest.php new file mode 100644 index 00000000..14378ef9 --- /dev/null +++ b/tests/DoctrineIntegration/Persistence/ManagerRegistryIntegrationTest.php @@ -0,0 +1,35 @@ +::nonexistant().", + "line": 31, + "ignorable": true + } +] \ No newline at end of file diff --git a/tests/DoctrineIntegration/Persistence/data/managerRegistryRepositoryDynamicReturn.php b/tests/DoctrineIntegration/Persistence/data/managerRegistryRepositoryDynamicReturn.php new file mode 100644 index 00000000..a74ddeb6 --- /dev/null +++ b/tests/DoctrineIntegration/Persistence/data/managerRegistryRepositoryDynamicReturn.php @@ -0,0 +1,48 @@ +managerRegistry = $managerRegistry; + } + + public function findDynamicType(): void + { + $test = $this->managerRegistry->getRepository(MyEntity::class)->createQueryBuilder('e'); + + $test->getQuery(); + } + + public function errorWithDynamicType(): void + { + $this->managerRegistry->getRepository(MyEntity::class)->nonexistant(); + } +} + +/** + * @ORM\Entity() + */ +class MyEntity +{ + /** + * @ORM\Id() + * @ORM\GeneratedValue() + * @ORM\Column(type="integer") + * + * @var int + */ + private $id; +} diff --git a/tests/DoctrineIntegration/Persistence/phpstan.neon b/tests/DoctrineIntegration/Persistence/phpstan.neon new file mode 100644 index 00000000..e6dd2808 --- /dev/null +++ b/tests/DoctrineIntegration/Persistence/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../../extension.neon