use of java.lang.reflect.WildcardType in project evosuite by EvoSuite.
the class GenericUtils method getMatchingTypeParameters.
/**
* TODO: Try to match p2 superclasses?
*
* @param p1 Desired TypeVariable assignment
* @param p2 Generic type with the TypeVariables that need assignment
* @return
*/
public static Map<TypeVariable<?>, Type> getMatchingTypeParameters(ParameterizedType p1, ParameterizedType p2) {
logger.debug("Matching generic types between " + p1 + " and " + p2);
Map<TypeVariable<?>, Type> map = new HashMap<TypeVariable<?>, Type>();
if (!p1.getRawType().equals(p2.getRawType())) {
logger.debug("Raw types do not match!");
GenericClass ownerClass = new GenericClass(p2);
if (GenericClass.isSubclass(p1.getRawType(), p2.getRawType())) {
logger.debug(p1 + " is a super type of " + p2);
Map<TypeVariable<?>, Type> commonsMap = TypeUtils.determineTypeArguments((Class<?>) p2.getRawType(), p1);
logger.debug("Adding to map: " + commonsMap);
for (TypeVariable<?> t : map.keySet()) {
logger.debug(t + ": " + t.getGenericDeclaration());
}
// For each type variable of the raw type, map the parameter type to that type
Type[] p2TypesA = ((Class<?>) p2.getRawType()).getTypeParameters();
Type[] p2TypesB = p2.getActualTypeArguments();
for (int i = 0; i < p2TypesA.length; i++) {
Type a = p2TypesA[i];
Type b = p2TypesB[i];
logger.debug("Should be mapping " + a + " and " + b);
if (a instanceof TypeVariable<?>) {
logger.debug(a + " is a type variable: " + ((TypeVariable<?>) a).getGenericDeclaration());
if (b instanceof TypeVariable<?>) {
logger.debug(b + " is a type variable: " + ((TypeVariable<?>) b).getGenericDeclaration());
if (commonsMap.containsKey((TypeVariable<?>) a) && !(commonsMap.get((TypeVariable<?>) a) instanceof WildcardType) && !(commonsMap.get((TypeVariable<?>) a) instanceof TypeVariable<?>))
map.put((TypeVariable<?>) b, commonsMap.get((TypeVariable<?>) a));
// else
// map.put((TypeVariable<?>)a, b);
}
}
// if(b instanceof TypeVariable<?>) {
// if(map.containsKey(a))
// map.put((TypeVariable<?>)b, map.get(a));
// //else
// // map.put((TypeVariable<?>)b, a);
// }
logger.debug("Updated map: " + map);
}
}
for (GenericClass interfaceClass : ownerClass.getInterfaces()) {
if (interfaceClass.isParameterizedType())
map.putAll(getMatchingTypeParameters(p1, (ParameterizedType) interfaceClass.getType()));
else
logger.debug("Interface " + interfaceClass + " is not parameterized");
}
if (ownerClass.getRawClass().getSuperclass() != null) {
GenericClass ownerSuperClass = ownerClass.getSuperClass();
if (ownerSuperClass.isParameterizedType())
map.putAll(getMatchingTypeParameters(p1, (ParameterizedType) ownerSuperClass.getType()));
else
logger.debug("Super type " + ownerSuperClass + " is not parameterized");
}
return map;
}
for (int i = 0; i < p1.getActualTypeArguments().length; i++) {
Type t1 = p1.getActualTypeArguments()[i];
Type t2 = p2.getActualTypeArguments()[i];
if (t1 == t2)
continue;
logger.debug("First match: " + t1 + " - " + t2);
if (t1 instanceof TypeVariable<?>) {
map.put((TypeVariable<?>) t1, t2);
}
if (t2 instanceof TypeVariable<?>) {
map.put((TypeVariable<?>) t2, t1);
} else if (t2 instanceof ParameterizedType && t1 instanceof ParameterizedType) {
map.putAll(getMatchingTypeParameters((ParameterizedType) t1, (ParameterizedType) t2));
}
logger.debug("Updated map: " + map);
}
if (p1.getOwnerType() != null && p1.getOwnerType() instanceof ParameterizedType && p2.getOwnerType() instanceof ParameterizedType) {
map.putAll(getMatchingTypeParameters((ParameterizedType) p1.getOwnerType(), (ParameterizedType) p2.getOwnerType()));
}
return map;
}
use of java.lang.reflect.WildcardType in project moshi by square.
the class Util method resolve.
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 ? new ParameterizedTypeImpl(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;
}
}
}
use of java.lang.reflect.WildcardType in project LanternServer by LanternPowered.
the class TypeTokenHelper method isAssignable.
private static boolean isAssignable(Type type, ParameterizedType toType, @Nullable Type parent, int index) {
if (type instanceof Class) {
final Class<?> other = (Class<?>) type;
final Class<?> toRaw = (Class<?>) toType.getRawType();
final Type toEnclosing = toType.getOwnerType();
if (toEnclosing != null && !Modifier.isStatic(toRaw.getModifiers())) {
final Class<?> otherEnclosing = other.getEnclosingClass();
if (otherEnclosing == null || !isAssignable(otherEnclosing, toEnclosing, null, 0)) {
return false;
}
}
if (!toRaw.isAssignableFrom(other)) {
return false;
}
// Check if the default generic parameters match the parameters
// of the parameterized type
final Type[] toTypes = toType.getActualTypeArguments();
final TypeVariable[] types = toRaw.getTypeParameters();
if (types.length != toTypes.length) {
return false;
}
for (int i = 0; i < types.length; i++) {
if (!isAssignable(types[i], toTypes[i], other, i)) {
return false;
}
}
return true;
}
if (type instanceof ParameterizedType) {
ParameterizedType other = (ParameterizedType) type;
final Class<?> otherRaw = (Class<?>) other.getRawType();
final Class<?> toRaw = (Class<?>) toType.getRawType();
if (!toRaw.isAssignableFrom(otherRaw)) {
return false;
}
final Type toEnclosing = toType.getOwnerType();
if (toEnclosing != null && !Modifier.isStatic(toRaw.getModifiers())) {
final Type otherEnclosing = other.getOwnerType();
if (otherEnclosing == null || !isAssignable(otherEnclosing, toEnclosing, null, 0)) {
return false;
}
}
final Type[] types;
if (otherRaw.equals(toRaw)) {
types = other.getActualTypeArguments();
} else {
// Get the type parameters based on the super class
other = (ParameterizedType) TypeToken.of(type).getSupertype((Class) toRaw).getType();
types = other.getActualTypeArguments();
}
final Type[] toTypes = toType.getActualTypeArguments();
if (types.length != toTypes.length) {
return false;
}
for (int i = 0; i < types.length; i++) {
if (!isAssignable(types[i], toTypes[i], other, i)) {
return false;
}
}
return true;
}
if (type instanceof TypeVariable) {
final TypeVariable other = (TypeVariable) type;
return allSupertypes(toType, other.getBounds());
}
if (type instanceof WildcardType) {
final WildcardType other = (WildcardType) type;
return allWildcardSupertypes(toType, other.getUpperBounds(), parent, index) && allAssignable(toType, other.getLowerBounds());
}
if (type instanceof GenericArrayType) {
final GenericArrayType other = (GenericArrayType) type;
final Class<?> rawType = (Class<?>) toType.getRawType();
return rawType.equals(Object.class) || (rawType.isArray() && isAssignable(other.getGenericComponentType(), rawType.getComponentType(), parent, index));
}
throw new IllegalStateException("Unsupported type: " + type);
}
use of java.lang.reflect.WildcardType in project dolphin-platform by canoo.
the class TypeUtils method unrollVariables.
/**
* Get a type representing {@code type} with variable assignments "unrolled."
*
* @param typeArguments
* @param type the type to unroll variable assignments for
* @return Type
* @since 3.2
*/
private static Type unrollVariables(Map<TypeVariable<?>, Type> typeArguments, final Type type) {
if (typeArguments == null) {
typeArguments = Collections.emptyMap();
}
if (containsTypeVariables(type)) {
if (type instanceof TypeVariable<?>) {
return unrollVariables(typeArguments, typeArguments.get(type));
}
if (type instanceof ParameterizedType) {
final ParameterizedType p = (ParameterizedType) type;
final Map<TypeVariable<?>, Type> parameterizedTypeArguments;
if (p.getOwnerType() == null) {
parameterizedTypeArguments = typeArguments;
} else {
parameterizedTypeArguments = new HashMap<>(typeArguments);
parameterizedTypeArguments.putAll(TypeUtils.getTypeArguments(p));
}
final Type[] args = p.getActualTypeArguments();
for (int i = 0; i < args.length; i++) {
final Type unrolled = unrollVariables(parameterizedTypeArguments, args[i]);
if (unrolled != null) {
args[i] = unrolled;
}
}
return parameterizeWithOwner(p.getOwnerType(), (Class<?>) p.getRawType(), args);
}
if (type instanceof WildcardType) {
final WildcardType wild = (WildcardType) type;
return wildcardType().withUpperBounds(unrollBounds(typeArguments, wild.getUpperBounds())).withLowerBounds(unrollBounds(typeArguments, wild.getLowerBounds())).build();
}
}
return type;
}
use of java.lang.reflect.WildcardType in project dolphin-platform by canoo.
the class TypeUtils method isAssignable.
/**
* <p>Checks if the subject type may be implicitly cast to the target
* wildcard type following the Java generics rules.</p>
*
* @param type the subject type to be assigned to the target type
* @param toWildcardType the target wildcard type
* @param typeVarAssigns a map with type variables
* @return {@code true} if {@code type} is assignable to
* {@code toWildcardType}.
*/
private static boolean isAssignable(final Type type, final WildcardType toWildcardType, final Map<TypeVariable<?>, Type> typeVarAssigns) {
if (type == null) {
return true;
}
// would have cause the previous to return true
if (toWildcardType == null) {
return false;
}
// all types are assignable to themselves
if (toWildcardType.equals(type)) {
return true;
}
final Type[] toUpperBounds = getImplicitUpperBounds(toWildcardType);
final Type[] toLowerBounds = getImplicitLowerBounds(toWildcardType);
if (type instanceof WildcardType) {
final WildcardType wildcardType = (WildcardType) type;
final Type[] upperBounds = getImplicitUpperBounds(wildcardType);
final Type[] lowerBounds = getImplicitLowerBounds(wildcardType);
for (Type toBound : toUpperBounds) {
// if there are assignments for unresolved type variables,
// now's the time to substitute them.
toBound = substituteTypeVariables(toBound, typeVarAssigns);
// upper bound of the target type
for (final Type bound : upperBounds) {
if (!isAssignable(bound, toBound, typeVarAssigns)) {
return false;
}
}
}
for (Type toBound : toLowerBounds) {
// if there are assignments for unresolved type variables,
// now's the time to substitute them.
toBound = substituteTypeVariables(toBound, typeVarAssigns);
// lower bound of the subject type
for (final Type bound : lowerBounds) {
if (!isAssignable(toBound, bound, typeVarAssigns)) {
return false;
}
}
}
return true;
}
for (final Type toBound : toUpperBounds) {
// now's the time to substitute them.
if (!isAssignable(type, substituteTypeVariables(toBound, typeVarAssigns), typeVarAssigns)) {
return false;
}
}
for (final Type toBound : toLowerBounds) {
// now's the time to substitute them.
if (!isAssignable(substituteTypeVariables(toBound, typeVarAssigns), type, typeVarAssigns)) {
return false;
}
}
return true;
}
Aggregations