Phan\Analysis\ArgumentType::analyzeParameterList PHP Метод

analyzeParameterList() приватный статический Метод

См. также: Phan\Deprecated\Pass2::arglist_type_check Formerly `function arglist_type_check`
private static analyzeParameterList ( CodeBase $code_base, Phan\Language\Element\FunctionInterface $method, ast\Node $node, Context $context ) : null
$code_base Phan\CodeBase The global code base
$method Phan\Language\Element\FunctionInterface The method we're analyzing arguments for
$node ast\Node The node holding the method call we're looking at
$context Phan\Language\Context The context in which we see the call
Результат null
    private static function analyzeParameterList(CodeBase $code_base, FunctionInterface $method, Node $node, Context $context)
    {
        // There's nothing reasonable we can do here
        if ($method instanceof Method) {
            if ($method->getIsMagicCall() || $method->getIsMagicCallStatic()) {
                return;
            }
        }
        foreach ($node->children ?? [] as $i => $argument) {
            // Get the parameter associated with this argument
            $parameter = $method->getParameterForCaller($i);
            // This issue should be caught elsewhere
            if (!$parameter) {
                continue;
            }
            // If this is a pass-by-reference parameter, make sure
            // we're passing an allowable argument
            if ($parameter->isPassByReference()) {
                if (!$argument instanceof \ast\Node || $argument->kind != \ast\AST_VAR && $argument->kind != \ast\AST_DIM && $argument->kind != \ast\AST_PROP && $argument->kind != \ast\AST_STATIC_PROP) {
                    Issue::maybeEmit($code_base, $context, Issue::TypeNonVarPassByRef, $node->lineno ?? 0, $i + 1, (string) $method->getFQSEN());
                } else {
                    $variable_name = (new ContextNode($code_base, $context, $argument))->getVariableName();
                    if (Type::isSelfTypeString($variable_name) && !$context->isInClassScope() && $argument->kind == \ast\AST_STATIC_PROP && $argument->kind == \ast\AST_PROP) {
                        Issue::maybeEmit($code_base, $context, Issue::ContextNotObject, $node->lineno ?? 0, "{$variable_name}");
                    }
                }
            }
            // Get the type of the argument. We'll check it against
            // the parameter in a moment
            $argument_type = UnionType::fromNode($context, $code_base, $argument);
            // Expand it to include all parent types up the chain
            $argument_type_expanded = $argument_type->asExpandedTypes($code_base);
            // Check the method to see if it has the correct
            // parameter types. If not, keep hunting through
            // alternates of the method until we find one that
            // takes the correct types
            $alternate_parameter = null;
            $alternate_found = false;
            foreach ($method->alternateGenerator($code_base) as $alternate_id => $alternate_method) {
                // Get the parameter associated with this argument
                $candidate_alternate_parameter = $alternate_method->getParameterForCaller($i);
                if (is_null($candidate_alternate_parameter)) {
                    continue;
                }
                $alternate_parameter = $candidate_alternate_parameter;
                // See if the argument can be cast to the
                // parameter
                if ($argument_type_expanded->canCastToUnionType($alternate_parameter->getUnionType())) {
                    $alternate_found = true;
                    break;
                }
            }
            if (!$alternate_found) {
                $parameter_name = $alternate_parameter ? $alternate_parameter->getName() : 'unknown';
                $parameter_type = $alternate_parameter ? $alternate_parameter->getUnionType() : 'unknown';
                if (is_object($parameter_type) && $parameter_type->hasTemplateType()) {
                    // Don't worry about template types
                } elseif ($method->isInternal()) {
                    // If we are not in strict mode and we accept a string parameter
                    // and the argument we are passing has a __toString method then it is ok
                    if (!$context->getIsStrictTypes() && $parameter_type->hasType(StringType::instance())) {
                        try {
                            foreach ($argument_type_expanded->asClassList($code_base, $context) as $clazz) {
                                if ($clazz->hasMethodWithName($code_base, "__toString")) {
                                    return;
                                }
                            }
                        } catch (CodeBaseException $e) {
                            // Swallow "Cannot find class", go on to emit issue
                        }
                    }
                    Issue::maybeEmit($code_base, $context, Issue::TypeMismatchArgumentInternal, $node->lineno ?? 0, $i + 1, $parameter_name, $argument_type_expanded, (string) $method->getFQSEN(), (string) $parameter_type);
                } else {
                    Issue::maybeEmit($code_base, $context, Issue::TypeMismatchArgument, $node->lineno ?? 0, $i + 1, $parameter_name, $argument_type_expanded, (string) $method->getFQSEN(), (string) $parameter_type, $method->getFileRef()->getFile(), $method->getFileRef()->getLineNumberStart());
                }
            }
        }
    }