Ejemplo n.º 1
0
 /**
  * Visit a node with kind `\ast\AST_METHOD_CALL`
  *
  * @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 UnionType
  * The set of types that are possibly produced by the
  * given node
  */
 public function visitMethodCall(Node $node) : UnionType
 {
     $class_name = AST::classNameFromNode($this->context, $this->code_base, $node);
     if (empty($class_name)) {
         return new UnionType();
     }
     $class_fqsen = FullyQualifiedClassName::fromstringInContext($class_name, $this->context);
     assert($this->code_base->hasClassWithFQSEN($class_fqsen), "Class {$class_fqsen} must exist");
     $clazz = $this->code_base->getClassByFQSEN($class_fqsen);
     $method_name = $node->children['method'];
     // Give up on any complicated nonsense where the
     // method name is a variable such as in
     // `$variable->$function_name()`.
     if ($method_name instanceof Node) {
         return new UnionType();
     }
     // Method names can some times turn up being
     // other method calls.
     assert(is_string($method_name), "Method name must be a string. Something else given.");
     if (!$clazz->hasMethodWithName($this->code_base, $method_name)) {
         Log::err(Log::EUNDEF, "call to undeclared method {$class_fqsen}->{$method_name}()", $this->context->getFile(), $node->lineno);
         return new UnionType();
     }
     $method = $clazz->getMethodByNameInContext($this->code_base, $method_name, $this->context);
     return $method->getUnionType();
 }