@Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      return typeVariable.equals(((TypeVarBoundedType) o).typeVariable);
    }
Exemplo n.º 2
0
 /** Returns a new {@code TypeResolver} with {@code variable} mapping to {@code type}. */
 final TypeTable where(Map<? extends TypeVariable<?>, ? extends Type> mappings) {
   ImmutableMap.Builder<TypeVariable<?>, Type> builder = ImmutableMap.builder();
   builder.putAll(map);
   for (Map.Entry<? extends TypeVariable<?>, ? extends Type> mapping : mappings.entrySet()) {
     TypeVariable<?> variable = mapping.getKey();
     Type type = mapping.getValue();
     checkArgument(!variable.equals(type), "Type variable %s bound to itself", variable);
     builder.put(variable, type);
   }
   return new TypeTable(builder.build());
 }
Exemplo n.º 3
0
 private static boolean isAssignable(
     Type paramType, TypeVariable paramTypeVariable, Map paramMap) {
   if (paramType == null) return true;
   if (paramTypeVariable == null) return false;
   if (paramTypeVariable.equals(paramType)) return true;
   if ((paramType instanceof TypeVariable)) {
     Type[] arrayOfType = getImplicitBounds((TypeVariable) paramType);
     int i = arrayOfType.length;
     for (int j = 0; j < i; j++)
       if (isAssignable(arrayOfType[j], paramTypeVariable, paramMap)) return true;
   }
   if (((paramType instanceof Class))
       || ((paramType instanceof ParameterizedType))
       || ((paramType instanceof GenericArrayType))
       || ((paramType instanceof WildcardType))) return false;
   throw new IllegalStateException("found an unhandled type: " + paramType);
 }
Exemplo n.º 4
0
  /**
   * Checks if the subject type may be implicitly cast to the target type variable following the
   * Java generics rules.
   *
   * @param type the subject type to be assigned to the target type
   * @param toTypeVariable the target type variable
   * @return true if <code>type</code> is assignable to <code>toTypeVariable</code>.
   */
  private static boolean isAssignable(
      Type type, TypeVariable<?> toTypeVariable, Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
      return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
      return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
      return true;
    }

    if (type instanceof TypeVariable<?>) {
      // a type variable is assignable to another type variable, if
      // and only if the former is the latter, extends the latter, or
      // is otherwise a descendant of the latter.
      Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

      for (Type bound : bounds) {
        if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
          return true;
        }
      }
    }

    if (type instanceof Class<?>
        || type instanceof ParameterizedType
        || type instanceof GenericArrayType
        || type instanceof WildcardType) {
      return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
  }
Exemplo n.º 5
0
 private void map(final TypeVariable<?> var, final Type arg) {
   if (mappings.containsKey(var)) {
     // Mapping already established
     // This is possible when following both superClass -> enclosingClass
     // and enclosingclass -> superClass paths.
     // Since we follow the path of superclass first, enclosing second,
     // superclass mapping should take precedence.
     return;
   }
   // First, check whether var -> arg forms a cycle
   for (Type t = arg; t != null; t = mappings.get(t)) {
     if (var.equals(t)) {
       // cycle detected, remove the entire cycle from the mapping so that
       // each type variable resolves deterministically to itself.
       // Otherwise, a F -> T cycle will end up resolving both F and T
       // nondeterministically to either F or T.
       for (Type x = arg; x != null; x = mappings.remove(x)) {}
       return;
     }
   }
   mappings.put(var, arg);
 }