55use PHPStan \Reflection \ClassReflection ;
66use PHPStan \Reflection \ParametersAcceptorSelector ;
77use PHPStan \Reflection \ReflectionProvider ;
8- use PHPStan \Type \ObjectType ;
9- use PHPStan \Type \UnionType ;
108use RuntimeException ;
119use Symfony \Component \Messenger \Handler \MessageSubscriberInterface ;
1210use function count ;
1816final class MessageMapFactory
1917{
2018
19+ private const DEFAULT_HANDLER_METHOD = '__invoke ' ;
20+
2121 /** @var ReflectionProvider */
2222 private $ reflectionProvider ;
2323
@@ -53,19 +53,13 @@ public function create(): MessageMap
5353 $ reflectionClass = $ this ->reflectionProvider ->getClass ($ serviceClass );
5454
5555 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 ]];
5758 } else {
5859 $ handles = $ this ->guessHandledMessages ($ reflectionClass );
5960 }
6061
6162 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-
6963 $ methodReflection = $ reflectionClass ->getNativeMethod ($ options ['method ' ]);
7064 $ variant = ParametersAcceptorSelector::selectSingle ($ methodReflection ->getVariants ());
7165
@@ -82,15 +76,24 @@ public function create(): MessageMap
8276 return new MessageMap ($ messages );
8377 }
8478
79+ /** @return array<string, array<string, string>> */
8580 private function guessHandledMessages (ClassReflection $ reflectionClass ): iterable
8681 {
8782 if ($ reflectionClass ->implementsInterface (MessageSubscriberInterface::class)) {
8883 // 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 ;
9093 }
9194
9295 // todo handle if doesn't exists
93- $ methodReflection = $ reflectionClass ->getNativeMethod (' __invoke ' );
96+ $ methodReflection = $ reflectionClass ->getNativeMethod (self :: DEFAULT_HANDLER_METHOD );
9497
9598 $ variant = ParametersAcceptorSelector::selectSingle ($ methodReflection ->getVariants ());
9699 $ parameters = $ variant ->getParameters ();
@@ -102,30 +105,10 @@ private function guessHandledMessages(ClassReflection $reflectionClass): iterabl
102105
103106 $ type = $ parameters [0 ]->getType ();
104107
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 ];
122111 }
123-
124- if (!$ type instanceof ObjectType) {
125- throw new RuntimeException ('invalid handler ' );
126- }
127-
128- return [$ type ->getClassName ()];
129112 }
130113
131114}
0 commit comments