-
Hello, Here is some code from the library Foundry: https://psalm.dev/r/7aa724d1ab Foundry is a lib which helps to create fixtures, mainly in Symfony's projects. we want to keep the I'm looking for a solution in our side: maybe by creating a Psalm's plugin ? that's how we've resolved the problem with PHPStan, but I didn't managed to find the solution with Psalm. Thank you for your help :) |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 2 replies
-
By that do you mean that you can't know in which class that annotation will be? Otherwise, I would have suggested to try stubbing the class, but if you don't have control over it, this possibility is out |
Beta Was this translation helpful? Give feedback.
-
Hi, thanks for your answer no, we don't know the class where is the annotation, all we know is that the class extends our abstract class I think stubs are not an option since there could be dozens of children of |
Beta Was this translation helpful? Give feedback.
-
Indeed. So yeah, plugins may be the solution. I believe AfterClassLikeVisitInterface could be the solution, you'll have to retrieve the class storage then method storage to change those. Beware, this plugin is called only when populating cache (which means you'll have to use --no-cache during development) |
Beta Was this translation helpful? Give feedback.
-
thanks a lot @orklah for this hint, I'm gonna test this in few days, and let you know :) |
Beta Was this translation helpful? Give feedback.
-
Hi @orklah let's take a precise case: /**
* @template T of object
*/
abstract class Factory
{
/**
* @return Proxy<T>
*/
final public static function find($criteria): Proxy in the child class (in userland) here is how it is described: /**
* @extends Factory<Post>
*
* @method static Post|Proxy find(object|array|mixed $criteria)
*/
final class PostFactory extends Factory Psalm reports the following error: ERROR: ImplementedReturnTypeMismatch - path/to/PostFactory.php:16:19 - The inherited return type 'Zenstruck\Foundry\Proxy<Zenstruck\Foundry\Tests\Fixtures\Entity\Post>' for Zenstruck\Foundry\Factory::find is different to the implemented return type for Zenstruck\Foundry\Factory::find 'Zenstruck\Foundry\Proxy|Zenstruck\Foundry\Tests\Fixtures\Entity\Post' seems legit: the parent returns a generic type, but the child returns an union type. By playing around with final class AfterClassLikeVisit implements AfterClassLikeVisitInterface
{
public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)
{
if (is_a($event->getStorage()->name, Factory::class, true)) {
foreach ($event->getStorage()->methods as $method) {
if ($method->cased_name === 'find') {
// what should I modify here?
}
}
}
}
} I've tried several things like that, but it's not working: $method->return_type = $method->signature_return_type = new Type\Union(
[
new Type\Atomic\TGenericObject(
Proxy::class,
[new Type\Union([new Type\Atomic\TNamedObject(Post::class)])]
),
]
); I also tried When I dump the whole
The thanks for your help! |
Beta Was this translation helpful? Give feedback.
If you're trying to acces
@method
, I think they're in here instead:psalm/src/Psalm/Storage/ClassLikeStorage.php
Line 242 in 086b943
I think emptying that entire property should be enough to make Psalm be unaware of any
@method
on this class