예제 #1
0
 /**
  * @param Node $node
  * A node of the type indicated by the method name that we'd
  * like to figure out the type that it produces.
  *
  * @return string
  * The class name represented by the given call
  */
 public function visitNew(Node $node) : string
 {
     // Things of the form `new $class_name();`
     if ($node->children['class']->kind == \ast\AST_VAR) {
         return '';
     }
     // Anonymous class
     // $v = new class { ... }
     if ($node->children['class']->kind == \ast\AST_CLASS && $node->children['class']->flags & \ast\flags\CLASS_ANONYMOUS) {
         return AST::unqualifiedNameForAnonymousClassNode($node->children['class'], $this->context);
     }
     // Things of the form `new $method->name()`
     if ($node->children['class']->kind !== \ast\AST_NAME) {
         return '';
     }
     $class_name = $node->children['class']->children['name'];
     if (!in_array($class_name, ['self', 'static', 'parent'])) {
         return (string) UnionTypeVisitor::unionTypeFromClassNode($this->code_base, $this->context, $node->children['class']);
     }
     if (!$this->context->isInClassScope()) {
         Log::err(Log::ESTATIC, "Cannot access {$class_name}:: when no class scope is active", $this->context->getFile(), $node->lineno);
         return '';
     }
     if ($class_name == 'static') {
         return (string) $this->context->getClassFQSEN();
     }
     if ($class_name == 'self') {
         if ($this->context->isGlobalScope()) {
             assert(false, "Unimplemented branch is required for {$this->context}");
         } else {
             return (string) $this->context->getClassFQSEN();
         }
     }
     if ($class_name == 'parent') {
         $clazz = $this->context->getClassInScope($this->code_base);
         if (!$clazz->hasParentClassFQSEN()) {
             return '';
         }
         return (string) $clazz->getParentClassFQSEN();
     }
     return '';
 }