示例#1
0
 static String toString(WildcardType wt) {
   final boolean isSuper = wt.getLowerBounds().length > 0;
   return String.format(
       "? %s %s",
       isSuper ? "super" : "extends",
       isSuper ? toString(wt.getLowerBounds()) : toString(wt.getLowerBounds()));
 }
 private String nameFor(WildcardType wild) {
   if ((wild.getLowerBounds().length != 0)) {
     return nameFor(wild.getLowerBounds()[0]);
   } else {
     return nameFor(wild.getUpperBounds()[0]);
   }
 }
示例#3
0
  /** Returns true if {@code a} and {@code b} are equal. */
  public static boolean equals(Type a, Type b) {
    if (a == b) {
      // also handles (a == null && b == null)
      return true;

    } else if (a instanceof Class) {
      // Class already specifies equals().
      return a.equals(b);

    } else if (a instanceof ParameterizedType) {
      if (!(b instanceof ParameterizedType)) {
        return false;
      }

      // TODO: save a .clone() call
      ParameterizedType pa = (ParameterizedType) a;
      ParameterizedType pb = (ParameterizedType) b;
      return equal(pa.getOwnerType(), pb.getOwnerType())
          && pa.getRawType().equals(pb.getRawType())
          && Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments());

    } else if (a instanceof GenericArrayType) {
      if (!(b instanceof GenericArrayType)) {
        return false;
      }

      GenericArrayType ga = (GenericArrayType) a;
      GenericArrayType gb = (GenericArrayType) b;
      return equals(ga.getGenericComponentType(), gb.getGenericComponentType());

    } else if (a instanceof WildcardType) {
      if (!(b instanceof WildcardType)) {
        return false;
      }

      WildcardType wa = (WildcardType) a;
      WildcardType wb = (WildcardType) b;
      return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds())
          && Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds());

    } else if (a instanceof TypeVariable) {
      if (!(b instanceof TypeVariable)) {
        return false;
      }
      TypeVariable<?> va = (TypeVariable<?>) a;
      TypeVariable<?> vb = (TypeVariable<?>) b;
      return va.getGenericDeclaration() == vb.getGenericDeclaration()
          && va.getName().equals(vb.getName());

    } else {
      // This isn't a type we support. Could be a generic array type,
      // wildcard type, etc.
      return false;
    }
  }
 private void visitType(java.lang.reflect.Type type, StringBuilder builder) {
   if (type instanceof Class) {
     Class<?> cl = (Class<?>) type;
     if (cl.isPrimitive()) {
       builder.append(Type.getType(cl).getDescriptor());
     } else {
       if (cl.isArray()) {
         builder.append(cl.getName().replace('.', '/'));
       } else {
         builder.append('L');
         builder.append(cl.getName().replace('.', '/'));
         builder.append(';');
       }
     }
   } else if (type instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type;
     visitNested(parameterizedType.getRawType(), builder);
     builder.append('<');
     for (java.lang.reflect.Type param : parameterizedType.getActualTypeArguments()) {
       visitType(param, builder);
     }
     builder.append(">;");
   } else if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     if (wildcardType.getUpperBounds().length == 1
         && wildcardType.getUpperBounds()[0].equals(Object.class)) {
       if (wildcardType.getLowerBounds().length == 0) {
         builder.append('*');
         return;
       }
     } else {
       for (java.lang.reflect.Type upperType : wildcardType.getUpperBounds()) {
         builder.append('+');
         visitType(upperType, builder);
       }
     }
     for (java.lang.reflect.Type lowerType : wildcardType.getLowerBounds()) {
       builder.append('-');
       visitType(lowerType, builder);
     }
   } else if (type instanceof TypeVariable) {
     TypeVariable<?> typeVar = (TypeVariable) type;
     builder.append('T');
     builder.append(typeVar.getName());
     builder.append(';');
   } else if (type instanceof GenericArrayType) {
     GenericArrayType arrayType = (GenericArrayType) type;
     builder.append('[');
     visitType(arrayType.getGenericComponentType(), builder);
   } else {
     throw new IllegalArgumentException(
         String.format("Cannot generate signature for %s.", type));
   }
 }
示例#5
0
  /**
   * Converts a Type into a jdiff compatible String. The returned types from this function should
   * match the same Strings that jdiff is providing to us.
   *
   * @param type the type to convert.
   * @return the jdiff formatted string.
   */
  private static String typeToString(Type type) {
    if (type instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) type;

      StringBuffer sb = new StringBuffer();
      sb.append(typeToString(pt.getRawType()));
      sb.append("<");

      int elementNum = 0;
      Type[] types = pt.getActualTypeArguments();
      for (Type t : types) {
        sb.append(typeToString(t));
        if (++elementNum < types.length) {
          sb.append(", ");
        }
      }

      sb.append(">");
      return sb.toString();
    } else if (type instanceof TypeVariable) {
      return ((TypeVariable<?>) type).getName();
    } else if (type instanceof Class) {
      return ((Class<?>) type).getCanonicalName();
    } else if (type instanceof GenericArrayType) {
      String typeName = typeToString(((GenericArrayType) type).getGenericComponentType());
      return typeName + "[]";
    } else if (type instanceof WildcardType) {
      WildcardType wt = (WildcardType) type;
      Type[] lowerBounds = wt.getLowerBounds();
      if (lowerBounds.length == 0) {
        String name = "? extends " + concatWildcardTypes(wt.getUpperBounds());

        // Special case for ?
        if (name.equals("? extends java.lang.Object")) {
          return "?";
        } else {
          return name;
        }
      } else {
        String name =
            concatWildcardTypes(wt.getUpperBounds())
                + " super "
                + concatWildcardTypes(wt.getLowerBounds());
        // Another special case for ?
        name = name.replace("java.lang.Object", "?");
        return name;
      }
    } else {
      throw new RuntimeException("Got an unknown java.lang.Type");
    }
  }
 @Override
 public boolean equals(Object obj) {
   if (!(obj instanceof WildcardType)) return false;
   WildcardType other = (WildcardType) obj;
   return Arrays.equals(lowerBounds, other.getLowerBounds())
       && Arrays.equals(upperBounds, other.getUpperBounds());
 }
示例#7
0
 @Nullable
 private static TypeWrapper wrap(Type type) {
   if (type == null) {
     return null;
   } else if (type instanceof Class) {
     return new ClassTypeWrapper((Class<?>) type);
   } else if (type instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type;
     return new ParameterizedTypeWrapper(
         toWrappers(parameterizedType.getActualTypeArguments()),
         (ClassTypeWrapper) wrap(parameterizedType.getRawType()),
         wrap(parameterizedType.getOwnerType()));
   } else if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     return new WildcardTypeWrapper(
         toWrappers(wildcardType.getUpperBounds()),
         toWrappers(wildcardType.getLowerBounds()),
         type.hashCode());
   } else if (type instanceof TypeVariable) {
     TypeVariable<?> typeVariable = (TypeVariable<?>) type;
     return new TypeVariableTypeWrapper(
         typeVariable.getName(), toWrappers(typeVariable.getBounds()), type.hashCode());
   } else if (type instanceof GenericArrayType) {
     GenericArrayType genericArrayType = (GenericArrayType) type;
     return new GenericArrayTypeWrapper(
         wrap(genericArrayType.getGenericComponentType()), type.hashCode());
   } else {
     throw new IllegalArgumentException("cannot wrap type of type " + type.getClass());
   }
 }
示例#8
0
文件: Lang.java 项目: flymichael/nutz
 /** 获取一个Type类型实际对应的Class */
 @SuppressWarnings("rawtypes")
 public static Class<?> getTypeClass(Type type) {
   Class<?> clazz = null;
   if (type instanceof Class<?>) {
     clazz = (Class<?>) type;
   } else if (type instanceof ParameterizedType) {
     ParameterizedType pt = (ParameterizedType) type;
     clazz = (Class<?>) pt.getRawType();
   } else if (type instanceof GenericArrayType) {
     GenericArrayType gat = (GenericArrayType) type;
     Class<?> typeClass = getTypeClass(gat.getGenericComponentType());
     return Array.newInstance(typeClass, 0).getClass();
   } else if (type instanceof TypeVariable) {
     TypeVariable tv = (TypeVariable) type;
     Type[] ts = tv.getBounds();
     if (ts != null && ts.length > 0) return getTypeClass(ts[0]);
   } else if (type instanceof WildcardType) {
     WildcardType wt = (WildcardType) type;
     Type[] t_low = wt.getLowerBounds(); // 取其下界
     if (t_low.length > 0) return getTypeClass(t_low[0]);
     Type[] t_up = wt.getUpperBounds(); // 没有下界?取其上界
     return getTypeClass(t_up[0]); // 最起码有Object作为上界
   }
   return clazz;
 }
 public boolean equals(Object o) {
   if (o instanceof WildcardType) {
     WildcardType wt = (WildcardType) o;
     return Arrays.equals(upperBounds, wt.getUpperBounds())
         && Arrays.equals(lowerBounds, wt.getLowerBounds());
   } else return false;
 }
示例#10
0
 public static Type[] getImplicitLowerBounds(WildcardType paramWildcardType) {
   Type[] arrayOfType = paramWildcardType.getLowerBounds();
   if (arrayOfType.length == 0) {
     arrayOfType = new Type[1];
     arrayOfType[0] = null;
   }
   return arrayOfType;
 }
示例#11
0
 public boolean equals(Object var1) {
   if (!(var1 instanceof WildcardType)) {
     return false;
   } else {
     WildcardType var2 = (WildcardType) var1;
     return this.lowerBounds.equals(Arrays.asList(var2.getLowerBounds()))
         && this.upperBounds.equals(Arrays.asList(var2.getUpperBounds()));
   }
 }
示例#12
0
 @Override
 public boolean equals(Object obj) {
   if (obj instanceof WildcardType) {
     WildcardType that = (WildcardType) obj;
     return lowerBounds.equals(Arrays.asList(that.getLowerBounds()))
         && upperBounds.equals(Arrays.asList(that.getUpperBounds()));
   }
   return false;
 }
示例#13
0
 public static boolean matches(Type type1, Type type2) {
   if (type1 instanceof Class<?>) {
     Class<?> clazz = (Class<?>) type1;
     if (matches(clazz, EMPTY_TYPES, type2)) {
       return true;
     }
   }
   if (type1 instanceof ParameterizedType) {
     ParameterizedType parameterizedType1 = (ParameterizedType) type1;
     if (parameterizedType1.getRawType() instanceof Class<?>) {
       if (matches(
           (Class<?>) parameterizedType1.getRawType(),
           parameterizedType1.getActualTypeArguments(),
           type2)) {
         return true;
       }
     }
   }
   if (type1 instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type1;
     if (isTypeBounded(type2, wildcardType.getLowerBounds(), wildcardType.getUpperBounds())) {
       return true;
     }
   }
   if (type2 instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type2;
     if (isTypeBounded(type1, wildcardType.getUpperBounds(), wildcardType.getLowerBounds())) {
       return true;
     }
   }
   if (type1 instanceof TypeVariable<?>) {
     TypeVariable<?> typeVariable = (TypeVariable<?>) type1;
     if (isTypeBounded(type2, EMPTY_TYPES, typeVariable.getBounds())) {
       return true;
     }
   }
   if (type2 instanceof TypeVariable<?>) {
     TypeVariable<?> typeVariable = (TypeVariable<?>) type2;
     if (isTypeBounded(type1, typeVariable.getBounds(), EMPTY_TYPES)) {
       return true;
     }
   }
   return false;
 }
示例#14
0
  /**
   * @param type - something like List&lt;? super T>, List<&lt;? extends T>, List&lt;? extends T &
   *     Comparable&lt? super T>>
   * @param containingType - the shallowest type in the hierarchy where type is defined.
   * @return the passed type if nothing to resolve or a copy of the type with the upper and lower
   *     bounds resolved.
   */
  private static WildcardType resolve(WildcardType type, Type containingType) {
    // Use a copy because we're going to modify them.
    final Type[] upper = type.getUpperBounds().clone();
    final Type[] lower = type.getLowerBounds().clone();

    boolean modified = resolve(upper, containingType);
    modified = modified || resolve(lower, containingType);

    return modified ? create(upper, lower) : type;
  }
  private static boolean isWildcardTypeAssignable(WildcardType supertype, Type type) {
    for (Type upperBound : supertype.getUpperBounds()) {
      if (!isAssignable(upperBound, type)) {
        return false;
      }
    }

    for (Type lowerBound : supertype.getLowerBounds()) {
      if (!isAssignable(type, lowerBound)) {
        return false;
      }
    }

    return true;
  }
示例#16
0
 /** Returns the array type of {@code componentType}. */
 static Type newArrayType(Type componentType) {
   if (componentType instanceof WildcardType) {
     WildcardType wildcard = (WildcardType) componentType;
     Type[] lowerBounds = wildcard.getLowerBounds();
     checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds.");
     if (lowerBounds.length == 1) {
       return supertypeOf(newArrayType(lowerBounds[0]));
     } else {
       Type[] upperBounds = wildcard.getUpperBounds();
       checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound.");
       return subtypeOf(newArrayType(upperBounds[0]));
     }
   }
   return JavaVersion.CURRENT.newArrayType(componentType);
 }
示例#17
0
 static Type newArrayType(Type var0) {
   if (var0 instanceof WildcardType) {
     WildcardType var1 = (WildcardType) var0;
     Type[] var2 = var1.getLowerBounds();
     Preconditions.checkArgument(
         var2.length <= 1, "Wildcard cannot have more than one lower bounds.");
     if (var2.length == 1) {
       return supertypeOf(newArrayType(var2[0]));
     } else {
       Type[] var3 = var1.getUpperBounds();
       Preconditions.checkArgument(var3.length == 1, "Wildcard should have only one upper bound.");
       return subtypeOf(newArrayType(var3[0]));
     }
   } else {
     return Types.JavaVersion.CURRENT.newArrayType(var0);
   }
 }
示例#18
0
 /**
  * Resolves all type variables in {@code type} and all downstream types and returns a
  * corresponding type with type variables resolved.
  */
 public Type resolveType(Type type) {
   checkNotNull(type);
   if (type instanceof TypeVariable) {
     return typeTable.resolve((TypeVariable<?>) type);
   } else if (type instanceof ParameterizedType) {
     return resolveParameterizedType((ParameterizedType) type);
   } else if (type instanceof GenericArrayType) {
     return resolveGenericArrayType((GenericArrayType) type);
   } else if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     return new Types.WildcardTypeImpl(
         resolveTypes(wildcardType.getLowerBounds()), resolveTypes(wildcardType.getUpperBounds()));
   } else {
     // if Class<?>, no resolution needed, we are done.
     return type;
   }
 }
示例#19
0
  /**
   * Returns raw class for given <code>type</code> when implementation class is known and it makes
   * difference.
   *
   * @see #resolveVariable(java.lang.reflect.TypeVariable, Class)
   */
  public static Class<?> getRawType(Type type, Class implClass) {
    if (type instanceof Class) {
      return (Class) type;
    }
    if (type instanceof ParameterizedType) {
      ParameterizedType pType = (ParameterizedType) type;
      return getRawType(pType.getRawType(), implClass);
    }
    if (type instanceof WildcardType) {
      WildcardType wType = (WildcardType) type;

      Type[] lowerTypes = wType.getLowerBounds();
      if (lowerTypes.length > 0) {
        return getRawType(lowerTypes[0], implClass);
      }

      Type[] upperTypes = wType.getUpperBounds();
      if (upperTypes.length != 0) {
        return getRawType(upperTypes[0], implClass);
      }

      return Object.class;
    }
    if (type instanceof GenericArrayType) {
      Type genericComponentType = ((GenericArrayType) type).getGenericComponentType();
      Class<?> rawType = getRawType(genericComponentType, implClass);
      // this is sort of stupid, but there seems no other way (consider don't creating new instances
      // each time)...
      return Array.newInstance(rawType, 0).getClass();
    }
    if (type instanceof TypeVariable) {
      TypeVariable<?> varType = (TypeVariable<?>) type;
      if (implClass != null) {
        Type resolvedType = resolveVariable(varType, implClass);
        if (resolvedType != null) {
          return getRawType(resolvedType, null);
        }
      }
      Type[] boundsTypes = varType.getBounds();
      if (boundsTypes.length == 0) {
        return Object.class;
      }
      return getRawType(boundsTypes[0], implClass);
    }
    return null;
  }
  /**
   * Creates {@link TypeInformation} for the given {@link Type}.
   *
   * @param fieldType the field type
   * @return the type information
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  protected TypeInformation<?> createInfo(Type fieldType) {

    if (fieldType.equals(this.type)) {
      return this;
    }

    if (fieldType instanceof Class) {
      return new ClassTypeInformation((Class<?>) fieldType);
    }

    Map<TypeVariable, Type> variableMap =
        GenericTypeResolver.getTypeVariableMap(resolveType(fieldType));

    if (fieldType instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) fieldType;
      return new ParameterizedTypeInformation(parameterizedType, this);
    }

    if (fieldType instanceof TypeVariable) {
      TypeVariable<?> variable = (TypeVariable<?>) fieldType;
      return new TypeVariableTypeInformation(variable, type, this, variableMap);
    }

    if (fieldType instanceof GenericArrayType) {
      return new GenericArrayTypeInformation((GenericArrayType) fieldType, this);
    }

    if (fieldType instanceof WildcardType) {

      WildcardType wildcardType = (WildcardType) fieldType;
      Type[] bounds = wildcardType.getLowerBounds();

      if (bounds.length > 0) {
        return createInfo(bounds[0]);
      }

      bounds = wildcardType.getUpperBounds();

      if (bounds.length > 0) {
        return createInfo(bounds[0]);
      }
    }

    throw new IllegalArgumentException();
  }
示例#21
0
  private ClassNode configureWildcardType(WildcardType wildcardType) {
    ClassNode base = ClassHelper.makeWithoutCaching("?");
    base.setRedirect(ClassHelper.OBJECT_TYPE);
    // TODO: more than one lower bound for wildcards?
    ClassNode[] lowers = configureTypes(wildcardType.getLowerBounds());
    ClassNode lower = null;
    // TODO: is it safe to remove this? What was the original intention?
    if (lower != null) lower = lowers[0];

    ClassNode[] upper = configureTypes(wildcardType.getUpperBounds());
    GenericsType t = new GenericsType(base, upper, lower);
    t.setWildcard(true);

    ClassNode ref = ClassHelper.makeWithoutCaching(Object.class, false);
    ref.setGenericsTypes(new GenericsType[] {t});

    return ref;
  }
示例#22
0
  public static Class<?> getActualType(Type genericType, final int pos) {

    if (genericType == null) return null;
    if (!ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
      if (genericType instanceof TypeVariable)
        genericType = getType(((TypeVariable<?>) genericType).getBounds(), pos);
      else if (genericType instanceof WildcardType) {
        final WildcardType wildcardType = (WildcardType) genericType;
        Type[] bounds = wildcardType.getLowerBounds();
        if (bounds.length == 0) bounds = wildcardType.getUpperBounds();
        genericType = getType(bounds, pos);
      }

      final Class<?> cls = (Class<?>) genericType;
      return cls.isArray() ? cls.getComponentType() : cls;
    }
    final ParameterizedType paramType = (ParameterizedType) genericType;
    final Type t = getType(paramType.getActualTypeArguments(), pos);
    return t instanceof Class ? (Class<?>) t : getActualType(t, pos);
  }
示例#23
0
  /**
   * Returns a type that is functionally equal but not necessarily equal according to {@link
   * Object#equals(Object) Object.equals()}. The returned type is {@link Serializable}.
   */
  public static Type canonicalize(Type type) {
    if (type instanceof Class) {
      Class<?> c = (Class<?>) type;
      return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;

    } else if (type instanceof ParameterizedType) {
      ParameterizedType p = (ParameterizedType) type;
      return new ParameterizedTypeImpl(
          p.getOwnerType(), p.getRawType(), p.getActualTypeArguments());

    } else if (type instanceof GenericArrayType) {
      GenericArrayType g = (GenericArrayType) type;
      return new GenericArrayTypeImpl(g.getGenericComponentType());

    } else if (type instanceof WildcardType) {
      WildcardType w = (WildcardType) type;
      return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());

    } else {
      // type is either serializable as-is or unsupported
      return type;
    }
  }
示例#24
0
 Type capture(Type type) {
   checkNotNull(type);
   if (type instanceof Class) {
     return type;
   }
   if (type instanceof TypeVariable) {
     return type;
   }
   if (type instanceof GenericArrayType) {
     GenericArrayType arrayType = (GenericArrayType) type;
     return Types.newArrayType(capture(arrayType.getGenericComponentType()));
   }
   if (type instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type;
     return Types.newParameterizedTypeWithOwner(
         captureNullable(parameterizedType.getOwnerType()),
         (Class<?>) parameterizedType.getRawType(),
         capture(parameterizedType.getActualTypeArguments()));
   }
   if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     Type[] lowerBounds = wildcardType.getLowerBounds();
     if (lowerBounds.length == 0) { // ? extends something changes to capture-of
       Type[] upperBounds = wildcardType.getUpperBounds();
       String name =
           "capture#"
               + id.incrementAndGet()
               + "-of ? extends "
               + Joiner.on('&').join(upperBounds);
       return Types.newTypeVariable(WildcardCapturer.class, name, wildcardType.getUpperBounds());
     } else {
       // TODO(benyu): handle ? super T somehow.
       return type;
     }
   }
   throw new AssertionError("must have been one of the known types");
 }
示例#25
0
  /** 得到实际Type类型对应的Class */
  public static Class<?> asClass(Type actualType) {

    if (actualType instanceof Class) return (Class<?>) actualType;

    if (actualType instanceof ParameterizedType) {
      final Type rawType = ((ParameterizedType) actualType).getRawType();
      // The sun implementation returns getRawType as Class<?>, but there is room in the interface
      // for it to be
      // some other Type. We'll assume it's a Class.
      // TODO: consider logging or throwing our own exception for that day when "something else"
      // causes some confusion
      return (Class) rawType;
    }

    if (actualType instanceof GenericArrayType) {
      final Type type = ((GenericArrayType) actualType).getGenericComponentType();
      return Array.newInstance(asClass(type), 0).getClass();
    }

    if (actualType instanceof TypeVariable) {
      // Support for List<T extends Number>
      // There is always at least one bound. If no bound is specified in the source then it will be
      // Object.class
      return asClass(((TypeVariable) actualType).getBounds()[0]);
    }

    if (actualType instanceof WildcardType) {
      final WildcardType wildcardType = (WildcardType) actualType;
      final Type[] bounds = wildcardType.getLowerBounds();
      if (bounds != null && bounds.length > 0) {
        return asClass(bounds[0]);
      }
      // If there is no lower bounds then the only thing that makes sense is Object.
      return Object.class;
    }
    throw new RuntimeException(String.format("Unable to convert %s to Class.", actualType));
  }
示例#26
0
  private static void typeToString(StringBuilder sb, Type type, Set<Type> visited) {
    if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) type;
      final Class<?> rawType = (Class<?>) parameterizedType.getRawType();
      sb.append(rawType.getName());
      boolean first = true;
      for (Type typeArg : parameterizedType.getActualTypeArguments()) {
        if (first) {
          first = false;
        } else {
          sb.append(", ");
        }
        sb.append('<');
        typeToString(sb, typeArg, visited);
        sb.append('>');
      }
    } else if (type instanceof WildcardType) {
      WildcardType wildcardType = (WildcardType) type;
      sb.append('?');

      // According to
      // JLS(http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.5.1):
      // - Lower and upper can't coexist: (for instance, this is not allowed: <? extends
      // List<String> & super MyInterface>)
      // - Multiple bounds are not supported (for instance, this is not allowed: <? extends
      // List<String> & MyInterface>)

      final Type bound;
      if (wildcardType.getLowerBounds().length != 0) {
        sb.append(" super ");
        bound = wildcardType.getLowerBounds()[0];
      } else {
        sb.append(" extends ");
        bound = wildcardType.getUpperBounds()[0];
      }
      typeToString(sb, bound, visited);
    } else if (type instanceof TypeVariable<?>) {
      TypeVariable<?> typeVariable = (TypeVariable<?>) type;
      sb.append(typeVariable.getName());

      // prevent cycles in case: <T extends List<T>>

      if (!visited.contains(type)) {
        visited.add(type);
        sb.append(" extends ");
        boolean first = true;
        for (Type bound : typeVariable.getBounds()) {
          if (first) {
            first = false;
          } else {
            sb.append(" & ");
          }
          typeToString(sb, bound, visited);
        }
        visited.remove(type);
      }
    } else if (type instanceof GenericArrayType) {
      GenericArrayType genericArrayType = (GenericArrayType) type;
      typeToString(genericArrayType.getGenericComponentType());
      sb.append(genericArrayType.getGenericComponentType());
      sb.append("[]");
    } else if (type instanceof Class) {
      Class<?> typeClass = (Class<?>) type;
      sb.append(typeClass.getName());
    } else {
      throw new IllegalArgumentException("Unsupported type: " + type);
    }
  }
示例#27
0
  public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
    // this implementation is made a little more complicated in an attempt
    // to avoid object-creation
    while (true) {
      if (toResolve instanceof TypeVariable) {
        TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
        toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
        if (toResolve == typeVariable) {
          return toResolve;
        }

      } else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
        Class<?> original = (Class<?>) toResolve;
        Type componentType = original.getComponentType();
        Type newComponentType = resolve(context, contextRawType, componentType);
        return componentType == newComponentType ? original : arrayOf(newComponentType);

      } else if (toResolve instanceof GenericArrayType) {
        GenericArrayType original = (GenericArrayType) toResolve;
        Type componentType = original.getGenericComponentType();
        Type newComponentType = resolve(context, contextRawType, componentType);
        return componentType == newComponentType ? original : arrayOf(newComponentType);

      } else if (toResolve instanceof ParameterizedType) {
        ParameterizedType original = (ParameterizedType) toResolve;
        Type ownerType = original.getOwnerType();
        Type newOwnerType = resolve(context, contextRawType, ownerType);
        boolean changed = newOwnerType != ownerType;

        Type[] args = original.getActualTypeArguments();
        for (int t = 0, length = args.length; t < length; t++) {
          Type resolvedTypeArgument = resolve(context, contextRawType, args[t]);
          if (resolvedTypeArgument != args[t]) {
            if (!changed) {
              args = args.clone();
              changed = true;
            }
            args[t] = resolvedTypeArgument;
          }
        }

        return changed
            ? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
            : original;

      } else if (toResolve instanceof WildcardType) {
        WildcardType original = (WildcardType) toResolve;
        Type[] originalLowerBound = original.getLowerBounds();
        Type[] originalUpperBound = original.getUpperBounds();

        if (originalLowerBound.length == 1) {
          Type lowerBound = resolve(context, contextRawType, originalLowerBound[0]);
          if (lowerBound != originalLowerBound[0]) {
            return supertypeOf(lowerBound);
          }
        } else if (originalUpperBound.length == 1) {
          Type upperBound = resolve(context, contextRawType, originalUpperBound[0]);
          if (upperBound != originalUpperBound[0]) {
            return subtypeOf(upperBound);
          }
        }
        return original;

      } else {
        return toResolve;
      }
    }
  }
示例#28
0
 static TypeName get(WildcardType wildcardName, Map<Type, TypeVariableName> map) {
   return new WildcardTypeName(
       list(wildcardName.getUpperBounds(), map), list(wildcardName.getLowerBounds(), map));
 }
示例#29
0
  /**
   * Returns an array containing a single value of <code>null</code> if {@link
   * WildcardType#getLowerBounds()} returns an empty array. Otherwise, it returns the result of
   * <code>WildcardType.getLowerBounds()</code>.
   *
   * @param wildcardType the subject wildcard type
   * @return a non-empty array containing the lower bounds of the wildcard type.
   */
  public static Type[] getImplicitLowerBounds(WildcardType wildcardType) {
    Type[] bounds = wildcardType.getLowerBounds();

    return bounds.length == 0 ? new Type[] {null} : bounds;
  }
 public void testWithGenericLowerBoundInWildcard() throws Exception {
   WildcardType wildcardType =
       (WildcardType) new WithGenericBound<String>() {}.getTargetType("withWildcardLowerBound");
   assertEquals(String.class, wildcardType.getLowerBounds()[0]);
 }