66use PhpParser \Node \Expr \MethodCall ;
77use PhpParser \Node \Identifier ;
88use PHPStan \Analyser \Scope ;
9+ use PHPStan \Reflection \ReflectionProvider ;
910use PHPStan \Symfony \Configuration ;
1011use PHPStan \Symfony \MessageMap ;
1112use PHPStan \Symfony \MessageMapFactory ;
1920 * Configurable extension for resolving return types of methods that internally use HandleTrait.
2021 *
2122 * Configured via PHPStan parameters under symfony.messenger.handleTraitWrappers with
22- * "Class ::method" patterns, e.g.:
23+ * "class ::method" patterns, e.g.:
2324 * - App\Bus\QueryBus::dispatch
2425 * - App\Bus\QueryBus::query
2526 * - App\Bus\CommandBus::execute
@@ -37,10 +38,14 @@ final class MessengerHandleTraitWrapperReturnTypeExtension implements Expression
3738 /** @var array<string> */
3839 private $ wrappers ;
3940
40- public function __construct (MessageMapFactory $ messageMapFactory , Configuration $ configuration )
41+ /** @var ReflectionProvider */
42+ private $ reflectionProvider ;
43+
44+ public function __construct (MessageMapFactory $ messageMapFactory , Configuration $ configuration , ReflectionProvider $ reflectionProvider )
4145 {
4246 $ this ->messageMapFactory = $ messageMapFactory ;
4347 $ this ->wrappers = $ configuration ->getMessengerHandleTraitWrappers ();
48+ $ this ->reflectionProvider = $ reflectionProvider ;
4449 }
4550
4651 public function getType (Expr $ expr , Scope $ scope ): ?Type
@@ -89,8 +94,23 @@ private function isSupported(Expr $expr, Scope $scope): bool
8994 $ className = $ classNames [0 ];
9095 $ classMethodCombination = $ className . ':: ' . $ methodName ;
9196
92- // Check if this class::method combination is configured
93- return in_array ($ classMethodCombination , $ this ->wrappers , true );
97+ // Check if this exact class::method combination is configured
98+ if (in_array ($ classMethodCombination , $ this ->wrappers , true )) {
99+ return true ;
100+ }
101+
102+ // Check if any interface implemented by this class::method is configured
103+ if ($ this ->reflectionProvider ->hasClass ($ className )) {
104+ $ classReflection = $ this ->reflectionProvider ->getClass ($ className );
105+ foreach ($ classReflection ->getInterfaces () as $ interface ) {
106+ $ interfaceMethodCombination = $ interface ->getName () . ':: ' . $ methodName ;
107+ if (in_array ($ interfaceMethodCombination , $ this ->wrappers , true )) {
108+ return true ;
109+ }
110+ }
111+ }
112+
113+ return false ;
94114 }
95115
96116 private function getMessageMap (): MessageMap
0 commit comments