phpstan-symfony icon indicating copy to clipboard operation
phpstan-symfony copied to clipboard

Support for Messenger HandleTrait return types

Open bnowak opened this issue 1 year ago • 2 comments

The goal is to cover https://github.com/phpstan/phpstan-symfony/issues/207.

That's my very first PR in phpstan-symfony plugin, so any feedback/tips/advices are very welcome :)

bnowak avatar Aug 13 '24 09:08 bnowak

@ondrejmirtes Thanks for the tip about ExpressionTypeResolverExtension! It resolved my blocker issue about not supported traits in DynamicMethodReturnTypeExtension.

It took me some time, however finally I've got ready to review version of this PR :) Please take a look in you free time :)

Thank you very much!

bnowak avatar Oct 17 '24 14:10 bnowak

As static analyzing should works now fine with the result of HandleTrait::handle, but only in classes which have statically typed query passed - like in this SF-adjusted example:

// src/Action/ListItems.php
namespace App\Action;

use App\Message\ListItemsQuery;
use App\MessageHandler\ListItemsQueryResult;
use Symfony\Component\Messenger\HandleTrait;
use Symfony\Component\Messenger\MessageBusInterface;

class ListItems
{
    use HandleTrait;

    public function __construct(
        private MessageBusInterface $messageBus,
    ) {
    }

    public function __invoke(): void
    {
        $result = $this->handle(new ListItemsQuery(/* ... */));
        // $result should be automatically recognized as `ListItemsQueryResult` now by phpstan via SF configuration

        // Do something with the result
        // ...
    }
}

However, my target goal was to cover QueryBus classes with dynamic return types based on dynamic query, something like:

// src/MessageBus/QueryBus.php
namespace App\MessageBus;

use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\HandleTrait;
use Symfony\Component\Messenger\MessageBusInterface;

class QueryBus
{
    use HandleTrait;

    public function __construct(
        private MessageBusInterface $messageBus,
    ) {
    }

    // wherever that method is called, phpstan should recognize return type based on passed query
    public function query($query)
    {
        return $this->handle($query);
    }
}

Maybe it's trivial and doable with already existing php-doc annotation or more complex to write some next extension for that, but I don't know how to connect the dots and reuse covered typing of HandleTrait::handle which is already in place. I'm happy to address that in separate PR (if will be needed to achieve that) :) Any thoughts/ideas are more than welcome :) /cc @ondrejmirtes

bnowak avatar Oct 17 '24 14:10 bnowak

@ondrejmirtes any chances to review that, please? :pray:

bnowak avatar Nov 20 '24 13:11 bnowak

@ondrejmirtes I can see that version 2.0.0 is released now. Is 1.x abandoned from now? Should I rebase that PR to 2.x branch? Any chances to review and/or merge it please? :slightly_smiling_face:

bnowak avatar Dec 18 '24 07:12 bnowak

@ondrejmirtes Thanks for review. I addressed all your comments, please take a look again when you have time :)

Also, could you take a look on https://github.com/phpstan/phpstan-symfony/pull/404#issuecomment-2419761831 and answer that if you have an idea how to solve it please? That's my initial goal to resolve by this PR :)

bnowak avatar Dec 23 '24 08:12 bnowak

@ondrejmirtes both comments fixed. Could you re-check? Thanks, in advance :)

bnowak avatar Dec 30 '24 06:12 bnowak

Thank you. Please be available if any issues arise.

ondrejmirtes avatar Jan 04 '25 13:01 ondrejmirtes

@ondrejmirtes Thank you for merging and your help with reviewing that :)

Could you take a look on https://github.com/phpstan/phpstan-symfony/pull/404#issuecomment-2419761831 comment please 🙏 I'm not sure whether I should create separate issue for that? Maybe it's able to achive with already existing features/annotations? If not, do you have an idea how to implement such feature?

bnowak avatar Jan 04 '25 16:01 bnowak

@bnowak Feel free to send a failing test so I can understand it better.

ondrejmirtes avatar Jan 05 '25 12:01 ondrejmirtes

Hi, since MessageSubscriberInterface has been deprecated/removed in favour of #[AsMessageHandler], shouldn't the code in MessageMapFactory be adjusted to also support the attribute? Thanks.

ondrejmirtes avatar Jul 10 '25 11:07 ondrejmirtes

@ondrejmirtes I'll take a look on that tomorrow. Thanks for info :wink:

bnowak avatar Jul 10 '25 11:07 bnowak

Maybe it's the reason why some of the tests are failing on Symfony 7.3, maybe not: https://github.com/phpstan/phpstan-symfony/actions/runs/16193692378/job/45715050598?pr=447

ondrejmirtes avatar Jul 10 '25 11:07 ondrejmirtes

Yes it is. I started working on tests separation and skipping the case when MessageSubscriberInterface is missing (SF <7.0). Tomorrow, I'll push PR for that.

Regarding adding support for #[AsMessageHandler] - I'll handle that in separate PR, no problem. However, I think firstly before that, it would be nice to have support for SF 7.3 in tests (work which you started in https://github.com/phpstan/phpstan-symfony/pull/447/files). Then, I'd add that support.

@ondrejmirtes What do you think? Does such order make sense?

bnowak avatar Jul 10 '25 12:07 bnowak

I think AsMessageHandler already existed before Symfony 7, didn't it?

It'd make it easy to implement it here, and when my symfony-7-3 is rebased, less tests should fail.

ondrejmirtes avatar Jul 10 '25 13:07 ondrejmirtes

Ahh, you're right. I don't know why I assumed it was introduced in 7.0 😅

Tomorrow will try to handle both topics 😉

bnowak avatar Jul 10 '25 14:07 bnowak

@ondrejmirtes please review https://github.com/phpstan/phpstan-symfony/pull/448.

Regarding AsMessageHandler support - it's just tag for auto configuring it during kernel boot, so its result is generated container xml file definition which this plugin read from (the same as messenger handle trait feature). Given that, it should be supported by default and additional tests are not needed IMO.

bnowak avatar Jul 11 '25 09:07 bnowak