public function getMethod($method_name, bool $is_static) : Method
{
if ($method_name instanceof Node) {
// The method_name turned out to be a variable.
// There isn't much we can do to figure out what
// it's referring to.
throw new NodeException($method_name, "Unexpected method node");
}
assert(is_string($method_name), "Method name must be a string. Found non-string in context.");
try {
$class_list = (new ContextNode($this->code_base, $this->context, $this->node->children['expr'] ?? $this->node->children['class']))->getClassList();
} catch (CodeBaseException $exception) {
throw new IssueException(Issue::fromType(Issue::UndeclaredClassMethod)($this->context->getFile(), $this->node->lineno ?? 0, [$method_name, (string) $exception->getFQSEN()]));
}
// If there were no classes on the left-type, figure
// out what we were trying to call the method on
// and send out an error.
if (empty($class_list)) {
$union_type = UnionTypeVisitor::unionTypeFromClassNode($this->code_base, $this->context, $this->node->children['expr'] ?? $this->node->children['class']);
if (!$union_type->isEmpty() && $union_type->isNativeType() && !$union_type->hasAnyType([MixedType::instance(), ObjectType::instance(), StringType::instance()]) && !(Config::get()->null_casts_as_any_type && $union_type->hasType(NullType::instance()))) {
throw new IssueException(Issue::fromType(Issue::NonClassMethodCall)($this->context->getFile(), $this->node->lineno ?? 0, [$method_name, (string) $union_type]));
}
throw new NodeException($this->node, "Can't figure out method call for {$method_name}");
}
// Hunt to see if any of them have the method we're
// looking for
foreach ($class_list as $i => $class) {
if ($class->hasMethodWithName($this->code_base, $method_name)) {
return $class->getMethodByNameInContext($this->code_base, $method_name, $this->context);
} else {
if (!$is_static && $class->hasCallMethod($this->code_base)) {
return $class->getCallMethod($this->code_base);
} else {
if ($is_static && $class->hasCallStaticMethod($this->code_base)) {
return $class->getCallStaticMethod($this->code_base);
}
}
}
}
// Figure out an FQSEN for the method we couldn't find
$method_fqsen = FullyQualifiedMethodName::make($class_list[0]->getFQSEN(), $method_name);
if ($is_static) {
throw new IssueException(Issue::fromType(Issue::UndeclaredStaticMethod)($this->context->getFile(), $this->node->lineno ?? 0, [(string) $method_fqsen]));
}
throw new IssueException(Issue::fromType(Issue::UndeclaredMethod)($this->context->getFile(), $this->node->lineno ?? 0, [(string) $method_fqsen]));
}