@Override
 public ConcreteType getTypeWithProperty(String field, ConcreteType type) {
   if (type.isInstance()) {
     ConcreteInstanceType instanceType = (ConcreteInstanceType) type;
     return instanceType.getInstanceTypeWithProperty(field);
   } else if (type.isFunction()) {
     if ("prototype".equals(field) || codingConvention.isSuperClassReference(field)) {
       return type;
     }
   } else if (type.isNone()) {
     // If the receiver is none, then this code is never reached.  We will
     // return a new fake type to ensure that this access is renamed
     // differently from any other, so it can be easily removed.
     return new ConcreteUniqueType(++nextUniqueId);
   } else if (type.isUnion()) {
     // If only one has the property, return that.
     for (ConcreteType t : ((ConcreteUnionType) type).getAlternatives()) {
       ConcreteType ret = getTypeWithProperty(field, t);
       if (ret != null) {
         return ret;
       }
     }
   }
   return null;
 }
 @Override
 public boolean isTypeToSkip(ConcreteType type) {
   // Skip anonymous object literals and enum types.
   return type.isInstance()
       && !(type.toInstance().isFunctionPrototype()
           || type.toInstance().instanceType.isInstanceType());
 }
 @Override
 public boolean isInvalidatingType(ConcreteType type) {
   // We will disallow types on functions so that 'prototype' is not renamed.
   // TODO(user): Support properties on functions as well.
   return (type == null)
       || type.isAll()
       || type.isFunction()
       || (type.isInstance() && invalidatingTypes.contains(type.toInstance().instanceType));
 }
 @Override
 public Iterable<ConcreteType> getTypeAlternatives(ConcreteType type) {
   if (type.isUnion()) {
     return ((ConcreteUnionType) type).getAlternatives();
   } else {
     return null;
   }
 }
    private ConcreteType maybeAddAutoboxes(ConcreteType cType, JSType jsType, String prop) {
      jsType = jsType.restrictByNotNullOrUndefined();
      if (jsType instanceof UnionType) {
        for (JSType alt : ((UnionType) jsType).getAlternates()) {
          return maybeAddAutoboxes(cType, alt, prop);
        }
      }

      if (jsType.autoboxesTo() != null) {
        JSType autoboxed = jsType.autoboxesTo();
        return cType.unionWith(tt.getConcreteInstance((ObjectType) autoboxed));
      } else if (jsType.unboxesTo() != null) {
        return cType.unionWith(tt.getConcreteInstance((ObjectType) jsType));
      }

      return cType;
    }
    /**
     * Add concrete types for autoboxing types if necessary. The concrete type system does not track
     * native types, like string, so add them if they are present in the JSType for the node.
     */
    private ConcreteType maybeAddAutoboxes(ConcreteType cType, Node node, String prop) {
      JSType jsType = node.getJSType();
      if (jsType == null) {
        return cType;
      } else if (jsType.isUnknownType()) {
        for (JSTypeNative nativeType : nativeTypes) {
          ConcreteType concrete =
              tt.getConcreteInstance(tt.getTypeRegistry().getNativeObjectType(nativeType));
          if (concrete != null && !concrete.getPropertyType(prop).isNone()) {
            cType = cType.unionWith(concrete);
          }
        }
        return cType;
      }

      return maybeAddAutoboxes(cType, jsType, prop);
    }
 @Override
 public ConcreteType getInstanceFromPrototype(ConcreteType type) {
   if (type.isInstance()) {
     ConcreteInstanceType instanceType = (ConcreteInstanceType) type;
     if (instanceType.isFunctionPrototype()) {
       return instanceType.getConstructorType().getInstanceType();
     }
   }
   return null;
 }