.phpstorm.meta.php: How to type generic container
I'm using Doctrine which has a class called EntityManager that has a method EntityManager::getRepository, which returns an EntityRepository object. The repository has i.a. a method find that returns an object of the type passed to EntityManager::getRepository. Here is a simplified example that mimics this code structure:
<?php
namespace repository;
class Foo {}
class Bar {}
interface EntityManager {
function get($name);
}
/** @var EntityManager $entityManager */
$fooRepository = $entityManager->get(\repository\Foo::class);
$foo = $fooRepository->find(1);
$barRepository = $entityManager->get(\repository\Bar::class);
$bar = $barRepository->find(1);
$obj = $entityManager->get('whatever')->find(1);
The type of $fooRepository, $barRepository, $foo, $bar and $obj is not known here. I use .phpstorm.meta.php to fix this:
<?php
interface FooRepository {
/** @return Foo */
function find($id);
}
interface BarRepository {
/** @return Bar */
function find($id);
}
namespace PHPSTORM_META {
override(\repository\EntityManager::get(0), map([
'\repository\Foo' => 'FooRepository',
'\repository\Bar' => 'BarRepository',
'' => 'object',
]));
}
Now $fooRepository is of type FooRepository and $foo is of type Foo. $barRepository is of type BarRepository and $bar is of type Bar. $obj is of type object. Everything is like expected. However, it is quite verbose and cumbersome to create such a generic *Repository interface for each class. Is there a generic approach?
--
IntelliJ IDEA 2019.3.3 (Ultimate Edition)
Build #IU-193.6494.35, built on February 11, 2020
Runtime version: 11.0.5+10-b520.38 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.14.6
PHP Plugin Version: 193.6494.35
Please sign in to leave a comment.
Unfortunately, the pattern syntax we have right now (the
@lookup pattern) won't let you process parameters as complex as you want. You can include the parameter in the type name, but that's it.Please vote: https://youtrack.jetbrains.com/issue/WI-27832
Well, well, well. I better get started writing s script to generate code ;-)
Michael Maier can you please share if you found a better solution or you've ended up generating code for each Repository?
To my knowledge there is no better solution than a script for code generation, but I have not yet found the time to write one. If I wrote one, I'll share it here. Are you also looking for a solution for Doctrine repositories?
Yes. Although looks like phpstan also needs them so we might have to add annotations anyway.