public void testWithMutualRecursiveBoundInTypeVariable() throws Exception {
   ParameterizedType paramType =
       (ParameterizedType)
           new WithGenericBound<String>() {}.getTargetType("withMutualRecursiveBound");
   TypeVariable<?> k = (TypeVariable<?>) paramType.getActualTypeArguments()[0];
   TypeVariable<?> v = (TypeVariable<?>) paramType.getActualTypeArguments()[1];
   assertEquals(Types.newParameterizedType(List.class, v), k.getBounds()[0]);
   assertEquals(Types.newParameterizedType(List.class, k), v.getBounds()[0]);
 }
示例#2
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());
   }
 }
示例#3
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;
 }
示例#4
0
 public static boolean isAssignableFrom(
     Class<?> rawType1, Type[] actualTypeArguments1, Type type2) {
   if (type2 instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type2;
     if (parameterizedType.getRawType() instanceof Class<?>) {
       if (isAssignableFrom(
           rawType1,
           actualTypeArguments1,
           (Class<?>) parameterizedType.getRawType(),
           parameterizedType.getActualTypeArguments())) {
         return true;
       }
     }
   } else if (type2 instanceof Class<?>) {
     Class<?> clazz = (Class<?>) type2;
     if (isAssignableFrom(rawType1, actualTypeArguments1, clazz, EMPTY_TYPES)) {
       return true;
     }
   } else if (type2 instanceof TypeVariable<?>) {
     TypeVariable<?> typeVariable = (TypeVariable<?>) type2;
     if (isTypeBounded(rawType1, actualTypeArguments1, typeVariable.getBounds())) {
       return true;
     }
   }
   return false;
 }
示例#5
0
 public static Class<?> getActualClass(final Type type, final Map<TypeVariable<?>, Type> map) {
   if (Class.class.isInstance(type)) {
     return Class.class.cast(type);
   }
   if (ParameterizedType.class.isInstance(type)) {
     return getActualClass(ParameterizedType.class.cast(type).getRawType(), map);
   }
   if (WildcardType.class.isInstance(type)) {
     return getActualClass(WildcardType.class.cast(type).getUpperBounds()[0], map);
   }
   if (TypeVariable.class.isInstance(type)) {
     final TypeVariable<?> typeVariable = TypeVariable.class.cast(type);
     if (map.containsKey(typeVariable)) {
       return getActualClass(map.get(typeVariable), map);
     }
     return getActualClass(typeVariable.getBounds()[0], map);
   }
   if (GenericArrayType.class.isInstance(type)) {
     final GenericArrayType genericArrayType = GenericArrayType.class.cast(type);
     final Class<?> componentClass =
         getActualClass(genericArrayType.getGenericComponentType(), map);
     return Array.newInstance(componentClass, 0).getClass();
   }
   return null;
 }
 public boolean equals(Object o) {
   if (!(o instanceof TypeVariable)) return false;
   TypeVariable tv = (TypeVariable) o;
   return equal(name, tv.getName())
       && equal(gd, tv.getGenericDeclaration())
       && Arrays.equals(bounds, tv.getBounds());
 }
 /**
  * True if this type variable is one of the java.* special cases
  *
  * @return
  */
 private boolean isSpecialCase(TypeVariable<?> typeVariable) {
   for (Type bound : typeVariable.getBounds()) {
     Class<?> clazz = GenericTypeReflector.erase(bound);
     if (specialCases.contains(clazz)) return true;
   }
   return false;
 }
示例#8
0
 /** getDefaultType的统一入口 */
 private static Type getDefaultType(Type type, Map<TypeVariable<?>, Type> handledArguments) {
   if (type instanceof TypeVariable<?>) {
     TypeVariable<?> tv = (TypeVariable<?>) type;
     return getDefaultType(tv.getBounds(), handledArguments, tv);
   } else {
     return getDefaultType(type, handledArguments, null);
   }
 }
  private static boolean isTypeVariableAssignable(Type supertype, TypeVariable<?> type) {
    for (Type bound : type.getBounds()) {
      if (isAssignable(supertype, bound)) {
        return true;
      }
    }

    return false;
  }
示例#10
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;
 }
  private void addType(Type cls, boolean allowArray) {
    if (cls instanceof Class) {
      if (globalAdapters.contains(cls)) {
        return;
      }
      if (((Class<?>) cls).isArray() && !allowArray) {
        addClass(((Class<?>) cls).getComponentType());
      } else {
        addClass((Class<?>) cls);
      }
    } else if (cls instanceof ParameterizedType) {
      final ParameterizedType parameterizedType = (ParameterizedType) cls;
      addType(parameterizedType.getRawType());
      if (!parameterizedType.getRawType().equals(Enum.class)) {
        for (Type t2 : parameterizedType.getActualTypeArguments()) {
          if (shouldTypeBeAdded(t2, parameterizedType)) {
            addType(t2);
          }
        }
      }
    } else if (cls instanceof GenericArrayType) {
      Class<?> ct;
      GenericArrayType gt = (GenericArrayType) cls;
      Type componentType = gt.getGenericComponentType();
      if (componentType instanceof Class) {
        ct = (Class<?>) componentType;
      } else {
        TypeVariable<?> tv = (TypeVariable<?>) componentType;
        Type[] bounds = tv.getBounds();
        if (bounds != null && bounds.length == 1) {
          if (bounds[0] instanceof Class) {
            ct = (Class<?>) bounds[0];
          } else {
            throw new IllegalArgumentException("Unable to determine type for: " + tv);
          }
        } else {
          throw new IllegalArgumentException("Unable to determine type for: " + tv);
        }
      }
      ct = Array.newInstance(ct, 0).getClass();

      addClass(ct);
    } else if (cls instanceof WildcardType) {
      for (Type t : ((WildcardType) cls).getUpperBounds()) {
        addType(t);
      }
      for (Type t : ((WildcardType) cls).getLowerBounds()) {
        addType(t);
      }
    } else if (cls instanceof TypeVariable) {
      for (Type t : ((TypeVariable<?>) cls).getBounds()) {
        addType(t);
      }
    }
  }
示例#12
0
  /**
   * Method to resolve a TypeVariable to its most <a
   * href="http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#112582">reifiable</a>
   * form.
   *
   * <p>How to resolve a TypeVariable:<br>
   * All of the TypeVariables defined by a generic class will be given a Type by any class that
   * extends it. The Type given may or may not be reifiable; it may be another TypeVariable for
   * instance.
   *
   * <p>Consider <br>
   * <i>class Pair&gt;A,B> { A getA(){...}; ...}</i><br>
   * <i>class StringLongPair extends Pair&gt;String, Long> { }</i><br>
   * To resolve the actual return type of Pair.getA() you must first resolve the TypeVariable "A".
   * We can do that by first finding the index of "A" in the Pair.class.getTypeParameters() array of
   * TypeVariables.
   *
   * <p>To get to the Type provided by StringLongPair you access the generics information by calling
   * StringLongPair.class.getGenericSuperclass; this will be a ParameterizedType. ParameterizedType
   * gives you access to the actual type arguments provided to Pair by StringLongPair. The array is
   * in the same order as the array in Pair.class.getTypeParameters so you can use the index we
   * discovered earlier to extract the Type; String.class.
   *
   * <p>When extracting Types we only have to consider the superclass hierarchy and not the
   * interfaces implemented by the class. When a class implements a generic interface it must
   * provide types for the interface and any generic methods implemented from the interface will be
   * re-defined by the class with its generic type variables.
   *
   * @param typeVariable - the type variable to resolve.
   * @param containingType - the shallowest class in the class hierarchy (furthest from Object)
   *     where typeVariable is defined.
   * @return a Type that has had all possible TypeVariables resolved that have been defined between
   *     the type variable declaration and the containingType.
   */
  private static Type resolve(TypeVariable typeVariable, Type containingType) {
    // The generic declaration is either a Class, Method or Constructor
    final GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();

    if (!(genericDeclaration instanceof Class)) {
      // It's a method or constructor. The best we can do here is try to resolve the bounds
      // e.g. <T extends E> T getT(T param){} where E is defined by the class.
      final Type bounds0 = typeVariable.getBounds()[0];
      return resolve(bounds0, containingType);
    }

    final Class typeVariableOwner = (Class) genericDeclaration;

    // find the typeOwner in the containingType's hierarchy
    final LinkedList<Type> stack = new LinkedList<Type>();

    // If you pass a List<Long> as the containingType then the TypeVariable is going to be resolved
    // by the
    // containingType and not the super class.
    if (containingType instanceof ParameterizedType) {
      stack.add(containingType);
    }

    Class theClass = asClass(containingType);
    Type genericSuperclass = theClass.getGenericSuperclass();
    while (genericSuperclass != null
        && // true for interfaces with no superclass
        !theClass.equals(Object.class)
        && !theClass.equals(typeVariableOwner)) {
      stack.addFirst(genericSuperclass);
      theClass = asClass(genericSuperclass);
      genericSuperclass = theClass.getGenericSuperclass();
    }

    int i = getTypeVariableIndex(typeVariable);
    Type resolved = typeVariable;
    for (Type t : stack) {
      if (t instanceof ParameterizedType) {
        resolved = ((ParameterizedType) t).getActualTypeArguments()[i];
        if (resolved instanceof Class) return resolved;
        if (resolved instanceof TypeVariable) {
          // Need to look at the next class in the hierarchy
          i = getTypeVariableIndex((TypeVariable) resolved);
          continue;
        }
        return resolve(resolved, containingType);
      }
    }

    // the only way we get here is if resolved is still a TypeVariable, otherwise an
    // exception is thrown or a value is returned.
    return ((TypeVariable) resolved).getBounds()[0];
  }
 private boolean shouldTypeBeAdded(final Type t2, final ParameterizedType parameterizedType) {
   if (!(t2 instanceof TypeVariable)) {
     return true;
   }
   TypeVariable<?> typeVariable = (TypeVariable<?>) t2;
   final Type[] bounds = typeVariable.getBounds();
   for (Type bound : bounds) {
     if (bound instanceof ParameterizedType && bound.equals(parameterizedType)) {
       return false;
     }
   }
   return true;
 }
示例#14
0
 public static Class resolveToClass(Type type) {
   if (type == null) {
     throw new NullPointerException("No null type accepted");
   }
   if (type instanceof Class<?>) {
     return (Class<?>) type;
   } else if (type instanceof TypeVariable) {
     TypeVariable resolvedTypeVariable = (TypeVariable) type;
     return resolveToClass(resolvedTypeVariable.getBounds()[0]);
   } else {
     throw new UnsupportedOperationException(
         "Type resolution of " + type + " not yet implemented");
   }
 }
示例#15
0
 /**
  * Resolves {@code var} using the encapsulated type mapping. If it maps to yet another
  * non-reified type or has bounds, {@code forDependants} is used to do further resolution, which
  * doesn't try to resolve any type variable on generic declarations that are already being
  * resolved.
  *
  * <p>Should only be called and overridden by {@link #resolve(TypeVariable)}.
  */
 Type resolveInternal(TypeVariable<?> var, TypeTable forDependants) {
   Type type = map.get(var);
   if (type == null) {
     Type[] bounds = var.getBounds();
     if (bounds.length == 0) {
       return var;
     }
     return Types.newTypeVariable(
         var.getGenericDeclaration(),
         var.getName(),
         new TypeResolver(forDependants).resolveTypes(bounds));
   }
   // in case the type is yet another type variable.
   return new TypeResolver(forDependants).resolveType(type);
 }
示例#16
0
 private GenericsType configureTypeVariableDefinition(TypeVariable tv) {
   ClassNode base = configureTypeVariableReference(tv);
   ClassNode redirect = base.redirect();
   base.setRedirect(null);
   Type[] tBounds = tv.getBounds();
   GenericsType gt;
   if (tBounds.length == 0) {
     gt = new GenericsType(base);
   } else {
     ClassNode[] cBounds = configureTypes(tBounds);
     gt = new GenericsType(base, cBounds, null);
     gt.setName(base.getName());
     gt.setPlaceholder(true);
   }
   base.setRedirect(redirect);
   return gt;
 }
示例#17
0
  private void buildGenericTypeVariables(Class<?>[] genericTypes) {
    if (samType.getTypeParameters().length != genericTypes.length)
      throw new LambdaException(
          "SAM class [%s] requires [%d] generic type variables, but only [%d] where provided",
          samType.getName(), samType.getTypeParameters().length, genericTypes.length);

    for (int i = 0; i < samType.getTypeParameters().length; i++) {
      TypeVariable typeVariable = samType.getTypeParameters()[i];
      for (Type bound : typeVariable.getBounds())
        if (bound instanceof Class<?> && !((Class) bound).isAssignableFrom(genericTypes[i]))
          throw new LambdaException(
              "SAM class [%s] generic type variable [%d, %s] is not compatible with generic parameter [%s]",
              samType.getName(), i, samType.getTypeParameters()[i].toString(), genericTypes[i]);
      materializedTypeVariableses.add(
          new MaterializedTypeVariable(typeVariable.getName(), genericTypes[i]));
    }
  }
示例#18
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;
  }
示例#19
0
 private Class<?> extractInjectionClass(ParameterizedType parameterizedType) {
   Type type = parameterizedType.getActualTypeArguments()[0];
   if (type instanceof Class) {
     return (Class<?>) type;
   } else if (type instanceof ParameterizedType) {
     return (Class<?>) ((ParameterizedType) type).getRawType();
   } else if (type instanceof WildcardType) {
     // To handle for instance Class<? extends Habba>, which will then return habba
     WildcardType wcType = (WildcardType) type;
     return (Class) wcType.getUpperBounds()[0];
   } else if (type instanceof TypeVariable) {
     TypeVariable tv = (TypeVariable) type;
     return (Class) tv.getBounds()[0];
   }
   throw new IllegalArgumentException(
       "Could not extract injectionClass of Type " + parameterizedType);
 }
示例#20
0
 /*     */ public JavaType getType(TypeBindings bindings) /*     */ {
   /*  66 */ TypeVariable[] localTypeParams = this._constructor.getTypeParameters();
   /*     */
   /*  68 */ if ((localTypeParams != null) && (localTypeParams.length > 0)) {
     /*  69 */ bindings = bindings.childInstance();
     /*  70 */ for (TypeVariable var : localTypeParams) {
       /*  71 */ String name = var.getName();
       /*     */
       /*  73 */ bindings._addPlaceholder(name);
       /*     */
       /*  75 */ Type lowerBound = var.getBounds()[0];
       /*  76 */ JavaType type =
           lowerBound == null
               ? TypeFactory.fastSimpleType(Object.class)
               : TypeFactory.type(lowerBound, bindings);
       /*     */
       /*  78 */ bindings.addBinding(var.getName(), type);
       /*     */ }
     /*     */ }
   /*  81 */ return TypeFactory.type(getGenericType(), bindings);
   /*     */ }
示例#21
0
  protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context) {
    /* 26-Sep-2009, tatus: It should be possible to try "partial"
     *  resolution; meaning that it is ok not to find bindings.
     *  For now this is indicated by passing null context.
     */
    if (context == null) {
      return _unknownType();
    }

    // Ok: here's where context might come in handy!
    String name = type.getName();
    JavaType actualType = context.findType(name);
    if (actualType != null) {
      return actualType;
    }

    /* 29-Jan-2010, tatu: We used to throw exception here, if type was
     *   bound: but the problem is that this can occur for generic "base"
     *   method, overridden by sub-class. If so, we will want to ignore
     *   current type (for method) since it will be masked.
     */
    Type[] bounds = type.getBounds();

    // With type variables we must use bound information.
    // Theoretically this gets tricky, as there may be multiple
    // bounds ("... extends A & B"); and optimally we might
    // want to choose the best match. Also, bounds are optional;
    // but here we are lucky in that implicit "Object" is
    // added as bounds if so.
    // Either way let's just use the first bound, for now, and
    // worry about better match later on if there is need.

    /* 29-Jan-2010, tatu: One more problem are recursive types
     *   (T extends Comparable<T>). Need to add "placeholder"
     *   for resolution to catch those.
     */
    context._addPlaceholder(name);
    return _fromType(bounds[0], context);
  }
示例#22
0
  public static Map<TypeVariable<?>, Type> getTypeVariableMap(final Class<?> clazz) {
    final Map<TypeVariable<?>, Type> map = LdiCollectionsUtil.newLinkedHashMap();

    final TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
    for (TypeVariable<?> typeParameter : typeParameters) {
      map.put(typeParameter, getActualClass(typeParameter.getBounds()[0], map));
    }

    final Class<?> superClass = clazz.getSuperclass();
    final Type superClassType = clazz.getGenericSuperclass();
    if (superClass != null) {
      gatherTypeVariables(superClass, superClassType, map);
    }

    final Class<?>[] interfaces = clazz.getInterfaces();
    final Type[] interfaceTypes = clazz.getGenericInterfaces();
    for (int i = 0; i < interfaces.length; ++i) {
      gatherTypeVariables(interfaces[i], interfaceTypes[i], map);
    }

    return map;
  }
 /** Generates the signature for the given constructor */
 private String signature(Constructor<?> constructor) {
   StringBuilder builder = new StringBuilder();
   if (constructor.getTypeParameters().length > 0) {
     builder.append('<');
     for (TypeVariable<?> typeVariable : constructor.getTypeParameters()) {
       builder.append(typeVariable.getName());
       for (java.lang.reflect.Type bound : typeVariable.getBounds()) {
         builder.append(':');
         visitType(bound, builder);
       }
     }
     builder.append('>');
   }
   builder.append('(');
   for (java.lang.reflect.Type paramType : constructor.getGenericParameterTypes()) {
     visitType(paramType, builder);
   }
   builder.append(")V");
   for (java.lang.reflect.Type exceptionType : constructor.getGenericExceptionTypes()) {
     builder.append('^');
     visitType(exceptionType, builder);
   }
   return builder.toString();
 }
示例#24
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);
    }
  }
  public Object parseArrayWithType(Type collectionType) {
    if (lexer.token() == JSONToken.NULL) {
      lexer.nextToken();
      return null;
    }

    Type[] actualTypes = ((ParameterizedType) collectionType).getActualTypeArguments();

    if (actualTypes.length != 1) {
      throw new JSONException("not support type " + collectionType);
    }

    Type actualTypeArgument = actualTypes[0];

    if (actualTypeArgument instanceof Class) {
      List<Object> array = new ArrayList<Object>();
      this.parseArray((Class<?>) actualTypeArgument, array);
      return array;
    }

    if (actualTypeArgument instanceof WildcardType) {
      WildcardType wildcardType = (WildcardType) actualTypeArgument;

      // assert wildcardType.getUpperBounds().length == 1;
      Type upperBoundType = wildcardType.getUpperBounds()[0];

      // assert upperBoundType instanceof Class;
      if (Object.class.equals(upperBoundType)) {
        if (wildcardType.getLowerBounds().length == 0) {
          // Collection<?>
          return parse();
        } else {
          throw new JSONException("not support type : " + collectionType);
        }
      }

      List<Object> array = new ArrayList<Object>();
      this.parseArray((Class<?>) upperBoundType, array);
      return array;

      // throw new JSONException("not support type : " +
      // collectionType);return parse();
    }

    if (actualTypeArgument instanceof TypeVariable) {
      TypeVariable<?> typeVariable = (TypeVariable<?>) actualTypeArgument;
      Type[] bounds = typeVariable.getBounds();

      if (bounds.length != 1) {
        throw new JSONException("not support : " + typeVariable);
      }

      Type boundType = bounds[0];
      if (boundType instanceof Class) {
        List<Object> array = new ArrayList<Object>();
        this.parseArray((Class<?>) boundType, array);
        return array;
      }
    }

    if (actualTypeArgument instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) actualTypeArgument;

      List<Object> array = new ArrayList<Object>();
      this.parseArray(parameterizedType, array);
      return array;
    }

    throw new JSONException("TODO : " + collectionType);
  }
示例#26
0
 private Class<?> extractInjectionClass(TypeVariable<?> typeVariable) {
   return (Class<?>) typeVariable.getBounds()[0];
 }
  private boolean addAssignableClass(
      TypeVariable<?> typeVariable, Map<TypeVariable<?>, Type> typeMap) {
    Set<Class<?>> classes = TestCluster.getInstance().getAnalyzedClasses();
    Set<Class<?>> assignableClasses = new LinkedHashSet<Class<?>>();

    for (Class<?> clazz : classes) {
      if (!TestUsageChecker.canUse(clazz)) continue;

      GenericClass genericClass = new GenericClass(clazz).getWithWildcardTypes();

      if (!genericClass.satisfiesBoundaries(typeVariable, typeMap)) {
        logger.debug("Not assignable: " + clazz);
      } else {
        logger.debug("Assignable");
        assignableClasses.add(clazz);
      }
    }
    for (Type t : typeMap.values()) {
      if (t instanceof WildcardType) continue; // TODO: For now.

      Class<?> clazz = GenericTypeReflector.erase(t);
      if (!TestUsageChecker.canUse(GenericTypeReflector.erase(clazz))) continue;

      GenericClass genericClass = new GenericClass(clazz).getWithWildcardTypes();
      if (!genericClass.satisfiesBoundaries(typeVariable, typeMap)) {
        logger.debug("Not assignable: " + clazz);
      } else {
        logger.debug("Assignable");
        assignableClasses.add(clazz);
      }
    }
    /*
    for (Type t : typeVariable.getBounds()) {
    	if (typeMap.containsKey(t))
    		t = typeMap.get(t);

    	Class<?> clazz = GenericTypeReflector.erase(t);
    	logger.debug("Checking bound: " + t);

    	if (!TestClusterGenerator.canUse(clazz))
    		continue;

    	GenericClass genericClass = new GenericClass(t);
    	//if (genericClass.hasTypeVariables()) {
    	logger.debug("Has type variables: " + genericClass
    	        + ", checking wildcard version with type map " + typeMap);
    	GenericClass wildcardClass = genericClass.getWithWildcardTypes();
    	//if (!wildcardClass.satisfiesBoundaries(typeVariable, typeMap)) {
    	//	logger.debug("Not assignable: " + clazz);
    	//} else {
    	//	logger.debug("Assignable");
    	assignableClasses.add(clazz);
    	//}
    	//} else {
    	//	logger.debug("Adding directly: " + genericClass);
    	//	assignableClasses.add(genericClass.getRawClass());
    	//	classMap.put(genericClass, 10);
    	//}
    }
    */
    logger.debug(
        "Found assignable classes for type variable "
            + typeVariable
            + ": "
            + assignableClasses.size());
    if (!assignableClasses.isEmpty()) {
      Class<?> clazz = Randomness.choice(assignableClasses);
      GenericClass castClass = new GenericClass(clazz);
      logger.debug("Adding cast class " + castClass);
      classMap.put(castClass, 10);
      return true;
    } else {
      InheritanceTree inheritanceTree = DependencyAnalysis.getInheritanceTree();
      Set<Class<?>> boundCandidates = new LinkedHashSet<Class<?>>();
      for (Type bound : typeVariable.getBounds()) {
        Class<?> rawBound = GenericTypeReflector.erase(bound);
        boundCandidates.add(rawBound);
        logger.debug("Getting concrete classes for " + rawBound);
        boundCandidates.addAll(ConcreteClassAnalyzer.getConcreteClasses(rawBound, inheritanceTree));
      }
      for (Class<?> clazz : boundCandidates) {
        if (!TestUsageChecker.canUse(clazz)) continue;

        boolean isAssignable = true;
        for (Type bound : typeVariable.getBounds()) {
          if (GenericTypeReflector.erase(bound).equals(Enum.class)) {
            if (clazz.isEnum()) continue;
          }

          if (!GenericClass.isAssignable(bound, clazz)) {
            isAssignable = false;
            logger.debug("Not assignable: " + clazz + " to bound " + bound);
            break;
          }
          if (bound instanceof ParameterizedType) {
            if (Arrays.asList(((ParameterizedType) bound).getActualTypeArguments())
                .contains(typeVariable)) {
              isAssignable = false;
              break;
            }
          }
        }
        if (isAssignable) {
          assignableClasses.add(clazz);
        }
      }
      logger.debug(
          "After adding bounds, found "
              + assignableClasses.size()
              + " assignable classes for type variable "
              + typeVariable
              + ": "
              + assignableClasses);
      if (!assignableClasses.isEmpty()) {
        // TODO: Add all classes?
        //				for(Class<?> clazz : assignableClasses) {
        //					GenericClass castClass = new GenericClass(clazz);
        //					logger.debug("Adding cast class " + castClass);
        //					classMap.put(castClass, 10);
        //				}
        Class<?> clazz = Randomness.choice(assignableClasses);
        GenericClass castClass = new GenericClass(clazz);
        logger.debug("Adding cast class " + castClass);
        classMap.put(castClass, 10);
        return true;
      }
    }

    return false;
  }
 public void testWithGenericBoundInTypeVariable() throws Exception {
   TypeVariable<?> typeVariable =
       (TypeVariable<?>) new WithGenericBound<String>() {}.getTargetType("withTypeVariable");
   assertEquals(String.class, typeVariable.getBounds()[0]);
 }
示例#29
0
  /**
   * Returns an array containing the sole type of {@link Object} if {@link TypeVariable#getBounds()}
   * returns an empty array. Otherwise, it returns the result of <code>TypeVariable.getBounds()
   * </code> passed into {@link #normalizeUpperBounds}.
   *
   * @param typeVariable the subject type variable
   * @return a non-empty array containing the bounds of the type variable.
   */
  public static Type[] getImplicitBounds(TypeVariable<?> typeVariable) {
    Type[] bounds = typeVariable.getBounds();

    return bounds.length == 0 ? new Type[] {Object.class} : normalizeUpperBounds(bounds);
  }
 public void testWithRecursiveBoundInTypeVariable() throws Exception {
   TypeVariable<?> typeVariable =
       (TypeVariable<?>) new WithGenericBound<String>() {}.getTargetType("withRecursiveBound");
   assertEquals(Types.newParameterizedType(Enum.class, typeVariable), typeVariable.getBounds()[0]);
 }