code: 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;
      }
docs: 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.