the middle of the idiots
This commit is contained in:
124
qwen/php/vendor/php-di/invoker/src/CallableResolver.php
vendored
Normal file
124
qwen/php/vendor/php-di/invoker/src/CallableResolver.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker;
|
||||
|
||||
use Closure;
|
||||
use Invoker\Exception\NotCallableException;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Resolves a callable from a container.
|
||||
*/
|
||||
class CallableResolver
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given callable into a real PHP callable.
|
||||
*
|
||||
* @param callable|string|array $callable
|
||||
* @return callable Real PHP callable.
|
||||
* @throws NotCallableException|ReflectionException
|
||||
*/
|
||||
public function resolve($callable): callable
|
||||
{
|
||||
if (is_string($callable) && strpos($callable, '::') !== false) {
|
||||
$callable = explode('::', $callable, 2);
|
||||
}
|
||||
|
||||
$callable = $this->resolveFromContainer($callable);
|
||||
|
||||
if (! is_callable($callable)) {
|
||||
throw NotCallableException::fromInvalidCallable($callable, true);
|
||||
}
|
||||
|
||||
return $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|string|array $callable
|
||||
* @return callable|mixed
|
||||
* @throws NotCallableException|ReflectionException
|
||||
*/
|
||||
private function resolveFromContainer($callable)
|
||||
{
|
||||
// Shortcut for a very common use case
|
||||
if ($callable instanceof Closure) {
|
||||
return $callable;
|
||||
}
|
||||
|
||||
// If it's already a callable there is nothing to do
|
||||
if (is_callable($callable)) {
|
||||
// TODO with PHP 8 that should not be necessary to check this anymore
|
||||
if (! $this->isStaticCallToNonStaticMethod($callable)) {
|
||||
return $callable;
|
||||
}
|
||||
}
|
||||
|
||||
// The callable is a container entry name
|
||||
if (is_string($callable)) {
|
||||
try {
|
||||
return $this->container->get($callable);
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
if ($this->container->has($callable)) {
|
||||
throw $e;
|
||||
}
|
||||
throw NotCallableException::fromInvalidCallable($callable, true);
|
||||
}
|
||||
}
|
||||
|
||||
// The callable is an array whose first item is a container entry name
|
||||
// e.g. ['some-container-entry', 'methodToCall']
|
||||
if (is_array($callable) && is_string($callable[0])) {
|
||||
try {
|
||||
// Replace the container entry name by the actual object
|
||||
$callable[0] = $this->container->get($callable[0]);
|
||||
return $callable;
|
||||
} catch (NotFoundExceptionInterface $e) {
|
||||
if ($this->container->has($callable[0])) {
|
||||
throw $e;
|
||||
}
|
||||
throw new NotCallableException(sprintf(
|
||||
'Cannot call %s() on %s because it is not a class nor a valid container entry',
|
||||
$callable[1],
|
||||
$callable[0]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Unrecognized stuff, we let it fail later
|
||||
return $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the callable represents a static call to a non-static method.
|
||||
*
|
||||
* @param mixed $callable
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function isStaticCallToNonStaticMethod($callable): bool
|
||||
{
|
||||
if (is_array($callable) && is_string($callable[0])) {
|
||||
[$class, $method] = $callable;
|
||||
|
||||
if (! method_exists($class, $method)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$reflection = new ReflectionMethod($class, $method);
|
||||
|
||||
return ! $reflection->isStatic();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
10
qwen/php/vendor/php-di/invoker/src/Exception/InvocationException.php
vendored
Normal file
10
qwen/php/vendor/php-di/invoker/src/Exception/InvocationException.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\Exception;
|
||||
|
||||
/**
|
||||
* Impossible to invoke the callable.
|
||||
*/
|
||||
class InvocationException extends \Exception
|
||||
{
|
||||
}
|
||||
33
qwen/php/vendor/php-di/invoker/src/Exception/NotCallableException.php
vendored
Normal file
33
qwen/php/vendor/php-di/invoker/src/Exception/NotCallableException.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\Exception;
|
||||
|
||||
/**
|
||||
* The given callable is not actually callable.
|
||||
*/
|
||||
class NotCallableException extends InvocationException
|
||||
{
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function fromInvalidCallable($value, bool $containerEntry = false): self
|
||||
{
|
||||
if (is_object($value)) {
|
||||
$message = sprintf('Instance of %s is not a callable', get_class($value));
|
||||
} elseif (is_array($value) && isset($value[0], $value[1])) {
|
||||
$class = is_object($value[0]) ? get_class($value[0]) : $value[0];
|
||||
|
||||
$extra = method_exists($class, '__call') || method_exists($class, '__callStatic')
|
||||
? ' A __call() or __callStatic() method exists but magic methods are not supported.'
|
||||
: '';
|
||||
|
||||
$message = sprintf('%s::%s() is not a callable.%s', $class, $value[1], $extra);
|
||||
} elseif ($containerEntry) {
|
||||
$message = var_export($value, true) . ' is neither a callable nor a valid container entry';
|
||||
} else {
|
||||
$message = var_export($value, true) . ' is not a callable';
|
||||
}
|
||||
|
||||
return new self($message);
|
||||
}
|
||||
}
|
||||
10
qwen/php/vendor/php-di/invoker/src/Exception/NotEnoughParametersException.php
vendored
Normal file
10
qwen/php/vendor/php-di/invoker/src/Exception/NotEnoughParametersException.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\Exception;
|
||||
|
||||
/**
|
||||
* Not enough parameters could be resolved to invoke the callable.
|
||||
*/
|
||||
class NotEnoughParametersException extends InvocationException
|
||||
{
|
||||
}
|
||||
109
qwen/php/vendor/php-di/invoker/src/Invoker.php
vendored
Normal file
109
qwen/php/vendor/php-di/invoker/src/Invoker.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker;
|
||||
|
||||
use Invoker\Exception\NotCallableException;
|
||||
use Invoker\Exception\NotEnoughParametersException;
|
||||
use Invoker\ParameterResolver\AssociativeArrayResolver;
|
||||
use Invoker\ParameterResolver\DefaultValueResolver;
|
||||
use Invoker\ParameterResolver\NumericArrayResolver;
|
||||
use Invoker\ParameterResolver\ParameterResolver;
|
||||
use Invoker\ParameterResolver\ResolverChain;
|
||||
use Invoker\Reflection\CallableReflection;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ReflectionParameter;
|
||||
|
||||
/**
|
||||
* Invoke a callable.
|
||||
*/
|
||||
class Invoker implements InvokerInterface
|
||||
{
|
||||
/** @var CallableResolver|null */
|
||||
private $callableResolver;
|
||||
|
||||
/** @var ParameterResolver */
|
||||
private $parameterResolver;
|
||||
|
||||
/** @var ContainerInterface|null */
|
||||
private $container;
|
||||
|
||||
public function __construct(?ParameterResolver $parameterResolver = null, ?ContainerInterface $container = null)
|
||||
{
|
||||
$this->parameterResolver = $parameterResolver ?: $this->createParameterResolver();
|
||||
$this->container = $container;
|
||||
|
||||
if ($container) {
|
||||
$this->callableResolver = new CallableResolver($container);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function call($callable, array $parameters = [])
|
||||
{
|
||||
if ($this->callableResolver) {
|
||||
$callable = $this->callableResolver->resolve($callable);
|
||||
}
|
||||
|
||||
if (! is_callable($callable)) {
|
||||
throw new NotCallableException(sprintf(
|
||||
'%s is not a callable',
|
||||
is_object($callable) ? 'Instance of ' . get_class($callable) : var_export($callable, true)
|
||||
));
|
||||
}
|
||||
|
||||
$callableReflection = CallableReflection::create($callable);
|
||||
|
||||
$args = $this->parameterResolver->getParameters($callableReflection, $parameters, []);
|
||||
|
||||
// Sort by array key because call_user_func_array ignores numeric keys
|
||||
ksort($args);
|
||||
|
||||
// Check all parameters are resolved
|
||||
$diff = array_diff_key($callableReflection->getParameters(), $args);
|
||||
$parameter = reset($diff);
|
||||
if ($parameter && \assert($parameter instanceof ReflectionParameter) && ! $parameter->isVariadic()) {
|
||||
throw new NotEnoughParametersException(sprintf(
|
||||
'Unable to invoke the callable because no value was given for parameter %d ($%s)',
|
||||
$parameter->getPosition() + 1,
|
||||
$parameter->name
|
||||
));
|
||||
}
|
||||
|
||||
return call_user_func_array($callable, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the default parameter resolver.
|
||||
*/
|
||||
private function createParameterResolver(): ParameterResolver
|
||||
{
|
||||
return new ResolverChain([
|
||||
new NumericArrayResolver,
|
||||
new AssociativeArrayResolver,
|
||||
new DefaultValueResolver,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParameterResolver By default it's a ResolverChain
|
||||
*/
|
||||
public function getParameterResolver(): ParameterResolver
|
||||
{
|
||||
return $this->parameterResolver;
|
||||
}
|
||||
|
||||
public function getContainer(): ?ContainerInterface
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CallableResolver|null Returns null if no container was given in the constructor.
|
||||
*/
|
||||
public function getCallableResolver(): ?CallableResolver
|
||||
{
|
||||
return $this->callableResolver;
|
||||
}
|
||||
}
|
||||
25
qwen/php/vendor/php-di/invoker/src/InvokerInterface.php
vendored
Normal file
25
qwen/php/vendor/php-di/invoker/src/InvokerInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker;
|
||||
|
||||
use Invoker\Exception\InvocationException;
|
||||
use Invoker\Exception\NotCallableException;
|
||||
use Invoker\Exception\NotEnoughParametersException;
|
||||
|
||||
/**
|
||||
* Invoke a callable.
|
||||
*/
|
||||
interface InvokerInterface
|
||||
{
|
||||
/**
|
||||
* Call the given function using the given parameters.
|
||||
*
|
||||
* @param callable|array|string $callable Function to call.
|
||||
* @param array $parameters Parameters to use.
|
||||
* @return mixed Result of the function.
|
||||
* @throws InvocationException Base exception class for all the sub-exceptions below.
|
||||
* @throws NotCallableException
|
||||
* @throws NotEnoughParametersException
|
||||
*/
|
||||
public function call($callable, array $parameters = []);
|
||||
}
|
||||
37
qwen/php/vendor/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php
vendored
Normal file
37
qwen/php/vendor/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Tries to map an associative array (string-indexed) to the parameter names.
|
||||
*
|
||||
* E.g. `->call($callable, ['foo' => 'bar'])` will inject the string `'bar'`
|
||||
* in the parameter named `$foo`.
|
||||
*
|
||||
* Parameters that are not indexed by a string are ignored.
|
||||
*/
|
||||
class AssociativeArrayResolver implements ParameterResolver
|
||||
{
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$parameters = $reflection->getParameters();
|
||||
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$parameters = array_diff_key($parameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
if (array_key_exists($parameter->name, $providedParameters)) {
|
||||
$resolvedParameters[$index] = $providedParameters[$parameter->name];
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver\Container;
|
||||
|
||||
use Invoker\ParameterResolver\ParameterResolver;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Inject entries from a DI container using the parameter names.
|
||||
*/
|
||||
class ParameterNameContainerResolver implements ParameterResolver
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container The container to get entries from.
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$parameters = $reflection->getParameters();
|
||||
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$parameters = array_diff_key($parameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
$name = $parameter->name;
|
||||
|
||||
if ($name && $this->container->has($name)) {
|
||||
$resolvedParameters[$index] = $this->container->get($name);
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
65
qwen/php/vendor/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php
vendored
Normal file
65
qwen/php/vendor/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver\Container;
|
||||
|
||||
use Invoker\ParameterResolver\ParameterResolver;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use ReflectionFunctionAbstract;
|
||||
use ReflectionNamedType;
|
||||
|
||||
/**
|
||||
* Inject entries from a DI container using the type-hints.
|
||||
*/
|
||||
class TypeHintContainerResolver implements ParameterResolver
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container The container to get entries from.
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$parameters = $reflection->getParameters();
|
||||
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$parameters = array_diff_key($parameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
$parameterType = $parameter->getType();
|
||||
if (! $parameterType) {
|
||||
// No type
|
||||
continue;
|
||||
}
|
||||
if (! $parameterType instanceof ReflectionNamedType) {
|
||||
// Union types are not supported
|
||||
continue;
|
||||
}
|
||||
if ($parameterType->isBuiltin()) {
|
||||
// Primitive types are not supported
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameterClass = $parameterType->getName();
|
||||
if ($parameterClass === 'self') {
|
||||
$parameterClass = $parameter->getDeclaringClass()->getName();
|
||||
}
|
||||
|
||||
if ($this->container->has($parameterClass)) {
|
||||
$resolvedParameters[$index] = $this->container->get($parameterClass);
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
43
qwen/php/vendor/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php
vendored
Normal file
43
qwen/php/vendor/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionException;
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Finds the default value for a parameter, *if it exists*.
|
||||
*/
|
||||
class DefaultValueResolver implements ParameterResolver
|
||||
{
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$parameters = $reflection->getParameters();
|
||||
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$parameters = array_diff_key($parameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
\assert($parameter instanceof \ReflectionParameter);
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
try {
|
||||
$resolvedParameters[$index] = $parameter->getDefaultValue();
|
||||
} catch (ReflectionException $e) {
|
||||
// Can't get default values from PHP internal classes and functions
|
||||
}
|
||||
} else {
|
||||
$parameterType = $parameter->getType();
|
||||
if ($parameterType && $parameterType->allowsNull()) {
|
||||
$resolvedParameters[$index] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
37
qwen/php/vendor/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php
vendored
Normal file
37
qwen/php/vendor/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Simply returns all the values of the $providedParameters array that are
|
||||
* indexed by the parameter position (i.e. a number).
|
||||
*
|
||||
* E.g. `->call($callable, ['foo', 'bar'])` will simply resolve the parameters
|
||||
* to `['foo', 'bar']`.
|
||||
*
|
||||
* Parameters that are not indexed by a number (i.e. parameter position)
|
||||
* will be ignored.
|
||||
*/
|
||||
class NumericArrayResolver implements ParameterResolver
|
||||
{
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$providedParameters = array_diff_key($providedParameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($providedParameters as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$resolvedParameters[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
30
qwen/php/vendor/php-di/invoker/src/ParameterResolver/ParameterResolver.php
vendored
Normal file
30
qwen/php/vendor/php-di/invoker/src/ParameterResolver/ParameterResolver.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Resolves the parameters to use to call the callable.
|
||||
*/
|
||||
interface ParameterResolver
|
||||
{
|
||||
/**
|
||||
* Resolves the parameters to use to call the callable.
|
||||
*
|
||||
* `$resolvedParameters` contains parameters that have already been resolved.
|
||||
*
|
||||
* Each ParameterResolver must resolve parameters that are not already
|
||||
* in `$resolvedParameters`. That allows to chain multiple ParameterResolver.
|
||||
*
|
||||
* @param ReflectionFunctionAbstract $reflection Reflection object for the callable.
|
||||
* @param array $providedParameters Parameters provided by the caller.
|
||||
* @param array $resolvedParameters Parameters resolved (indexed by parameter position).
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
);
|
||||
}
|
||||
61
qwen/php/vendor/php-di/invoker/src/ParameterResolver/ResolverChain.php
vendored
Normal file
61
qwen/php/vendor/php-di/invoker/src/ParameterResolver/ResolverChain.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
/**
|
||||
* Dispatches the call to other resolvers until all parameters are resolved.
|
||||
*
|
||||
* Chain of responsibility pattern.
|
||||
*/
|
||||
class ResolverChain implements ParameterResolver
|
||||
{
|
||||
/** @var ParameterResolver[] */
|
||||
private $resolvers;
|
||||
|
||||
public function __construct(array $resolvers = [])
|
||||
{
|
||||
$this->resolvers = $resolvers;
|
||||
}
|
||||
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$reflectionParameters = $reflection->getParameters();
|
||||
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
$resolvedParameters = $resolver->getParameters(
|
||||
$reflection,
|
||||
$providedParameters,
|
||||
$resolvedParameters
|
||||
);
|
||||
|
||||
$diff = array_diff_key($reflectionParameters, $resolvedParameters);
|
||||
if (empty($diff)) {
|
||||
// Stop traversing: all parameters are resolved
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a parameter resolver after the ones already registered.
|
||||
*/
|
||||
public function appendResolver(ParameterResolver $resolver): void
|
||||
{
|
||||
$this->resolvers[] = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a parameter resolver before the ones already registered.
|
||||
*/
|
||||
public function prependResolver(ParameterResolver $resolver): void
|
||||
{
|
||||
array_unshift($this->resolvers, $resolver);
|
||||
}
|
||||
}
|
||||
54
qwen/php/vendor/php-di/invoker/src/ParameterResolver/TypeHintResolver.php
vendored
Normal file
54
qwen/php/vendor/php-di/invoker/src/ParameterResolver/TypeHintResolver.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\ParameterResolver;
|
||||
|
||||
use ReflectionFunctionAbstract;
|
||||
use ReflectionNamedType;
|
||||
|
||||
/**
|
||||
* Inject entries using type-hints.
|
||||
*
|
||||
* Tries to match type-hints with the parameters provided.
|
||||
*/
|
||||
class TypeHintResolver implements ParameterResolver
|
||||
{
|
||||
public function getParameters(
|
||||
ReflectionFunctionAbstract $reflection,
|
||||
array $providedParameters,
|
||||
array $resolvedParameters
|
||||
): array {
|
||||
$parameters = $reflection->getParameters();
|
||||
|
||||
// Skip parameters already resolved
|
||||
if (! empty($resolvedParameters)) {
|
||||
$parameters = array_diff_key($parameters, $resolvedParameters);
|
||||
}
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
$parameterType = $parameter->getType();
|
||||
if (! $parameterType) {
|
||||
// No type
|
||||
continue;
|
||||
}
|
||||
if (! $parameterType instanceof ReflectionNamedType) {
|
||||
// Union types are not supported
|
||||
continue;
|
||||
}
|
||||
if ($parameterType->isBuiltin()) {
|
||||
// Primitive types are not supported
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameterClass = $parameterType->getName();
|
||||
if ($parameterClass === 'self') {
|
||||
$parameterClass = $parameter->getDeclaringClass()->getName();
|
||||
}
|
||||
|
||||
if (array_key_exists($parameterClass, $providedParameters)) {
|
||||
$resolvedParameters[$index] = $providedParameters[$parameterClass];
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedParameters;
|
||||
}
|
||||
}
|
||||
56
qwen/php/vendor/php-di/invoker/src/Reflection/CallableReflection.php
vendored
Normal file
56
qwen/php/vendor/php-di/invoker/src/Reflection/CallableReflection.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Invoker\Reflection;
|
||||
|
||||
use Closure;
|
||||
use Invoker\Exception\NotCallableException;
|
||||
use ReflectionException;
|
||||
use ReflectionFunction;
|
||||
use ReflectionFunctionAbstract;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Create a reflection object from a callable or a callable-like.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CallableReflection
|
||||
{
|
||||
/**
|
||||
* @param callable|array|string $callable Can be a callable or a callable-like.
|
||||
* @throws NotCallableException|ReflectionException
|
||||
*/
|
||||
public static function create($callable): ReflectionFunctionAbstract
|
||||
{
|
||||
// Closure
|
||||
if ($callable instanceof Closure) {
|
||||
return new ReflectionFunction($callable);
|
||||
}
|
||||
|
||||
// Array callable
|
||||
if (is_array($callable)) {
|
||||
[$class, $method] = $callable;
|
||||
|
||||
if (! method_exists($class, $method)) {
|
||||
throw NotCallableException::fromInvalidCallable($callable);
|
||||
}
|
||||
|
||||
return new ReflectionMethod($class, $method);
|
||||
}
|
||||
|
||||
// Callable object (i.e. implementing __invoke())
|
||||
if (is_object($callable) && method_exists($callable, '__invoke')) {
|
||||
return new ReflectionMethod($callable, '__invoke');
|
||||
}
|
||||
|
||||
// Standard function
|
||||
if (is_string($callable) && function_exists($callable)) {
|
||||
return new ReflectionFunction($callable);
|
||||
}
|
||||
|
||||
throw new NotCallableException(sprintf(
|
||||
'%s is not a callable',
|
||||
is_string($callable) ? $callable : 'Instance of ' . get_class($callable)
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user