Match provided arguments with a method/function's reflection parameters

@param  \ReflectionParameter[] $reflectionParameters
@param  array $providedArguments
@return array the resolved arguments
@throws LogicException
@access protected
517680
protected function matchArguments(
        array $reflectionParameters,
        array $providedArguments
    )/*# : array */ {
        // result
        $resolvedArguments = [];
        foreach ($reflectionParameters as $i => $param) {
            $class = $param->getClass();

            if ($this->isTypeMatched($class, $providedArguments)) {
                $resolvedArguments[$i] = array_shift($providedArguments);
            } elseif ($this->isRequiredClass($param, $providedArguments)) {
                $resolvedArguments[$i] = $this->getObjectByClass($class->getName());
            }
        }
        return array_merge($resolvedArguments, $providedArguments);
    }
161083
private function extractArguments(): array
    {
        $parameters = [];

        //Use the Reflection API to create Parameter Value object
        foreach ($this->getReflectionInstance()->getParameters() as $param) {
            $name = $param->getName();
            $hasDefault = $param->isDefaultValueAvailable();

            //Default value. To null if the parameter has no default value
            $defaultValue = null;
            if (true === $hasDefault) {
                $defaultValue = $param->getDefaultValue();
            }
            $class = $param->getClass();

            $parameters[$name] = new Parameter($name, $hasDefault, $defaultValue, $class);
        }

        return $parameters;
    }
1280448
private function getArgumentByName(\ReflectionParameter $parameter, $parameters)
    {
        foreach ($parameters as $name => $item) {
            $paramName = $parameter->getName();
            if ($name === $paramName) {
                return $item;
            }
        }

        return null;
    }
225479
private function resolveMethodArguments(\ReflectionMethod $method, array $incomeArgs)
    {
        $orderedArguments = [];
        foreach ($method->getParameters() as $parameter) {
            if ($parameter->isOptional()) {
                $orderedArguments[$parameter->getPosition()] = $parameter->getDefaultValue();
            }
            foreach ($incomeArgs as $key => $value) {
                if ($parameter->getName() === $key) {
                    $orderedArguments[$parameter->getPosition()] = $value;
                    continue 2;
                }
            }

            //inject root common argument
            if ($this->root && !isset($incomeArgs['root']) && 'root' === $parameter->getName()) {
                $orderedArguments[$parameter->getPosition()] = $this->root;
            }

            //inject context common argument
            if ($this->context
                && 'context' === $parameter->getName()
                && $parameter->getClass()
                && is_a($parameter->getClass()->getName(), ResolverContext::class, true)
            ) {
                $orderedArguments[$parameter->getPosition()] = $this->context;
            }
        }

        // verify required arguments and types
        foreach ($method->getParameters() as $index => $parameter) {
            $givenValue = $orderedArguments[$index] ?? null;
            // does not allow null on required arguments
            if (null === $givenValue && !$parameter->allowsNull()) {
                throw new BadRequestError();
            }
        }

        return $orderedArguments;
    }
99609
private function getMethodArguments(\ReflectionMethod $method)
    {
        // ignore all query params
        $params = $this->paramReader->getParamsFromMethod($method);

        // check if a parameter is coming from the request body
        $ignoreParameters = [];
        if (class_exists(ParamConverter::class)) {
            $ignoreParameters = array_map(function ($annotation) {
                return
                    $annotation instanceof ParamConverter &&
                    'fos_rest.request_body' === $annotation->getConverter()
                        ? $annotation->getName() : null;
            }, $this->annotationReader->getMethodAnnotations($method));
        }

        // ignore several type hinted arguments
        $ignoreClasses = [
            Request::class,
            ParamFetcherInterface::class,
            ConstraintViolationListInterface::class,
            ParamConverter::class,
            MessageInterface::class,
        ];

        $arguments = [];
        foreach ($method->getParameters() as $argument) {
            if (isset($params[$argument->getName()])) {
                continue;
            }

            $argumentClass = $argument->getClass();
            if ($argumentClass) {
                $className = $argumentClass->getName();
                foreach ($ignoreClasses as $class) {
                    if ($className === $class || is_subclass_of($className, $class)) {
                        continue 2;
                    }
                }
            }

            if (in_array($argument->getName(), $ignoreParameters, true)) {
                continue;
            }

            $arguments[] = $argument;
        }

        return $arguments;
    }
1291403
private function makeParameters(array $parameters): array
    {
        return array_map(function (ReflectionParameter $parameter) {
            $class = $parameter->getClass();

            if ($class instanceof ReflectionClass) {
                return $this->make($class->getName());
            }

            if ($parameter->isDefaultValueAvailable()) {
                return $parameter->getDefaultValue();
            }

            return null;
        }, $parameters);
    }
945109
protected function resolveArgs($methodCallArgs) {
		if (! isset($methodCallArgs[1])) {
			if ($this->arguments === null) {
				return $this->normalizeArgs([]);
			}
			
			return $this->normalizeArgs($this->arguments);
		}
		
		if (isset($methodCallArgs[2])) {
			array_shift($methodCallArgs);
			return $this->normalizeArgs($methodCallArgs);
		}
		
		return $this->normalizeArgs($methodCallArgs[1]);
	}
177873
private function checkRequestConsistence(array $provided_parameters) {

        $signatures = $this->registered_method->getSignatures(false);

        $provided_parameters_count = count($provided_parameters);

        foreach ( $signatures as $num=>$signature ) {

            $requested_parameters_count = count($signature["PARAMETERS"]);

            if ( $provided_parameters_count != $requested_parameters_count ) {

                continue;

            }

            $index = 0;

            foreach ( $signature["PARAMETERS"] as $parameter => $type ) {

                if ( !Validator::validate($provided_parameters[$index], $type) ) continue 2;

                $index += 1;

            }

            return $num;

        }

        throw new RpcException("Invalid params", -32602);

    }
1175312
private function orderArguments(ReflectionMethod $method, array $args): array
    {
        $result = [];
        if (!$args) {
            return $result;
        }

        foreach ($method->getParameters() as $param) {
            if (array_key_exists($param->getName(), $args)) {
                $arg = $args[$param->getName()];

                // Fetch entity from DB
                if ($arg instanceof EntityID) {
                    $arg = $arg->getEntity();
                }

                $result[] = $arg;
            }
        }

        return $result;
    }
1093761
protected function getArguments(ReflectionMethod $method, RouteMatchInterface $routeMatch): array
    {
        $parameters = $routeMatch->getParameters();

        $arguments = [];
        foreach ($method->getParameters() as $parameter) {
            $name = $parameter->getName();

            if (array_key_exists($name, $parameters) === false) {
                if ($parameter->isDefaultValueAvailable() === true) {
                    $arguments[] = $parameter->getDefaultValue();
                } elseif ($parameter->allowsNull()) {
                    $arguments[] = null;
                } else {
                    throw new ParameterNotFound($name);
                }
            } else {
                $arguments[] = $parameters[$name];
            }
        }

        return $arguments;
    }
484732
private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments)
    {
        $class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId;
        $method = $reflectionMethod->name;
        $parameters = $reflectionMethod->getParameters();
        if (method_exists('ReflectionMethod', 'isVariadic') && $reflectionMethod->isVariadic()) {
            array_pop($parameters);
        }

        foreach ($parameters as $index => $parameter) {
            if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
                continue;
            }

            $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true);

            if (!$type) {
                if (isset($arguments[$index])) {
                    continue;
                }

                // no default value? Then fail
                if (!$parameter->isDefaultValueAvailable()) {
                    // For core classes, isDefaultValueAvailable() can
                    // be false when isOptional() returns true. If the
                    // argument *is* optional, allow it to be missing
                    if ($parameter->isOptional()) {
                        continue;
                    }
                    $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false);
                    $type = $type ? sprintf('is type-hinted "%s"', $type) : 'has no type-hint';

                    throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type));
                }

                // specifically pass the default value
                $arguments[$index] = $parameter->getDefaultValue();

                continue;
            }

            if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''), 'for '.sprintf('argument "$%s" of method "%s()"', $parameter->name, $class.'::'.$method))) {
                $failureMessage = $this->createTypeNotFoundMessage($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));

                if ($parameter->isDefaultValueAvailable()) {
                    $value = $parameter->getDefaultValue();
                } elseif (!$parameter->allowsNull()) {
                    throw new AutowiringFailedException($this->currentId, $failureMessage);
                }
                $this->container->log($this, $failureMessage);
            }

            $arguments[$index] = $value;
        }

        if ($parameters && !isset($arguments[++$index])) {
            while (0 <= --$index) {
                $parameter = $parameters[$index];
                if (!$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== $arguments[$index]) {
                    break;
                }
                unset($arguments[$index]);
            }
        }

        // it's possible index 1 was set, then index 0, then 2, etc
        // make sure that we re-order so they're injected as expected
        ksort($arguments);

        return $arguments;
    }
1370162
private function resolveConstructorArguments(array $args, \ReflectionClass $reflection): array
    {
        $params = [];
        foreach ($reflection->getConstructor()->getParameters() as $param) {
            $params[$param->getName()] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
        }
        return array_merge($params, array_intersect_key($args, $params));
    }
255428
private function getDependencyInjectionParameter(\ReflectionParameter $reflectionParameter, array &$arguments, array $argumentsClass)
    {
        // Parameter name in arguments list?
        if (array_key_exists($reflectionParameter->getName(), $arguments)) {
            $parameter = $arguments[$reflectionParameter->getName()];

            // Remove argument to do not use again
            unset($arguments[$reflectionParameter->getName()]);

            return $parameter;
        }

        // Parameter is class?
        if ($reflectionParameter->hasType() && !$reflectionParameter->getType()->isBuiltin()) {
            // Parameter type is in arguments class?
            if (array_key_exists($reflectionParameter->getType()->getName(), $argumentsClass)) {
                $argumentsFound = $argumentsClass[$reflectionParameter->getType()->getName()];

                // Argument is already available?
                if (($argumentFound = reset($argumentsFound)) !== false && isset($arguments[$argumentFound])) {
                    $parameter = $arguments[$argumentFound];

                    // Remove argument to do not use again
                    unset($arguments[$argumentFound]);

                    return $parameter;
                }
            }

            if (!is_null($this->getContainer())) {
                // Service exists with the same name and same type?
                if ($this->getContainer()->has($reflectionParameter->getName())
                    && is_a($service = $this->getContainer()->get($reflectionParameter->getName()), $reflectionParameter->getType()->getName())) {
                    return $service;
                }

                // Service exists with same class?
                if ($this->getContainer()->has($reflectionParameter->getType()->getName())
                    && is_a($service = $this->getContainer()->get($reflectionParameter->getType()->getName()), $reflectionParameter->getType()->getName())) {
                    return $service;
                }
            }
        }

        if ($reflectionParameter->isDefaultValueAvailable()) {
            try {
                return $reflectionParameter->getDefaultValue();
            } catch (\Exception $e) {
                throw new InstantiatorException(sprintf('Unable to get default value of parameter "%s"', $reflectionParameter->getName()));
            }
        } else {
            if ($reflectionParameter->allowsNull()) {
                return null;
            } else {
                throw new InstantiatorException(sprintf('Missing parameter "%s"', $reflectionParameter->getName()));
            }
        }
    }
912370
public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
    {
        foreach ($reflector->getParameters() as $key => $parameter) {
            $instance = $this->transformDependency($parameter, $parameters);

            if (!is_null($instance)) {
                $this->spliceIntoParameters($parameters, $key, $instance);
            }
        }

        return $parameters;
    }
345924
protected function abortIfRequiredArgumentsAreMissing($expectedArguments, $actualArguments)
    {
        $actualArgumentNames = array_keys($actualArguments);
        /** @var $expectedArgument ArgumentDefinition */
        foreach ($expectedArguments as $expectedArgument) {
            if ($expectedArgument->isRequired() && !in_array($expectedArgument->getName(), $actualArgumentNames)) {
                throw new Exception('Required argument "' . $expectedArgument->getName() . '" was not supplied.', 1237823699);
            }
        }
    }
92986
private static function guessArgs(\ReflectionMethod $method)
    {
        $arguments = [];
        foreach ($method->getParameters() as $index => $parameter) {
            if (!$parameter->hasType()) {
                throw new InvalidArgumentException(\sprintf('Argument n°%s "$%s" on method "%s" cannot be auto-guessed as there is not type hint.', $index + 1, $parameter->getName(), $method->getName()));
            }

            try {
                $gqlType = self::resolveGraphqlTypeFromReflectionType($parameter->getType(), self::$validInputTypes, $parameter->isDefaultValueAvailable());
            } catch (\Exception $e) {
                throw new InvalidArgumentException(\sprintf('Argument n°%s "$%s" on method "%s" cannot be auto-guessed : %s".', $index + 1, $parameter->getName(), $method->getName(), $e->getMessage()));
            }

            $argumentConfig = [];
            if ($parameter->isDefaultValueAvailable()) {
                $argumentConfig['defaultValue'] = $parameter->getDefaultValue();
            }

            $argumentConfig['type'] = $gqlType;

            $arguments[$parameter->getName()] = $argumentConfig;
        }

        return $arguments;
    }
800604
protected function prepareArguments($reflection_parameter, $arguments) {
		$array_type = $this->getArrayType($arguments);
		$prepared = array();

		if ($array_type == self::ARRAY_TYPE_LIST) {
			$prepared = $arguments;
		} elseif ($array_type == self::ARRAY_TYPE_DICT) {
			foreach ($reflection_parameter as $parameter) {
				$name = $parameter->getName();

				if (isset($arguments[$name])) {
					$value = $arguments[$name];
				} else if ($parameter->isDefaultValueAvailable()) {
					$value = $parameter->getDefaultValue();
				} else {
					throw new InvalidParameterException("Missing parameter '$name' on position {$parameter->getPosition()}");
				}

				$prepared[] = $value;
			}
		} else {
			throw new InvalidParameterException('Unable to handle mixed arrays');
		}

		return $prepared;
	}