Ejemplo n.º 1
0
 /**
  * Perform an intersection operation between two Types.
  *
  * If the two types are the same, this will just return that type.
  * If the two types are not the same, this will return NULL.
  *
  * When performed on two UnionTypes, this operation will return another
  * Type or UnionType containing the types that were equal from a many-to-many
  * typeof() operation or NULL if there are no matches.
  *
  * UnionType->intersect(NormalType)
  * When performed on a UnionType and one normal Type, this operation
  * will return the normal type if the UnionType contains the Type, or
  * NULL otherwise.
  *
  * NormalType->intersect(UnionType)
  * When performed on a Type and one UnionType, this operation will
  * return the Type if the UnionType contains it. NULL otherwise.
  *
  * Strict operation.
  *
  * @param Type $a
  * @param Type $b
  *
  * @return Type|null
  */
 public static final function intersect(Type $a, Type $b)
 {
     // Intersecting between $a and $b
     $output = [];
     $a = $a->getTypes();
     $b = $b->getTypes();
     // Check all elements of $a
     foreach ($a as $x) {
         foreach ($b as $y) {
             if ($x->typeof($y)) {
                 $output[] = $x;
             }
         }
     }
     // Check all elements of $b
     foreach ($b as $x) {
         foreach ($a as $y) {
             if ($x->typeof($y)) {
                 $output[] = $x;
             }
         }
     }
     // Combine results
     return Type::unique(...$output) ?: null;
 }
Ejemplo n.º 2
0
 /**
  * Check if all types are the same, in which case just return that type.
  * Otherwise, create the UnionType and return.
  * Also automatically flatten all nested UnionTypes.
  *
  * @param Type $type Require at least one type
  * @param Type|Type[] ...$types
  *
  * @return UnionType|Type
  */
 public static function createIfNotDuplicate(Type $type, Type ...$types)
 {
     $types = array_merge([$type], $types);
     // Flatten nested UnionTypes
     $types = Type::flatten($types);
     if (array_any($types, function (Type $type, $key, array $collection) {
         return $type instanceof UnionType;
     })) {
         throw new \LogicException("UnionType::flatten() failed to flatten nested UnionTypes.");
     }
     $types = Type::unique($types);
     if (count($types) <= 1) {
         return first($types);
     }
     return new UnionType(array_shift($types), $types);
 }