static ObjectType meet(ObjectType obj1, ObjectType obj2) {
   Preconditions.checkState(areRelatedClasses(obj1.nominalType, obj2.nominalType));
   if (obj1 == TOP_OBJECT) {
     return obj2;
   } else if (obj2 == TOP_OBJECT) {
     return obj1;
   }
   NominalType resultNomType = NominalType.pickSubclass(obj1.nominalType, obj2.nominalType);
   FunctionType fn = FunctionType.meet(obj1.fn, obj2.fn);
   if (!FunctionType.isInhabitable(fn)) {
     return BOTTOM_OBJECT;
   }
   boolean isLoose = obj1.isLoose && obj2.isLoose || fn != null && fn.isLoose();
   if (resultNomType != null && resultNomType.isFunction() && fn == null) {
     fn = obj1.fn == null ? obj2.fn : obj1.fn;
     isLoose = fn.isLoose();
   }
   PersistentMap<String, Property> props;
   if (isLoose) {
     props = joinPropsLoosely(obj1.props, obj2.props);
   } else {
     props = meetPropsHelper(false, resultNomType, obj1.props, obj2.props);
   }
   if (props == BOTTOM_MAP) {
     return BOTTOM_OBJECT;
   }
   ObjectKind ok = ObjectKind.meet(obj1.objectKind, obj2.objectKind);
   return new ObjectType(resultNomType, props, fn, isLoose, ok);
 }
Пример #2
0
 public FunctionType getFunType() {
   if (objs == null) {
     return null;
   }
   if (objs.size() == 1) { // The common case is fast
     return Iterables.getOnlyElement(objs).getFunType();
   }
   FunctionType result = FunctionType.TOP_FUNCTION;
   for (ObjectType obj : objs) {
     result = FunctionType.meet(result, obj.getFunType());
   }
   return result;
 }