Get ReflectionFunctionAbstract of a variable if it was callable.

@param mixed $callable A variable to be tested.

@return \ReflectionFunction|\ReflectionMethod|false
Reflection of a function if $callable is callable, false otherwise.
779374
public static function getReflectionCallable($callable)
    {
        if (is_callable($callable, true)) {
            try {
                if (is_object($callable)) {
                    return new ReflectionFunction($callable);
                }
                if (is_array($callable)) {
                    return new ReflectionMethod($callable[0], $callable[1]);
                }
                if (strpos($callable, '::') === false) {
                    return new ReflectionFunction($callable);
                }
                return new ReflectionMethod($callable);
            } catch (ReflectionException $exception) {
            }
        }
        return false;
    }
1123775
protected function parse($callable)
    {
        list($callable, $args) = $this->parseArgs($callable);

        if ($this->isClassMethod($callable)) {
            $callable = $this->parseClassMethod($callable);
        } elseif ($this->isMutatorMethod($callable)) {
            $callable = [$this, $callable];
        } elseif (!function_exists($callable)) {
            throw new InvalidCallableException("Function [{$callable}] not found.");
        }

        return [$callable, $args];
    }
339232
protected function getCallableName(\ReflectionFunctionAbstract $ref)
	{
		if($ref instanceof \ReflectionMethod)
		{
			return $ref->getDeclaringClass()->name . '->' . $ref->name . '()';
		}
		
		if($ref->isClosure())
		{
			return '*closure*';
		}
		
		return $ref->getName() . '()';
	}
180798
public function call(callable $callable, array $parameters = [])
	{
		if(is_array($callable))
		{
			$reflection = new ReflectionMethod($callable[0], $callable[1]);
		}
		else
		{
			$reflection = new ReflectionFunction($callable);
		}

		return $callable(...$this->resolveParameters($reflection->getParameters(), $parameters));
	}
808195
public function call($key, $callable)
    {
        if (!is_callable($callable)) {
            throw new \InvalidArgumentException('Not a valid callable.');
        }

        if ($this->exists($key)) {
            return $this->get($key);
        }

        $args = func_get_args();
        array_shift($args);
        array_shift($args);

        $value = call_user_func_array($callable, $args);

        $this->set($key, $value);

        return $value;
    }
773217
private static function getCallToolArgs($callable, $tool, $operation)
    {
        $className = get_parent_class($callable[0]);
        $methodRef = new \ReflectionMethod($className, $callable[1]);
        $annotations = ToolParser::getInstance()->getData()['class'][$className]['Methods'][$methodRef->name]['Args'] ?? [];
        $args = [];
        foreach($methodRef->getParameters() as $param)
        {
            $annotation = $annotations[$param->name] ?? null;
            if(null === $annotation)
            {
                $value = $param->isOptional() ? $param->getDefaultValue() : null;
            }
            else if(Args::exists($annotation->name))
            {
                $value = static::parseArgValue(Args::get($annotation->name), $annotation);
            }
            else if($annotation->required)
            {
                throw new \InvalidArgumentException(sprintf('tool %s/%s param %s is required', $tool, $operation, $annotation->name));
            }
            else
            {
                $value = $annotation->default;
            }
            $args[] = $value;
        }
        return $args;
    }
146740
public function resolveFunctionParameters($callable, $parameters, $labels = false)
    {
        // method reflection
        $reflectionFunction = new ReflectionFunction($callable);

        // resolved array of parameters
        return $this->resolveParameters($reflectionFunction->getParameters(), $parameters, $labels);
    }
316056
public static function share($callable)
    {
        if (!is_object($callable) || !method_exists($callable, '__invoke')) {
            throw new InvalidArgumentException('Callable is not a Closure or invokable object.');
        }
        
        return function ($c) use ($callable) {
            static $object;

            if (null === $object) {
                $object = $callable($c);
            }

            return $object;
        };
    }
979803
public function match($callable)
    {
        ob_start();
        $callable();

        $this->actual = ob_get_contents();
        ob_end_clean();

        return ($this->actual == $this->expected);
    }
522247
public function filter(callable $callable)
    {
        $result = [];

        foreach ($this->value as $key => $value) {
            if ($callable($value, $key, $this)) {
                $result[$key] = $value;
            }
        }

        return static::of($result);
    }
327191
public function share(Closure $callable) : Closure
    {
        return function () use ($callable) {
            static $object;
            $c = $this;

            if (is_null($object) && $callable instanceof Closure) {
                $object = $callable($c);
            }

            return $object;
        };
    }
489335
public function dynamic($callable)
    {
        return $this->attributes[$this->attribute] = new self::$classMap['dynamic']($this->attribute, $this->entity, $callable);
    }
1002371
protected static function getReflection($callable)
    {

        if (is_array($callable)) {
            return new ReflectionMethod($callable[0], $callable[1]);
        }

        if ($callable instanceof \Closure) {
            return new ReflectionFunction($callable);
        }

        if (is_object($callable)) {
            return new ReflectionMethod($callable, '__invoke');
        }

        // Should be a string until here
        if (strpos($callable, '::')) {
            list($class, $method) = explode('::', $callable);
            return new ReflectionMethod($class, $method);
        }

        return new ReflectionFunction($callable);
    }
243651
protected static function getArity(callable $f)
    {
        if (is_string($f) || $f instanceof \Closure) {
            $reflector = (new \ReflectionFunction($f));
        } else {
            $reflector = (new \ReflectionMethod($f[0], $f[1]));
        }

        // Count the number of arguments the function is asking for
        return $reflector->getNumberOfParameters();
    }
901453
protected function reflectCallable($callable)
	{
		if (is_string($callable) && strpos($callable, '::')) {
			$callable = explode('::', $callable, 2);
		}

		if (is_a($callable, 'Closure')) {
			$reflection = new \ReflectionFunction($callable);
		} else if (is_object($callable)) {
			$reflection = new \ReflectionMethod(get_class($callable), '__invoke');
		} else if (is_array($callable) && count($callable) == 2) {
			$reflection = new \ReflectionMethod((is_object($callable[0]) ? get_class($callable[0]) : $callable[0]), $callable[1]);
		} else if (is_string($callable) && function_exists($callable)) {
			$reflection = new \ReflectionFunction($callable);
		}

		return $reflection;
	}
200515
public function invoke($callable, $vars=[])
    {
        if ($callable instanceof \Closure) {
            $result=$this->invokeFunction($callable, $vars);
        } else {
            $result=$this->invokeMethod($callable, $vars);
        }
        return $result;
    }
969737
public function execute($callable, array $args = [], $context = null)
    {
        if ($callable instanceof \Closure) {
            $ref = new \ReflectionObject($callable);

            $args = $this->getMethodArgs($ref->getMethod('__invoke'), $args);
        } else {
            if (is_string($callable)) {
                $callable = explode('::', $callable);
            }

            list($object, $method) = $callable;

            $ref = new \ReflectionClass($object);

            $args = $this->getMethodArgs($ref->getMethod($method), $args);
        }

        $closure = function () use ($args, $callable) {
            switch (count($args)) {
                case 0:
                    return $callable();
                case 1:
                    return $callable($args[0]);
                case 2:
                    return $callable($args[0], $args[1]);
                case 3:
                    return $callable($args[0], $args[1], $args[2]);
                case 4:
                    return $callable($args[0], $args[1], $args[2], $args[3]);
                default:
                    return call_user_func_array($callable, $args);
            }
        };

        if ($context) {
            $closure = $closure->bindTo($context, $context);
        }

        return $closure();
    }