1212
1313namespace ScaleUpStack \EasyObject \Magic ;
1414
15+ use ScaleUpStack \EasyObject \FeatureAnalyzers \VirtualMethods ;
1516use ScaleUpStack \Metadata \Metadata \ClassMetadata ;
1617use ScaleUpStack \Metadata \Factory ;
18+ use ScaleUpStack \Metadata \Metadata \VirtualMethodMetadata ;
1719
1820final class Dispatcher
1921{
@@ -64,7 +66,10 @@ public static function invoke(
6466 $ callHandler = $ instance ->callHandlers [$ callHandlerClassName ];
6567
6668 if ($ callHandler ->canHandle ($ methodName , $ classMetadata , [])) {
67- return $ callHandler ->execute ($ object , $ methodName , $ arguments , $ classMetadata );
69+ $ return = $ callHandler ->execute ($ object , $ methodName , $ arguments , $ classMetadata );
70+
71+ $ instance ->assertReturnType ($ object , $ methodName , $ return , $ classMetadata );
72+ return $ return ;
6873 }
6974 }
7075
@@ -82,4 +87,34 @@ private function classMetadata(string $className) : ClassMetadata
8287 return Factory::getMetadataForClass ($ className )
8388 ->classMetadata [$ className ];
8489 }
90+
91+ private function assertReturnType (
92+ object $ object ,
93+ string $ methodName ,
94+ $ returnValue ,
95+ ClassMetadata $ classMetadata
96+ )
97+ {
98+ /** @var VirtualMethodMetadata $virtualMethodMetadata */
99+ $ virtualMethodMetadata = $ classMetadata ->features [VirtualMethods::FEATURES_KEY ][$ methodName ];
100+ $ returnType = $ virtualMethodMetadata ->returnType ;
101+
102+ if (! is_null ($ returnType ->declaration ())) {
103+ $ isTypeValid = $ returnType ->validateVariable ($ returnValue , $ object );
104+
105+ if (! $ isTypeValid ) {
106+ // TODO: Handle error on strict_types declaration of calling context (not file defining the class) :-/
107+
108+ throw new \TypeError (
109+ sprintf (
110+ 'Return value of %s::%s() must be of the type %s, %s returned ' ,
111+ $ classMetadata ->name ,
112+ $ methodName ,
113+ $ returnType ->declaration (),
114+ gettype ($ returnValue )
115+ )
116+ );
117+ }
118+ }
119+ }
85120}
0 commit comments