Phan\AST\UnionTypeVisitor::visitClassNode PHP Method

visitClassNode() private method

*
private visitClassNode ( ast\Node $node ) : UnionType
$node ast\Node A node holding a class
return Phan\Language\UnionType The set of types that are possibly produced by the given node
    private function visitClassNode(Node $node) : UnionType
    {
        // Things of the form `new $class_name();`
        if ($node->kind == \ast\AST_VAR) {
            return new UnionType();
        }
        // Anonymous class of form `new class { ... }`
        if ($node->kind == \ast\AST_CLASS && $node->flags & \ast\flags\CLASS_ANONYMOUS) {
            // Generate a stable name for the anonymous class
            $anonymous_class_name = (new ContextNode($this->code_base, $this->context, $node))->getUnqualifiedNameForAnonymousClass();
            // Turn that into a fully qualified name
            $fqsen = FullyQualifiedClassName::fromStringInContext($anonymous_class_name, $this->context);
            // Turn that into a union type
            return Type::fromFullyQualifiedString((string) $fqsen)->asUnionType();
        }
        // Things of the form `new $method->name()`
        if ($node->kind !== \ast\AST_NAME) {
            return new UnionType();
        }
        // Get the name of the class
        $class_name = $node->children['name'];
        // If this is a straight-forward class name, recurse into the
        // class node and get its type
        if (!Type::isSelfTypeString($class_name)) {
            // TODO: does anyone else call this method?
            return self::unionTypeFromClassNode($this->code_base, $this->context, $node);
        }
        // This is a self-referential node
        if (!$this->context->isInClassScope()) {
            $this->emitIssue(Issue::ContextNotObject, $node->lineno ?? 0, $class_name);
            return new UnionType();
        }
        // Reference to a parent class
        if ($class_name === 'parent') {
            $class = $this->context->getClassInScope($this->code_base);
            if (!$class->hasParentType()) {
                $this->emitIssue(Issue::ParentlessClass, $node->lineno ?? 0, (string) $class->getFQSEN());
                return new UnionType();
            }
            return Type::fromFullyQualifiedString((string) $class->getParentClassFQSEN())->asUnionType();
        }
        return Type::fromFullyQualifiedString((string) $this->context->getClassFQSEN())->asUnionType();
    }