Beispiel #1
0
MaybeDataType TypeConstraint::underlyingDataTypeResolved() const {
  assert(!isSelf() && !isParent());
  if (!hasConstraint()) return folly::none;

  auto t = underlyingDataType();

  // If we aren't a class or type alias, nothing special to do.
  if (!isObjectOrTypeAlias()) return t;

  auto p = getTypeAliasOrClassWithAutoload(m_namedEntity, m_typeName);
  auto td = p.first;
  auto c = p.second;

  // See if this is a type alias.
  if (td) {
    if (td->kind != KindOfObject) {
      t = td->kind;
    } else {
      c = td->klass;
    }
  }

  // If the underlying type is a class, see if it is an enum and get that.
  if (c && isEnum(c)) {
    t = c->enumBaseTy();
  }

  return t;
}
Beispiel #2
0
  ExprPtr with(const Assign* v) const {
    // hack to assign [char] into <std.string>
    if (hasConstraint(this->constraint, v->type())) {
      if (*v->left()->type()->monoType() == *stdstrty && *v->right()->type()->monoType() == *chararrty) {
        static MonoTypePtr assignty = functy(list(stdstrty, chararrty), unitty);

        return fncall(var("stdstringAssign", assignty, v->left()->la()), list(switchOf(v->left(), *this), switchOf(v->right(), *this)), v->la());
      }
    }

    return wrapWithTy(v->type(), new Assign(switchOf(v->left(), *this), switchOf(v->right(), *this), v->la()));
  }
Beispiel #3
0
MaybeDataType TypeConstraint::underlyingDataTypeResolved() const {
  assert(!isSelf() && !isParent() && !isCallable());
  assert(IMPLIES(
    !hasConstraint() || isTypeVar() || isTypeConstant(),
    isMixed()));

  if (!isPrecise()) return folly::none;

  auto t = underlyingDataType();
  assert(t);

  // If we aren't a class or type alias, nothing special to do.
  if (!isObject()) return t;

  assert(t == KindOfObject);
  auto p = getTypeAliasOrClassWithAutoload(m_namedEntity, m_typeName);
  auto td = p.first;
  auto c = p.second;

  // See if this is a type alias.
  if (td) {
    if (td->type != Type::Object) {
      t = (getAnnotMetaType(td->type) != MetaType::Precise)
        ? folly::none : MaybeDataType(getAnnotDataType(td->type));
    } else {
      c = td->klass;
    }
  }

  // If the underlying type is a class, see if it is an enum and get that.
  if (c && isEnum(c)) {
    t = c->enumBaseTy();
  }

  return t;
}
bool ofxPhysics2d::has(ofxConstraint*c){
	return hasConstraint(c);	
}
Beispiel #5
0
bool
TypeConstraint::check(const TypedValue* tv, const Func* func) const {
  assert(hasConstraint());

  // This is part of the interpreter runtime; perf matters.
  if (tv->m_type == KindOfRef) {
    tv = tv->m_data.pref->tv();
  }
  if (nullable() && IS_NULL_TYPE(tv->m_type)) return true;

  if (tv->m_type == KindOfObject) {
    if (!isObjectOrTypedef()) return false;
    // Perfect match seems common enough to be worth skipping the hash
    // table lookup.
    if (m_typeName->isame(tv->m_data.pobj->getVMClass()->name())) {
      if (shouldProfile()) Class::profileInstanceOf(m_typeName);
      return true;
    }
    const Class *c = nullptr;
    const bool selfOrParentOrCallable = isSelf() || isParent() || isCallable();
    if (selfOrParentOrCallable) {
      if (isSelf()) {
        selfToClass(func, &c);
      } else if (isParent()) {
        parentToClass(func, &c);
      } else {
        assert(isCallable());
        return f_is_callable(tvAsCVarRef(tv));
      }
    } else {
      // We can't save the Class* since it moves around from request
      // to request.
      assert(m_namedEntity);
      c = Unit::lookupClass(m_namedEntity);
    }
    if (shouldProfile() && c) {
      Class::profileInstanceOf(c->preClass()->name());
    }
    if (c && tv->m_data.pobj->instanceof(c)) {
      return true;
    }
    return !selfOrParentOrCallable && checkTypedefObj(tv);
  }

  if (isObjectOrTypedef()) {
    switch (tv->m_type) {
      case KindOfArray:
        if (interface_supports_array(m_typeName)) {
          return true;
        }
        break;
      case KindOfString:
      case KindOfStaticString:
        if (interface_supports_string(m_typeName)) {
          return true;
        }
        break;
      case KindOfInt64:
        if (interface_supports_int(m_typeName)) {
          return true;
        }
        break;
      case KindOfDouble:
        if (interface_supports_double(m_typeName)) {
          return true;
        }
        break;
      default:
        break;
    }

    if (isCallable()) {
      return f_is_callable(tvAsCVarRef(tv));
    }
    return isPrecise() && checkTypedefNonObj(tv);
  }

  return equivDataTypes(m_type.m_dt, tv->m_type);
}
Beispiel #6
0
bool TypeConstraint::check(TypedValue* tv, const Func* func) const {
  assert(hasConstraint() && !isTypeVar() && !isMixed() && !isTypeConstant());

  // This is part of the interpreter runtime; perf matters.
  if (tv->m_type == KindOfRef) {
    tv = tv->m_data.pref->tv();
  }

  if (isNullable() && tv->m_type == KindOfNull) {
    return true;
  }

  if (tv->m_type == KindOfObject) {
    // Perfect match seems common enough to be worth skipping the hash
    // table lookup.
    const Class *c = nullptr;
    if (isObject()) {
      if (m_typeName->isame(tv->m_data.pobj->getVMClass()->name())) {
        if (isProfileRequest()) InstanceBits::profile(m_typeName);
        return true;
      }
      // We can't save the Class* since it moves around from request
      // to request.
      assert(m_namedEntity);
      c = Unit::lookupClass(m_namedEntity);
    } else {
      switch (metaType()) {
        case MetaType::Self:
          selfToClass(func, &c);
          break;
        case MetaType::Parent:
          parentToClass(func, &c);
          break;
        case MetaType::Callable:
          return is_callable(tvAsCVarRef(tv));
        case MetaType::Precise:
        case MetaType::Number:
        case MetaType::ArrayKey:
        case MetaType::Dict:
        case MetaType::Vec:
          return false;
        case MetaType::Mixed:
          // We assert'd at the top of this function that the
          // metatype cannot be Mixed
          not_reached();
      }
    }
    if (isProfileRequest() && c) {
      InstanceBits::profile(c->preClass()->name());
    }
    if (c && tv->m_data.pobj->instanceof(c)) {
      return true;
    }
    return isObject() && checkTypeAliasObj(tv->m_data.pobj->getVMClass());
  }

  auto const result = annotCompat(tv->m_type, m_type, m_typeName);
  switch (result) {
    case AnnotAction::Pass: return true;
    case AnnotAction::Fail: return false;
    case AnnotAction::CallableCheck:
      return is_callable(tvAsCVarRef(tv));
    case AnnotAction::DictCheck:
      return tv->m_data.parr->isDict();
    case AnnotAction::VecCheck:
      return tv->m_data.parr->isVecArray();
    case AnnotAction::ObjectCheck:
      assert(isObject());
      return checkTypeAliasNonObj(tv);
  }
  not_reached();
}
Beispiel #7
0
bool TypeConstraint::check(TypedValue* tv, const Func* func) const {
  assert(hasConstraint());

  // This is part of the interpreter runtime; perf matters.
  if (tv->m_type == KindOfRef) {
    tv = tv->m_data.pref->tv();
  }
  if (isNullable() && tv->m_type == KindOfNull) return true;

  if (isNumber()) {
    return IS_INT_TYPE(tv->m_type) || IS_DOUBLE_TYPE(tv->m_type);
  }

  if (isArrayKey()) {
    return IS_INT_TYPE(tv->m_type) || IS_STRING_TYPE(tv->m_type);
  }

  if (tv->m_type == KindOfObject) {
    if (!isObjectOrTypeAlias()) return false;
    // Perfect match seems common enough to be worth skipping the hash
    // table lookup.
    if (m_typeName->isame(tv->m_data.pobj->getVMClass()->name())) {
      if (isProfileRequest()) InstanceBits::profile(m_typeName);
      return true;
    }
    const Class *c = nullptr;
    const bool selfOrParentOrCallable = isSelf() || isParent() || isCallable();
    if (selfOrParentOrCallable) {
      if (isSelf()) {
        selfToClass(func, &c);
      } else if (isParent()) {
        parentToClass(func, &c);
      } else {
        assert(isCallable());
        return HHVM_FN(is_callable)(tvAsCVarRef(tv));
      }
    } else {
      // We can't save the Class* since it moves around from request
      // to request.
      assert(m_namedEntity);
      c = Unit::lookupClass(m_namedEntity);
    }
    if (isProfileRequest() && c) {
      InstanceBits::profile(c->preClass()->name());
    }
    if (c && tv->m_data.pobj->instanceof(c)) {
      return true;
    }
    return !selfOrParentOrCallable && checkTypeAliasObj(tv);
  }

  if (isObjectOrTypeAlias()) {
    do {
      switch (tv->m_type) {
        case KindOfInt64:
          if (interface_supports_int(m_typeName)) {
            return true;
          }
          continue;

        case KindOfDouble:
          if (interface_supports_double(m_typeName)) {
            return true;
          }
          continue;

        case KindOfStaticString:
        case KindOfString:
          if (interface_supports_string(m_typeName)) {
            return true;
          }
          continue;

        case KindOfArray:
          if (interface_supports_array(m_typeName)) {
            return true;
          }
          continue;

        case KindOfUninit:
        case KindOfNull:
        case KindOfBoolean:
        case KindOfObject:
        case KindOfResource:
          continue;

        case KindOfRef:
        case KindOfClass:
          break;
      }
      not_reached();
    } while (0);

    if (isCallable()) {
      return HHVM_FN(is_callable)(tvAsCVarRef(tv));
    }
    return isPrecise() && checkTypeAliasNonObj(tv);
  }

  return m_type.dt && equivDataTypes(*m_type.dt, tv->m_type);
}
Beispiel #8
0
bool hasConstraint(const ConstraintPtr& c, const QualTypePtr& qt) {
  return hasConstraint(c, qt->constraints());
}