6
6
use PhpParser \Node \Expr \MethodCall ;
7
7
use PhpParser \Node \Identifier ;
8
8
use PHPStan \Analyser \Scope ;
9
+ use PHPStan \Reflection \ReflectionProvider ;
9
10
use PHPStan \Symfony \Configuration ;
10
11
use PHPStan \Symfony \MessageMap ;
11
12
use PHPStan \Symfony \MessageMapFactory ;
19
20
* Configurable extension for resolving return types of methods that internally use HandleTrait.
20
21
*
21
22
* Configured via PHPStan parameters under symfony.messenger.handleTraitWrappers with
22
- * "Class ::method" patterns, e.g.:
23
+ * "class ::method" patterns, e.g.:
23
24
* - App\Bus\QueryBus::dispatch
24
25
* - App\Bus\QueryBus::query
25
26
* - App\Bus\CommandBus::execute
@@ -37,10 +38,14 @@ final class MessengerHandleTraitWrapperReturnTypeExtension implements Expression
37
38
/** @var array<string> */
38
39
private $ wrappers ;
39
40
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 )
41
45
{
42
46
$ this ->messageMapFactory = $ messageMapFactory ;
43
47
$ this ->wrappers = $ configuration ->getMessengerHandleTraitWrappers ();
48
+ $ this ->reflectionProvider = $ reflectionProvider ;
44
49
}
45
50
46
51
public function getType (Expr $ expr , Scope $ scope ): ?Type
@@ -89,8 +94,23 @@ private function isSupported(Expr $expr, Scope $scope): bool
89
94
$ className = $ classNames [0 ];
90
95
$ classMethodCombination = $ className . ':: ' . $ methodName ;
91
96
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 ;
94
114
}
95
115
96
116
private function getMessageMap (): MessageMap
0 commit comments