@param  string                      $function_id
@param  array<PhpParser\Node\Arg>   $call_args

@return Type\Union
326758
public static function getReturnTypeFromCallMapWithArgs(
        StatementsAnalyzer $statements_analyzer,
        $function_id,
        array $call_args,
        Context $context
    ) {
        $call_map_key = strtolower($function_id);

        $call_map = CallMap::getCallMap();

        if (!isset($call_map[$call_map_key])) {
            throw new \InvalidArgumentException('Function ' . $function_id . ' was not found in callmap');
        }

        if (!$call_args) {
            switch ($call_map_key) {
                case 'getenv':
                    return new Type\Union([new Type\Atomic\TArray([Type::getArrayKey(), Type::getString()])]);

                case 'gettimeofday':
                    return new Type\Union([
                        new Type\Atomic\TArray([
                            Type::getString(),
                            Type::getInt()
                        ])
                    ]);

                case 'microtime':
                    return Type::getString();

                case 'hrtime':
                    return new Type\Union([
                        new Type\Atomic\ObjectLike([
                            Type::getInt(),
                            Type::getInt()
                        ])
                    ]);

                case 'get_called_class':
                    return new Type\Union([new Type\Atomic\TClassString($context->self ?: 'object')]);

                case 'get_parent_class':
                    $codebase = $statements_analyzer->getCodebase();

                    if ($context->self && $codebase->classExists($context->self)) {
                        $classlike_storage = $codebase->classlike_storage_provider->get($context->self);

                        if ($classlike_storage->parent_classes) {
                            return new Type\Union([
                                new Type\Atomic\TClassString(
                                    array_values($classlike_storage->parent_classes)[0]
                                )
                            ]);
                        }
                    }
            }
        } else {
            switch ($call_map_key) {
                case 'pathinfo':
                    if (isset($call_args[1])) {
                        return Type::getString();
                    }

                    return Type::getArray();

                case 'count':
                    if (isset($call_args[0]->value->inferredType)) {
                        $atomic_types = $call_args[0]->value->inferredType->getTypes();

                        if (count($atomic_types) === 1 && isset($atomic_types['array'])) {
                            if ($atomic_types['array'] instanceof Type\Atomic\TNonEmptyArray) {
                                return new Type\Union([
                                    $atomic_types['array']->count !== null
                                        ? new Type\Atomic\TLiteralInt($atomic_types['array']->count)
                                        : new Type\Atomic\TInt
                                ]);
                            } elseif ($atomic_types['array'] instanceof Type\Atomic\ObjectLike
                                && $atomic_types['array']->sealed
                            ) {
                                return new Type\Union([
                                    new Type\Atomic\TLiteralInt(count($atomic_types['array']->properties))
                                ]);
                            }
                        }
                    }

                    break;

                case 'var_export':
                case 'highlight_string':
                case 'highlight_file':
                    if (isset($call_args[1]->value->inferredType)) {
                        $subject_type = $call_args[1]->value->inferredType;

                        if ((string) $subject_type === 'true') {
                            return Type::getString();
                        }

                        return new Type\Union([
                            new Type\Atomic\TString,
                            $call_map_key === 'var_export' ? new Type\Atomic\TNull : new Type\Atomic\TBool
                        ]);
                    }

                    return $call_map_key === 'var_export' ? Type::getVoid() : Type::getBool();

                case 'print_r':
                    if (isset($call_args[1]->value->inferredType)) {
                        $subject_type = $call_args[1]->value->inferredType;

                        if ((string) $subject_type === 'true') {
                            return Type::getString();
                        }
                    }

                    return new Type\Union([
                        new Type\Atomic\TString,
                        new Type\Atomic\TTrue
                    ]);

                case 'microtime':
                    if (isset($call_args[0]->value->inferredType)) {
                        $subject_type = $call_args[0]->value->inferredType;

                        if ((string) $subject_type === 'true') {
                            return Type::getFloat();
                        }

                        if ((string) $subject_type === 'false') {
                            return Type::getString();
                        }
                    }

                    return new Type\Union([
                        new Type\Atomic\TFloat,
                        new Type\Atomic\TString
                    ]);

                case 'hrtime':
                    if (isset($call_args[0]->value->inferredType)) {
                        $subject_type = $call_args[0]->value->inferredType;

                        if ((string) $subject_type === 'true') {
                            $int = Type::getInt();
                            $int->from_calculation = true;
                            return $int;
                        }

                        if ((string) $subject_type === 'false') {
                            return new Type\Union([
                                new Type\Atomic\ObjectLike([
                                    Type::getInt(),
                                    Type::getInt()
                                ])
                            ]);
                        }

                        return new Type\Union([
                            new Type\Atomic\ObjectLike([
                                Type::getInt(),
                                Type::getInt()
                            ]),
                            new Type\Atomic\TInt()
                        ]);
                    }

                    $int = Type::getInt();
                    $int->from_calculation = true;
                    return $int;

                case 'getenv':
                    return new Type\Union([new Type\Atomic\TString, new Type\Atomic\TFalse]);

                case 'gettimeofday':
                    if (isset($call_args[0]->value->inferredType)) {
                        $subject_type = $call_args[0]->value->inferredType;

                        if ((string) $subject_type === 'true') {
                            return Type::getFloat();
                        }

                        if ((string) $subject_type === 'false') {
                            return new Type\Union([
                                new Type\Atomic\TArray([
                                    Type::getString(),
                                    Type::getInt()
                                ])
                            ]);
                        }
                    }

                    break;

                case 'explode':
                    if ($call_args[0]->value instanceof PhpParser\Node\Scalar\String_) {
                        if ($call_args[0]->value->value === '') {
                            return Type::getFalse();
                        }

                        return new Type\Union([
                            new Type\Atomic\TNonEmptyArray([
                                Type::getInt(),
                                Type::getString()
                            ])
                        ]);
                    } elseif (isset($call_args[0]->value->inferredType)
                        && $call_args[0]->value->inferredType->hasString()
                    ) {
                        $falsable_array = new Type\Union([
                            new Type\Atomic\TNonEmptyArray([
                                Type::getInt(),
                                Type::getString()
                            ]),
                            new Type\Atomic\TFalse
                        ]);

                        $codebase = $statements_analyzer->getCodebase();

                        if ($codebase->config->ignore_internal_falsable_issues) {
                            $falsable_array->ignore_falsable_issues = true;
                        }

                        return $falsable_array;
                    }

                    break;

                case 'abs':
                    if (isset($call_args[0]->value)) {
                        $first_arg = $call_args[0]->value;

                        if (isset($first_arg->inferredType)) {
                            $numeric_types = [];

                            foreach ($first_arg->inferredType->getTypes() as $inner_type) {
                                if ($inner_type->isNumericType()) {
                                    $numeric_types[] = $inner_type;
                                }
                            }

                            if ($numeric_types) {
                                return new Type\Union($numeric_types);
                            }
                        }
                    }

                    break;

                case 'min':
                case 'max':
                    if (isset($call_args[0])) {
                        $first_arg = $call_args[0]->value;

                        if (isset($first_arg->inferredType)) {
                            if ($first_arg->inferredType->hasArray()) {
                                $array_type = $first_arg->inferredType->getTypes()['array'];
                                if ($array_type instanceof Type\Atomic\ObjectLike) {
                                    return $array_type->getGenericValueType();
                                }

                                if ($array_type instanceof Type\Atomic\TArray) {
                                    return clone $array_type->type_params[1];
                                }
                            } elseif ($first_arg->inferredType->hasScalarType() &&
                                ($second_arg = $call_args[1]->value) &&
                                isset($second_arg->inferredType) &&
                                $second_arg->inferredType->hasScalarType()
                            ) {
                                return Type::combineUnionTypes($first_arg->inferredType, $second_arg->inferredType);
                            }
                        }
                    }

                    break;

                case 'round':
                    if (isset($call_args[1])) {
                        $second_arg = $call_args[1]->value;

                        if (isset($second_arg->inferredType)
                            && $second_arg->inferredType->isSingleIntLiteral()
                        ) {
                            switch ($second_arg->inferredType->getSingleIntLiteral()->value) {
                                case 0:
                                    return Type::getInt(true);
                                default:
                                    return Type::getFloat();
                            }
                        }

                        return new Type\Union([new Type\Atomic\TInt, new Type\Atomic\TFloat]);
                    }

                    return Type::getInt(true);

                case 'get_parent_class':
                    // this is unreliable, as it's hard to know exactly what's wanted - attempted this in
                    // https://github.com/vimeo/psalm/commit/355ed831e1c69c96bbf9bf2654ef64786cbe9fd7
                    // but caused problems where it didn’t know exactly what level of child we
                    // were receiving.
                    //
                    // Really this should only work on instances we've created with new Foo(),
                    // but that requires more work
                    break;
            }
        }

        if (!$call_map[$call_map_key][0]) {
            return Type::getMixed();
        }

        $call_map_return_type = Type::parseString($call_map[$call_map_key][0]);

        switch ($call_map_key) {
            case 'mb_strpos':
            case 'mb_strrpos':
            case 'mb_stripos':
            case 'mb_strripos':
            case 'strpos':
            case 'strrpos':
            case 'stripos':
            case 'strripos':
            case 'strstr':
            case 'stristr':
            case 'strrchr':
            case 'strpbrk':
            case 'array_search':
                break;

            default:
                $codebase = $statements_analyzer->getCodebase();

                if ($call_map_return_type->isFalsable()
                    && $codebase->config->ignore_internal_falsable_issues
                ) {
                    $call_map_return_type->ignore_falsable_issues = true;
                }
        }

        return $call_map_return_type;
    }
167423
public static <T> RelationalFunctionCall<T> relationalFunctionCall(Class<? extends T> type, String function, Object... args) {
        return new RelationalFunctionCall<T>(type, function, args);
    }
123113
public function add($fd, $flag, $func, $args = null)
    {
        $callback = function ($event, $socket) use ($fd, $func) {
            try {
                call_user_func($func, $fd);
            } catch (\Exception $e) {
                Worker::log($e);
                exit(250);
            } catch (\Error $e) {
                Worker::log($e);
                exit(250);
            }
        };
        switch ($flag) {
            case self::EV_SIGNAL:
                $event                   = new \EvSignal($fd, $callback);
                $this->_eventSignal[$fd] = $event;
                return true;
            case self::EV_TIMER:
            case self::EV_TIMER_ONCE:
                $repeat                             = $flag == self::EV_TIMER_ONCE ? 0 : $fd;
                $param                              = array($func, (array)$args, $flag, $fd, self::$_timerId);
                $event                              = new \EvTimer($fd, $repeat, array($this, 'timerCallback'), $param);
                $this->_eventTimer[self::$_timerId] = $event;
                return self::$_timerId++;
            default :
                $fd_key                           = (int)$fd;
                $real_flag                        = $flag === self::EV_READ ? \Ev::READ : \Ev::WRITE;
                $event                            = new \EvIo($fd, $real_flag, $callback);
                $this->_allEvents[$fd_key][$flag] = $event;
                return true;
        }

    }
289865
public function call_function() {
		$args = func_get_args();
		$name = array_shift( $args );

		return call_user_func_array( trim( $name ), $args );
	}
899748
public function getFunctionStorage($function_id)
    {
        if (isset(self::$builtin_functions[$function_id])) {
            return self::$builtin_functions[$function_id];
        }

        throw new \UnexpectedValueException('Expecting to have a function for ' . $function_id);
    }
805627
public function build(): CallFunctionOnRequest
	{
		$instance = new CallFunctionOnRequest();
		if ($this->functionDeclaration === null) {
			throw new BuilderException('Property [functionDeclaration] is required.');
		}
		$instance->functionDeclaration = $this->functionDeclaration;
		$instance->objectId = $this->objectId;
		$instance->arguments = $this->arguments;
		$instance->silent = $this->silent;
		$instance->returnByValue = $this->returnByValue;
		$instance->generatePreview = $this->generatePreview;
		$instance->userGesture = $this->userGesture;
		$instance->awaitPromise = $this->awaitPromise;
		$instance->executionContextId = $this->executionContextId;
		$instance->objectGroup = $this->objectGroup;
		return $instance;
	}
1269606
public static function getFunctionParamsFromCallMapById(Codebase $codebase, $method_id, array $args)
    {
        $function_param_options = CallMap::getParamsFromCallMap($method_id);

        if ($function_param_options === null) {
            throw new \UnexpectedValueException(
                'Not expecting $function_param_options to be null for ' . $method_id
            );
        }

        return self::getMatchingParamsFromCallMapOptions($codebase, $function_param_options, $args);
    }
527144
public static function call($handlers, $handler_id, $method, $arguments = array())
    {
        $callback = static::get($handlers, $handler_id, $method);
        return call_user_func_array($callback, $arguments);
    }
338530
public function fromCall(Call $call): CallVerifier
    {
        return new CallVerifier(
            $call,
            $this->matcherFactory,
            $this->matcherVerifier,
            $this->generatorVerifierFactory,
            $this->iterableVerifierFactory,
            $this->assertionRecorder,
            $this->assertionRenderer
        );
    }
996219
public function callback($function, $params = null)
    {
        $callback = new Callback($function, $params);
        $this->register($callback);

        return $callback;
    }
462611
def call(function, args, pseudo_type=None):
    ''''''

    if not isinstance(function, Node):
        function = local(function)
    return Node('call', function=function, args=args, pseudo_type=pseudo_type)
1045945
private static function checkArrayFunctionClosureType(
        StatementsAnalyzer $statements_analyzer,
        $method_id,
        Type\Atomic $closure_type,
        PhpParser\Node\Arg $closure_arg,
        $min_closure_param_count,
        $max_closure_param_count,
        array $array_arg_types,
        bool $check_functions
    ) {
        $codebase = $statements_analyzer->getCodebase();

        if (!$closure_type instanceof Type\Atomic\Fn) {
            if (!$closure_arg->value instanceof PhpParser\Node\Scalar\String_
                && !$closure_arg->value instanceof PhpParser\Node\Expr\Array_
                && !$closure_arg->value instanceof PhpParser\Node\Expr\BinaryOp\Concat
            ) {
                return;
            }

            $function_ids = self::getFunctionIdsFromCallableArg(
                $statements_analyzer,
                $closure_arg->value
            );

            $closure_types = [];

            foreach ($function_ids as $function_id) {
                $function_id = strtolower($function_id);

                if (strpos($function_id, '::') !== false) {
                    $function_id_parts = explode('&', $function_id);

                    foreach ($function_id_parts as $function_id_part) {
                        list($callable_fq_class_name, $method_name) = explode('::', $function_id_part);

                        switch ($callable_fq_class_name) {
                            case 'self':
                            case 'static':
                            case 'parent':
                                $container_class = $statements_analyzer->getFQCLN();

                                if ($callable_fq_class_name === 'parent') {
                                    $container_class = $statements_analyzer->getParentFQCLN();
                                }

                                if (!$container_class) {
                                    continue 2;
                                }

                                $callable_fq_class_name = $container_class;
                        }

                        if (!$codebase->classOrInterfaceExists($callable_fq_class_name)) {
                            return;
                        }

                        $function_id_part = $callable_fq_class_name . '::' . $method_name;

                        try {
                            $method_storage = $codebase->methods->getStorage($function_id_part);
                        } catch (\UnexpectedValueException $e) {
                            // the method may not exist, but we're suppressing that issue
                            continue;
                        }

                        $closure_types[] = new Type\Atomic\Fn(
                            'Closure',
                            $method_storage->params,
                            $method_storage->return_type ?: Type::getMixed()
                        );
                    }
                } else {
                    if (!$check_functions) {
                        continue;
                    }

                    if (!$codebase->functions->functionExists($statements_analyzer, $function_id)) {
                        continue;
                    }

                    $function_storage = $codebase->functions->getStorage(
                        $statements_analyzer,
                        $function_id
                    );

                    if (CallMap::inCallMap($function_id)) {
                        $callmap_params_options = CallMap::getParamsFromCallMap($function_id);

                        if ($callmap_params_options === null) {
                            throw new \UnexpectedValueException('This should not happen');
                        }

                        $passing_callmap_params_options = [];

                        foreach ($callmap_params_options as $callmap_params_option) {
                            $required_param_count = 0;

                            foreach ($callmap_params_option as $i => $param) {
                                if (!$param->is_optional && !$param->is_variadic) {
                                    $required_param_count = $i + 1;
                                }
                            }

                            if ($required_param_count <= $max_closure_param_count) {
                                $passing_callmap_params_options[] = $callmap_params_option;
                            }
                        }

                        if ($passing_callmap_params_options) {
                            foreach ($passing_callmap_params_options as $passing_callmap_params_option) {
                                $closure_types[] = new Type\Atomic\Fn(
                                    'Closure',
                                    $passing_callmap_params_option,
                                    $function_storage->return_type ?: Type::getMixed()
                                );
                            }
                        } else {
                            $closure_types[] = new Type\Atomic\Fn(
                                'Closure',
                                $callmap_params_options[0],
                                $function_storage->return_type ?: Type::getMixed()
                            );
                        }
                    } else {
                        $closure_types[] = new Type\Atomic\Fn(
                            'Closure',
                            $function_storage->params,
                            $function_storage->return_type ?: Type::getMixed()
                        );
                    }
                }
            }
        } else {
            $closure_types = [$closure_type];
        }

        foreach ($closure_types as $closure_type) {
            if ($closure_type->params === null) {
                continue;
            }

            if (self::checkArrayFunctionClosureTypeArgs(
                $statements_analyzer,
                $method_id,
                $closure_type,
                $closure_arg,
                $min_closure_param_count,
                $max_closure_param_count,
                $array_arg_types
            ) === false) {
                return false;
            }
        }
    }
440616
protected function callFunction(\Closure $function, $value, array $args = [])
    {
        if ($value instanceof Monadic && !$value instanceof Collection) {
            return $value->bind($function, $args);
        }

        $val = ($value instanceof \Closure ? $value() : $value);
        array_unshift($args, $val);

        return call_user_func_array($function, $args);
    }
386405
@Override
    public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
                             Scriptable thisObj, Object[] args)
    {
        if (!f.hasTag(getClassName())) {
            return super.execIdCall(f, cx, scope, thisObj, args);
        }
        int id = f.methodId();
        switch (id) {
        case Id_constructor:
            return js_constructor(args);
        case Id_getInt8:
            return realThis(thisObj, f).js_getInt(1, true, args);
        case Id_getUint8:
            return realThis(thisObj, f).js_getInt(1, false, args);
        case Id_getInt16:
            return realThis(thisObj, f).js_getInt(2, true, args);
        case Id_getUint16:
            return realThis(thisObj, f).js_getInt(2, false, args);
        case Id_getInt32:
            return realThis(thisObj, f).js_getInt(4, true, args);
        case Id_getUint32:
            return realThis(thisObj, f).js_getInt(4, false, args);
        case Id_getFloat32:
            return realThis(thisObj, f).js_getFloat(4, args);
        case Id_getFloat64:
            return realThis(thisObj, f).js_getFloat(8, args);
        case Id_setInt8:
            realThis(thisObj, f).js_setInt(1, true, args);
            return Undefined.instance;
        case Id_setUint8:
            realThis(thisObj, f).js_setInt(1, false, args);
            return Undefined.instance;
        case Id_setInt16:
            realThis(thisObj, f).js_setInt(2, true, args);
            return Undefined.instance;
        case Id_setUint16:
            realThis(thisObj, f).js_setInt(2, false, args);
            return Undefined.instance;
        case Id_setInt32:
            realThis(thisObj, f).js_setInt(4, true, args);
            return Undefined.instance;
        case Id_setUint32:
            realThis(thisObj, f).js_setInt(4, false, args);
            return Undefined.instance;
        case Id_setFloat32:
            realThis(thisObj, f).js_setFloat(4, args);
            return Undefined.instance;
        case Id_setFloat64:
            realThis(thisObj, f).js_setFloat(8, args);
            return Undefined.instance;
        }
        throw new IllegalArgumentException(String.valueOf(id));
    }
758357
private function _wrapArgs($caller_args, $num_args=null) {
    $num_args = (is_null($num_args)) ? count($caller_args) - 1 : $num_args;
    
    $filled_args = array();
    if(isset($this) && isset($this->_wrapped)) {
      $filled_args[] =& $this->_wrapped;
    }
    if(count($caller_args) > 0) {
      foreach($caller_args as $k=>$v) {
        $filled_args[] = $v;
      }
    }
    
    return array_pad($filled_args, $num_args, null);
  }
99976
protected static function checkArrayFunctionArgumentsMatch(
        StatementsAnalyzer $statements_analyzer,
        array $args,
        $method_id,
        bool $check_functions
    ) {
        $closure_index = $method_id === 'array_map' ? 0 : 1;

        $array_arg_types = [];

        foreach ($args as $i => $arg) {
            if ($i === 0 && $method_id === 'array_map') {
                continue;
            }

            if ($i === 1 && $method_id === 'array_filter') {
                break;
            }

            $array_arg = isset($arg->value) ? $arg->value : null;

            /** @var ObjectLike|TArray|null */
            $array_arg_type = $array_arg
                    && isset($array_arg->inferredType)
                    && isset($array_arg->inferredType->getTypes()['array'])
                ? $array_arg->inferredType->getTypes()['array']
                : null;

            if ($array_arg_type instanceof ObjectLike) {
                $array_arg_type = $array_arg_type->getGenericArrayType();
            }

            $array_arg_types[] = $array_arg_type;
        }

        /** @var null|PhpParser\Node\Arg */
        $closure_arg = isset($args[$closure_index]) ? $args[$closure_index] : null;

        /** @var Type\Union|null */
        $closure_arg_type = $closure_arg && isset($closure_arg->value->inferredType)
                ? $closure_arg->value->inferredType
                : null;

        if ($closure_arg && $closure_arg_type) {
            $min_closure_param_count = $max_closure_param_count = count($array_arg_types);

            if ($method_id === 'array_filter') {
                $max_closure_param_count = count($args) > 2 ? 2 : 1;
            }

            foreach ($closure_arg_type->getTypes() as $closure_type) {
                if (self::checkArrayFunctionClosureType(
                    $statements_analyzer,
                    $method_id,
                    $closure_type,
                    $closure_arg,
                    $min_closure_param_count,
                    $max_closure_param_count,
                    $array_arg_types,
                    $check_functions
                ) === false) {
                    return false;
                }
            }
        }
    }
662743
public static function call(callable $callable, $args=null)
    {

        if (!is_array($args)) {
            $args = $args === null ? [] : [$args];
        }

        return static::callFast($callable, static::evaluateArgs($args));

    }