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]); }
@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()); } }
/** 获取一个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 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; }
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; }
/** 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; }
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); } } }
/** * 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>A,B> { A getA(){...}; ...}</i><br> * <i>class StringLongPair extends Pair>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; }
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"); } }
/** * 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); }
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; }
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])); } }
/** * 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; }
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); }
/* */ 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); /* */ }
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); }
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(); }
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); }
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]); }
/** * 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]); }