private function restrictByNumericType(PhpType $type = null, $outcome)
 {
     if ($outcome) {
         return $this->typeRegistry->getNativeType('numeric');
     }
     if (null === $type) {
         return null;
     }
     // String is excluded here since not all strings are necessarily numeric.
     // So, even if the condition evaluates to false, we could technically
     // still have a string inside the if (just that it is not numeric).
     if ($type->isIntegerType() || $type->isDoubleType()) {
         return $this->typeRegistry->getNativeType('none');
     }
     if ($type->isUnionType()) {
         // Again, we do not restrict by string as explained above.
         return $type->getRestrictedUnion($this->typeRegistry->createUnionType(array('integer', 'double')));
     }
     if ($type->isAllType()) {
         return $this->typeRegistry->createUnionType(array('object', 'string', 'null', 'array', 'boolean'));
     }
     return $type;
 }
示例#2
0
 /**
  * Emulates a loose comparison between two types, and returns the result.
  *
  * The result can be true, false, or unknown:
  *
  *     - true: loose comparison of these types is always true
  *     - false: loose comparison of these types is always false
  *     - unknown: outcome depends on the actual values of these types
  *
  * @see http://php.net/manual/en/types.comparisons.php (table with loose comparison ==)
  *
  * @param PhpType $thisType
  * @param PhpType $thatType
  */
 public function testForEquality(PhpType $that)
 {
     if ($that->isAllType() || $that->isUnknownType() || $that->isNoResolvedType() || $this->isAllType() || $this->isUnknownType() || $this->isNoResolvedType()) {
         return TernaryValue::get('unknown');
     }
     if ($this->isNoType() || $that->isNoType()) {
         if ($this->isNoType() && $that->isNoType()) {
             return TernaryValue::get('true');
         }
         return TernaryValue::get('unknown');
     }
     $isThisNumeric = $this->isIntegerType() || $this->isDoubleType();
     $isThatNumeric = $that->isIntegerType() || $that->isDoubleType();
     if (($isThisNumeric || $this->isStringType()) && $that->isArrayType() || ($isThatNumeric || $that->isStringType()) && $this->isArrayType()) {
         return TernaryValue::get('false');
     }
     if ($this->isObjectType() ^ $that->isObjectType()) {
         return TernaryValue::get('false');
     }
     if ($that->isUnionType()) {
         return $that->testForEquality($this);
     }
     if ($this->isArrayType() && $that->isArrayType()) {
         // TODO: Maybe make this more sophisticated by looking at the key,
         //       and element types.
         return TernaryValue::get('unknown');
     }
     // If this is reached, then this base type does not have enough information to
     // make an informed decision, but the method should be overridden by a subtype
     // as this method eventually is never allowed to return null.
     return null;
 }