src/Container.php
public function populateArguments(\ReflectionFunctionAbstract $ref, ?array $args = null, ?string $target = null): array
    {
        if ($args) {
            $params = \array_slice($ref->getParameters(), \count($args));
        } else {
            $params = $ref->getParameters();
            $args = [];
        }
        
        foreach ($params as $param) {
            try {
                $type = $param->getClass();
            } catch (\ReflectionException $e) {
                if ($param->isOptional()) {
                    $args[] = null;
                    
                    continue;
                }
                
                throw new \InvalidArgumentException(\sprintf('Type of argument "%s" not found: %s', $param->getName(), $param->getType()), 0, $e);
            }
            
            if ($type === null) {
                if ($param->isOptional()) {
                    $args[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
                    
                    continue;
                }
                
                throw new \InvalidArgumentException(\sprintf('Cannot populate required parameter "%s" without a type hint', $param->getName()));
            }
            
            switch ($type->getName()) {
                case Settings::class:
                    $args[] = $this->get(Settings::class, $param->isOptional(), $target);
                    break;
                case InjectionPoint::class:
                    if ($target === null) {
                        if (!$param->isOptional()) {
                            throw new \InvalidArgumentException(\sprintf('Unable to provide injection point without target'));
                        }
                        
                        $args[] = null;
                    } else {
                        $args[] = new InjectionPoint($target, $type->getName());
                    }
                    break;
                default:
                    $args[] = $this->shared[$type->getName()] ?? $this->get($type->getName(), $param->isOptional(), $target);
            }
        }
        
        return $args;
    }
public function populateArguments(\ReflectionFunctionAbstract $ref, ?array $args = null, ?string $target = null): array
    {
        if ($args) {
            $params = \array_slice($ref->getParameters(), \count($args));
        } else {
            $params = $ref->getParameters();
            $args = [];
        }
        
        foreach ($params as $param) {
            try {
                $type = $param->getClass();
            } catch (\ReflectionException $e) {
                if ($param->isOptional()) {
                    $args[] = null;
                    
                    continue;
                }
                
                throw new \InvalidArgumentException(\sprintf('Type of argument "%s" not found: %s', $param->getName(), $param->getType()), 0, $e);
            }
            
            if ($type === null) {
                if ($param->isOptional()) {
                    $args[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
                    
                    continue;
                }
                
                throw new \InvalidArgumentException(\sprintf('Cannot populate required parameter "%s" without a type hint', $param->getName()));
            }
            
            switch ($type->getName()) {
                case Settings::class:
                    $args[] = $this->get(Settings::class, $param->isOptional(), $target);
                    break;
                case InjectionPoint::class:
                    if ($target === null) {
                        if (!$param->isOptional()) {
                            throw new \InvalidArgumentException(\sprintf('Unable to provide injection point without target'));
                        }
                        
                        $args[] = null;
                    } else {
                        $args[] = new InjectionPoint($target, $type->getName());
                    }
                    break;
                default:
                    $args[] = $this->shared[$type->getName()] ?? $this->get($type->getName(), $param->isOptional(), $target);
            }
        }
        
        return $args;
    }
Create an array of arguments that can be passed to the given function / method.

@param \ReflectionFunctionAbstract $ref Target function / method.
@param array $args Arguments to be prepended to the generated args array.
@param string $target The name of the type that is the target of an injection.
@return array Prepared arguments.