1515use ScaleUpStack \Metadata \FeatureAnalyzers \VirtualMethods ;
1616use ScaleUpStack \Metadata \Metadata \ClassMetadata ;
1717use ScaleUpStack \Metadata \Factory ;
18+ use ScaleUpStack \Metadata \Metadata \DataTypeMetadata ;
1819use ScaleUpStack \Metadata \Metadata \VirtualMethodMetadata ;
1920
2021final class Dispatcher
@@ -96,7 +97,12 @@ private function doInvocation(
9697 throw new \Error ("Calling a non-static method when not in object context. " );
9798 }
9899
99- $ this ->assertGivenParametersMatchMethodSignature ($ methodName , $ arguments , $ classMetadata );
100+ $ this ->assertGivenParametersMatchMethodSignature (
101+ $ objectOrClassName ,
102+ $ methodName ,
103+ $ arguments ,
104+ $ classMetadata
105+ );
100106
101107 $ return = $ callHandler ->execute ($ objectOrClassName , $ methodName , $ arguments , $ classMetadata );
102108
@@ -158,16 +164,22 @@ private function determineCallHandler(
158164 return null ;
159165 }
160166
167+ /**
168+ * @param object|string $objectContext
169+ */
161170 private function assertGivenParametersMatchMethodSignature (
171+ $ objectContext ,
162172 string $ methodName ,
163- array $ parameters ,
173+ array $ givenParameters ,
164174 ClassMetadata $ classMetadata
165175 )
166176 {
177+ /** @var VirtualMethodMetadata $methodMetadata */
167178 $ methodMetadata = $ classMetadata ->features [VirtualMethods::class][$ methodName ];
168- $ expectedParameterCount = count ($ methodMetadata ->parameters );
169179
170- $ givenParametersCount = count ($ parameters );
180+ // validate parameter count according to method signature
181+ $ expectedParameterCount = count ($ methodMetadata ->parameters );
182+ $ givenParametersCount = count ($ givenParameters );
171183
172184 if ($ expectedParameterCount !== $ givenParametersCount ) {
173185 throw new \ArgumentCountError (
@@ -176,11 +188,31 @@ private function assertGivenParametersMatchMethodSignature(
176188 $ expectedParameterCount > $ givenParametersCount ? 'few ' : 'many ' ,
177189 $ classMetadata ->name ,
178190 $ methodName ,
179- count ($ parameters ),
191+ count ($ givenParameters ),
180192 $ expectedParameterCount
181193 )
182194 );
183195 }
196+
197+ // validate parameters' data types according to method signature
198+ $ key = 0 ;
199+ /** @var DataTypeMetadata $signatureParameter */
200+ foreach ($ methodMetadata ->parameters as $ signatureParameterName => $ signatureParameter ) {
201+ $ parameterValue = $ givenParameters [$ key ];
202+ if (! $ signatureParameter ->validateVariable ($ parameterValue , $ objectContext )) {
203+ throw new \TypeError (
204+ sprintf (
205+ 'Argument %s (%s) passed to %s() must be of the type %s, %s given ' ,
206+ $ key + 1 ,
207+ $ signatureParameterName ,
208+ $ methodName ,
209+ $ signatureParameter ->declaration (),
210+ gettype ($ parameterValue )
211+ )
212+ );
213+ }
214+ $ key ++;
215+ }
184216 }
185217
186218 /**
0 commit comments