@Override public List<Type> extraInterfaces() { Type type = extractActualBoundedTypeOf(typeVariable); if (type instanceof BoundedType) { return Arrays.asList(((BoundedType) type).interfaceBounds()); } if (type instanceof ParameterizedType) { return Collections.singletonList(type); } if (type instanceof Class) { return Collections.emptyList(); } throw new MockitoException("Cannot extract extra-interfaces from '" + typeVariable + "' : '" + type + "'"); }
protected Class<?> extractRawTypeOf(Type type) { if (type instanceof Class) { return (Class<?>) type; } if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); } if (type instanceof BoundedType) { return extractRawTypeOf(((BoundedType) type).firstBound()); } if (type instanceof TypeVariable) { /* * If type is a TypeVariable, then it is needed to gather data elsewhere. Usually TypeVariables are declared * on the class definition, such as such as List<E>. */ return extractRawTypeOf(contextualActualTypeParameters.get(type)); } throw new MockitoException("Raw extraction not supported for : '" + type + "'"); }
private Type extractActualBoundedTypeOf(Type type) { if (type instanceof TypeVariable) { /* If type is a TypeVariable, then it is needed to gather data elsewhere. Usually TypeVariables are declared on the class definition, such as such as List<E>. */ return extractActualBoundedTypeOf(contextualActualTypeParameters.get(type)); } if (type instanceof BoundedType) { Type actualFirstBound = extractActualBoundedTypeOf(((BoundedType) type).firstBound()); if (!(actualFirstBound instanceof BoundedType)) { return type; // avoid going one step further, ie avoid : O(TypeVar) -> K(TypeVar) -> Some ParamType } return actualFirstBound; } return type; // irrelevant, we don't manage other types as they are not bounded. } }