function spliceDynamicCalls()
{
    if (Config\getRedefinableInternals() === []) {
        return function () {
        };
    }
    return function (Source $s) {
        spliceDynamicCallsWithin($s, 0, count($s->tokens) - 1);
    };
}
Example #2
0
function getRedefinableCallables()
{
    return array_merge(getUserDefinedCallables(), Config\getRedefinableInternals());
}
Example #3
0
function connectDefaultInternals()
{
    if (Config\getRedefinableInternals() === []) {
        return;
    }
    foreach (Config\getDefaultRedefinableInternals() as $function) {
        $offsets = [];
        foreach ((new \ReflectionFunction($function))->getParameters() as $offset => $argument) {
            $name = $argument->getName();
            if (strpos($name, 'call') !== false || strpos($name, 'func') !== false) {
                $offsets[] = $offset;
            }
        }
        connect($function, function () use($offsets) {
            $args = Stack\top('args');
            foreach ($offsets as $offset) {
                if (!isset($args[$offset])) {
                    continue;
                }
                $callable = $args[$offset];
                $args[$offset] = function () use($callable) {
                    if ($callable instanceof \Closure) {
                        return call_user_func_array($callable, func_get_args());
                    }
                    list($class, $method, $instance) = Utils\interpretCallable($callable);
                    if ($class === 'self' || $class === 'static' || $class === 'parent') {
                        $origin = debug_backtrace()[$frame]['class'];
                        if ($class === 'parent') {
                            $origin = get_parent_class($origin);
                        }
                        $class = $origin;
                        $callable = [$class, $method];
                    }
                    if ($class !== null && !is_callable([$class, $method])) {
                        $reflection = new \ReflectionMethod($class, $method);
                        $reflection->setAccessible(true);
                        return $reflection->invokeArgs($instance, func_get_args());
                    }
                    return dispatchDynamic($callable, func_get_args());
                };
            }
            return relay($args);
        });
    }
}