1313use Closure ;
1414use ReflectionClass ;
1515use ReflectionException ;
16+ use ReflectionFunctionAbstract ;
1617use ReflectionMethod ;
1718use RuntimeException ;
1819use Traversable ;
3031use function property_exists ;
3132use function serialize ;
3233use function spl_object_hash ;
34+ use function sprintf ;
3335use function ucfirst ;
3436use function unserialize ;
3537
@@ -193,29 +195,29 @@ public static function hash($object, $unique = true): string
193195 * @from https://github.com/ventoviro/windwalker
194196 * Build an array of constructor parameters.
195197 *
196- * @param ReflectionMethod $method Method for which to build the argument array.
197- * @param array $extraArgs
198+ * @param ReflectionMethod $method Method for which to build the argument array.
199+ * @param array $provideArgs Manual provide params map.
198200 *
199201 * @return array
200202 * @throws RuntimeException
201203 * @throws ReflectionException
202204 */
203- public static function getMethodArgs (ReflectionMethod $ method , array $ extraArgs = []): array
205+ public static function getMethodArgs (ReflectionMethod $ method , array $ provideArgs = []): array
204206 {
205207 $ methodArgs = [];
206208
207209 foreach ($ method ->getParameters () as $ idx => $ param ) {
208210 // if user have been provide arg
209- if (isset ($ extraArgs [$ idx ])) {
210- $ methodArgs [] = $ extraArgs [$ idx ];
211+ if (isset ($ provideArgs [$ idx ])) {
212+ $ methodArgs [] = $ provideArgs [$ idx ];
211213 continue ;
212214 }
213215
214- $ dependencyClass = $ param ->getClass ();
216+ // $depRftClass = $param->getClass();
217+ $ depRftClass = $ param ->getType ();
215218
216219 // If we have a dependency, that means it has been type-hinted.
217- if ($ dependencyClass && ($ depClass = $ dependencyClass ->getName ()) !== Closure::class) {
218- $ depClass = $ dependencyClass ->getName ();
220+ if ($ depRftClass && ($ depClass = $ depRftClass ->getName ()) !== Closure::class) {
219221 $ depObject = self ::create ($ depClass );
220222
221223 if ($ depObject instanceof $ depClass ) {
@@ -242,6 +244,49 @@ public static function getMethodArgs(ReflectionMethod $method, array $extraArgs
242244 return $ methodArgs ;
243245 }
244246
247+ /**
248+ * @param ReflectionFunctionAbstract $rftFunc
249+ * @param array $provideArgs
250+ *
251+ * @psalm-param array<string, mixed> $provideArgs
252+ *
253+ * @return array
254+ * @throws ReflectionException
255+ */
256+ public static function buildReflectCallArgs (ReflectionFunctionAbstract $ rftFunc , array $ provideArgs = []): array
257+ {
258+ $ funcArgs = [];
259+ foreach ($ rftFunc ->getParameters () as $ param ) {
260+ // filling by param type. eg: an class name
261+ $ typeName = (string )$ param ->getType ();
262+ if ($ typeName !== Closure::class && isset ($ provideArgs [$ typeName ])) {
263+ $ funcArgs [] = $ provideArgs [$ typeName ];
264+ continue ;
265+ }
266+
267+ // filling by param name
268+ $ name = $ param ->getName ();
269+ if (isset ($ provideArgs [$ name ])) {
270+ $ funcArgs [] = $ provideArgs [$ name ];
271+ continue ;
272+ }
273+
274+ // Finally, if there is a default parameter, use it.
275+ if ($ param ->isOptional ()) {
276+ $ funcArgs [] = $ param ->getDefaultValue ();
277+ continue ;
278+ }
279+
280+ throw new RuntimeException (sprintf (
281+ 'Could not resolve dependency: %s for the %dth parameter ' ,
282+ $ param ->getPosition (),
283+ $ name
284+ ));
285+ }
286+
287+ return $ funcArgs ;
288+ }
289+
245290 /**
246291 * 从类名创建服务实例对象,会尽可能自动补完构造函数依赖
247292 *
0 commit comments