isEmpty() public method

public isEmpty ( ) : boolean
return boolean True if this Union has no types
Exemplo n.º 1
0
 public function __toString() : string
 {
     $string = '';
     if (!$this->type->isEmpty()) {
         $string .= "{$this->type} ";
     }
     $string .= $this->name;
     return $string;
 }
Exemplo n.º 2
0
 /**
  * Visit a node with kind `\ast\AST_DIM`
  *
  * @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 visitDim(Node $node) : UnionType
 {
     $union_type = self::unionTypeFromNode($this->code_base, $this->context, $node->children['expr']);
     if ($union_type->isEmpty()) {
         return $union_type;
     }
     // Figure out what the types of accessed array
     // elements would be
     $generic_types = $union_type->genericArrayElementTypes();
     // If we have generics, we're all set
     if (!$generic_types->isEmpty()) {
         return $generic_types;
     }
     // If the only type is null, we don't know what
     // accessed items will be
     if ($union_type->isType(NullType::instance())) {
         return new UnionType();
     }
     $element_types = new UnionType();
     // You can access string characters via array index,
     // so we'll add the string type to the result if we're
     // indexing something that could be a string
     if ($union_type->isType(StringType::instance()) || $union_type->canCastToUnionType(StringType::instance()->asUnionType())) {
         $element_types->addType(StringType::instance());
     }
     // array offsets work on strings, unfortunately
     // Double check that any classes in the type don't
     // have ArrayAccess
     $array_access_type = Type::fromNamespaceAndName('\\', 'ArrayAccess');
     // Hunt for any types that are viable class names and
     // see if they inherit from ArrayAccess
     foreach ($union_type->getTypeList() as $type) {
         if ($type->isNativeType()) {
             continue;
         }
         $class_fqsen = FullyQualifiedClassName::fromType($type);
         // If we can't find the class, the type probably
         // wasn't a class.
         if (!$this->code_base->hasClassWithFQSEN($class_fqsen)) {
             continue;
         }
         $class = $this->code_base->getClassByFQSEN($class_fqsen);
         // If the class has type ArrayAccess, it can be indexed
         // as if it were an array. That being said, we still don't
         // know the types of the elements, but at least we don't
         // error out.
         if ($class->getUnionType()->hasType($array_access_type)) {
             return $element_types;
         }
     }
     if ($element_types->isEmpty()) {
         Log::err(Log::ETYPE, "Suspicious array access to {$union_type}", $this->context->getFile(), $node->lineno);
     }
     return $element_types;
 }
Exemplo n.º 3
0
 /**
  * Visit a node with kind `\ast\AST_DIM`
  *
  * @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 visitDim(Node $node) : UnionType
 {
     $union_type = self::unionTypeFromNode($this->code_base, $this->context, $node->children['expr']);
     if ($union_type->isEmpty()) {
         return $union_type;
     }
     // Figure out what the types of accessed array
     // elements would be
     $generic_types = $union_type->genericArrayElementTypes();
     // If we have generics, we're all set
     if (!$generic_types->isEmpty()) {
         return $generic_types;
     }
     // If the only type is null, we don't know what
     // accessed items will be
     if ($union_type->isType(NullType::instance())) {
         return new UnionType();
     }
     $element_types = new UnionType();
     // You can access string characters via array index,
     // so we'll add the string type to the result if we're
     // indexing something that could be a string
     if ($union_type->isType(StringType::instance()) || $union_type->canCastToUnionType(StringType::instance()->asUnionType())) {
         $element_types->addType(StringType::instance());
     }
     // array offsets work on strings, unfortunately
     // Double check that any classes in the type don't
     // have ArrayAccess
     $array_access_type = Type::fromNamespaceAndName('\\', 'ArrayAccess');
     // Hunt for any types that are viable class names and
     // see if they inherit from ArrayAccess
     try {
         foreach ($union_type->asClassList($this->code_base) as $class) {
             if ($class->getUnionType()->hasType($array_access_type)) {
                 return $element_types;
             }
         }
     } catch (CodeBaseException $exception) {
         // Swallow it
     }
     if ($element_types->isEmpty()) {
         $this->emitIssue(Issue::TypeArraySuspicious, $node->lineno ?? 0, (string) $union_type);
     }
     return $element_types;
 }
Exemplo n.º 4
0
 /**
  * @param UnionType $target
  * A type to check to see if this can cast to it
  *
  * @return bool
  * True if this type is allowed to cast to the given type
  * i.e. int->float is allowed  while float->int is not.
  *
  * @see \Phan\Deprecated\Pass2::type_check
  * Formerly 'function type_check'
  */
 public function canCastToUnionType(UnionType $target) : bool
 {
     // Fast-track most common cases first
     // If either type is unknown, we can't call it
     // a success
     if ($this->isEmpty() || $target->isEmpty()) {
         return true;
     }
     // T === T
     if ($this->isEqualTo($target)) {
         return true;
     }
     if (Config::get()->null_casts_as_any_type) {
         // null <-> null
         if ($this->isType(NullType::instance()) || $target->isType(NullType::instance())) {
             return true;
         }
     }
     // mixed <-> mixed
     if ($target->hasType(MixedType::instance()) || $this->hasType(MixedType::instance())) {
         return true;
     }
     // int -> float
     if ($this->isType(IntType::instance()) && $target->isType(FloatType::instance())) {
         return true;
     }
     // Check conversion on the cross product of all
     // type combinations and see if any can cast to
     // any.
     foreach ($this->getTypeList() as $source_type) {
         if (empty($source_type)) {
             continue;
         }
         foreach ($target->getTypeList() as $target_type) {
             if (empty($target_type)) {
                 continue;
             }
             if ($source_type->canCastToType($target_type)) {
                 return true;
             }
         }
     }
     // Only if no source types can be cast to any target
     // types do we say that we cannot perform the cast
     return false;
 }
Exemplo n.º 5
0
 /**
  * @return bool
  * True if this doc block contains a (at)return
  * directive specifying a type.
  */
 public function hasReturnUnionType() : bool
 {
     return !empty($this->return_union_type) && !$this->return_union_type->isEmpty();
 }