5
5
use PHPStan \Reflection \ClassReflection ;
6
6
use PHPStan \Reflection \ParametersAcceptorSelector ;
7
7
use PHPStan \Reflection \ReflectionProvider ;
8
- use PHPStan \Type \ObjectType ;
9
- use PHPStan \Type \UnionType ;
10
8
use RuntimeException ;
11
9
use Symfony \Component \Messenger \Handler \MessageSubscriberInterface ;
12
10
use function count ;
18
16
final class MessageMapFactory
19
17
{
20
18
19
+ private const DEFAULT_HANDLER_METHOD = '__invoke ' ;
20
+
21
21
/** @var ReflectionProvider */
22
22
private $ reflectionProvider ;
23
23
@@ -53,19 +53,13 @@ public function create(): MessageMap
53
53
$ reflectionClass = $ this ->reflectionProvider ->getClass ($ serviceClass );
54
54
55
55
if (isset ($ tagAttributes ['handles ' ])) {
56
- $ handles = isset ($ tag ['method ' ]) ? [$ tag ['handles ' ] => $ tag ['method ' ]] : [$ tag ['handles ' ]];
56
+ // todo cover by test case
57
+ $ handles = [$ tagAttributes ['handles ' ] => ['method ' => $ tagAttributes ['method ' ] ?? self ::DEFAULT_HANDLER_METHOD ]];
57
58
} else {
58
59
$ handles = $ this ->guessHandledMessages ($ reflectionClass );
59
60
}
60
61
61
62
foreach ($ handles as $ messageClassName => $ options ) {
62
- if (is_int ($ messageClassName ) && is_string ($ options )) {
63
- $ messageClassName = $ options ;
64
- $ options = [];
65
- }
66
-
67
- $ options ['method ' ] = $ options ['method ' ] ?? '__invoke ' ;
68
-
69
63
$ methodReflection = $ reflectionClass ->getNativeMethod ($ options ['method ' ]);
70
64
$ variant = ParametersAcceptorSelector::selectSingle ($ methodReflection ->getVariants ());
71
65
@@ -82,15 +76,24 @@ public function create(): MessageMap
82
76
return new MessageMap ($ messages );
83
77
}
84
78
79
+ /** @return array<string, array<string, string>> */
85
80
private function guessHandledMessages (ClassReflection $ reflectionClass ): iterable
86
81
{
87
82
if ($ reflectionClass ->implementsInterface (MessageSubscriberInterface::class)) {
88
83
// todo handle different return formats
89
- return $ reflectionClass ->getName ()::getHandledMessages ();
84
+ foreach ($ reflectionClass ->getName ()::getHandledMessages () as $ index => $ value ) {
85
+ if (is_int ($ index ) && is_string ($ value )) {
86
+ yield $ value => ['method ' => self ::DEFAULT_HANDLER_METHOD ];
87
+ } else {
88
+ yield $ index => $ value ;
89
+ }
90
+ }
91
+
92
+ return ;
90
93
}
91
94
92
95
// todo handle if doesn't exists
93
- $ methodReflection = $ reflectionClass ->getNativeMethod (' __invoke ' );
96
+ $ methodReflection = $ reflectionClass ->getNativeMethod (self :: DEFAULT_HANDLER_METHOD );
94
97
95
98
$ variant = ParametersAcceptorSelector::selectSingle ($ methodReflection ->getVariants ());
96
99
$ parameters = $ variant ->getParameters ();
@@ -102,30 +105,10 @@ private function guessHandledMessages(ClassReflection $reflectionClass): iterabl
102
105
103
106
$ type = $ parameters [0 ]->getType ();
104
107
105
- if ($ type instanceof UnionType) {
106
- $ types = [];
107
- foreach ($ type ->getTypes () as $ type ) {
108
- if (!$ type instanceof ObjectType) {
109
- // todo handle error
110
- throw new RuntimeException ('invalid handler ' );
111
- }
112
-
113
- $ types [] = $ type ->getClassName ();
114
- }
115
-
116
- if ($ types ) {
117
- return $ types ;
118
- }
119
-
120
- // todo handle error
121
- throw new RuntimeException ('invalid handler ' );
108
+ // todo many class names?
109
+ foreach ($ type ->getObjectClassNames () as $ className ) {
110
+ yield $ className => ['method ' => self ::DEFAULT_HANDLER_METHOD ];
122
111
}
123
-
124
- if (!$ type instanceof ObjectType) {
125
- throw new RuntimeException ('invalid handler ' );
126
- }
127
-
128
- return [$ type ->getClassName ()];
129
112
}
130
113
131
114
}
0 commit comments