/**
  * Compare the supplied types for equivalence.
  *
  * @param Type $left  The left-hand type.
  * @param Type $right The right-hand type.
  *
  * @return integer The comparison result.
  */
 public function compare(Type $left, Type $right)
 {
     return $right->accept(new TypeEquivalenceComparatorVisitor($this, $left));
 }
 /**
  * Render the supplied type.
  *
  * @api
  *
  * @param Type $type The type.
  *
  * @return string The rendered type.
  */
 public function render(Type $type)
 {
     return $type->accept($this);
 }
Exemple #3
0
 /**
  * @param RuntimeConfiguration $configuration
  * @param Type                 $documentedType
  * @param Type                 $nativeType
  * @param integer              $depth
  *
  * @return boolean
  */
 protected function typeIsCompatible(RuntimeConfiguration $configuration, Type $documentedType, Type $nativeType, $depth = 0)
 {
     $this->typeCheck->typeIsCompatible(func_get_args());
     // callable
     if ($this->useNativeCallable($configuration) && $documentedType instanceof CallableType) {
         return $nativeType instanceof CallableType;
     }
     // null
     if ($documentedType instanceof NullType) {
         if ($depth < 1) {
             return $nativeType instanceof MixedType;
         }
         return $nativeType instanceof NullType;
     }
     // traversable
     if ($documentedType instanceof TraversableType) {
         return !$documentedType->primaryType() instanceof ArrayType || $nativeType instanceof TraversableType;
     }
     // tuple
     if ($documentedType instanceof TupleType) {
         return $nativeType instanceof TraversableType;
     }
     // object of type
     if ($documentedType instanceof ObjectType && null !== $documentedType->ofType()) {
         if (!$nativeType instanceof ObjectType) {
             return false;
         }
         if ($nativeType->ofType()->isRuntimeEquivalentTo($documentedType->ofType())) {
             return true;
         }
         $documentedClassReflector = new ReflectionClass($documentedType->ofType()->string());
         return $documentedClassReflector->isSubclassOf($nativeType->ofType()->string());
     }
     // or type
     if ($documentedType instanceof OrType) {
         if ($nativeType instanceof OrType) {
             foreach ($documentedType->types() as $documentedSubType) {
                 $compatible = false;
                 foreach ($nativeType->types() as $nativeSubType) {
                     $compatible = $this->typeIsCompatible($configuration, $documentedSubType, $nativeSubType, $depth + 1);
                     if ($compatible) {
                         break;
                     }
                 }
                 if (!$compatible) {
                     return false;
                 }
             }
             return $compatible;
         }
         if (!$nativeType instanceof MixedType) {
             return false;
         }
         $hasArray = false;
         $hasCallable = false;
         $hasNull = false;
         $hasObjectOfType = false;
         $impossibleNatively = false;
         foreach ($documentedType->types() as $documentedSubType) {
             if ($documentedSubType instanceof TraversableType && $documentedSubType->primaryType() instanceof ArrayType) {
                 $hasArray = true;
             } elseif ($documentedSubType instanceof CallableType) {
                 $hasCallable = true;
             } elseif ($documentedSubType instanceof NullType) {
                 $hasNull = true;
             } elseif ($documentedSubType instanceof ObjectType && null !== $documentedSubType->ofType()) {
                 $hasObjectOfType = true;
             } else {
                 return true;
             }
         }
         return !$this->useNativeCallable($configuration) && $hasCallable || $hasArray && $hasCallable || $hasArray && $hasObjectOfType || $hasCallable && $hasObjectOfType;
     }
     // and type
     if ($documentedType instanceof AndType) {
         foreach ($documentedType->types() as $documentedSubType) {
             $compatible = $this->typeIsCompatible($configuration, $documentedSubType, $nativeType, $depth + 1);
             if ($compatible) {
                 return true;
             }
         }
         return false;
     }
     return $nativeType instanceof MixedType;
 }
 /**
  * @param Type $type
  *
  * @return string
  */
 protected function renderTypeName(Type $type)
 {
     $this->typeCheck->renderTypeName(func_get_args());
     if ($type instanceof NullifiedType) {
         return $type->originalType()->accept($this->typeRenderer());
     }
     return $type->accept($this->typeRenderer());
 }