.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

5 comments
Comment actions Permalink

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

0
Comment actions Permalink

Well, well, well. I better get started writing s script to generate code ;-)

0
Comment actions Permalink

Michael Maier can you please share if you found a better solution or you've ended up generating code for each Repository? 

0
Comment actions Permalink

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?

0
Comment actions Permalink

Yes. Although looks like phpstan also needs them so we might have to add annotations anyway.

0

Please sign in to leave a comment.