org.hildan.generics.MentionedClassesExplorer Maven / Gradle / Ivy
Show all versions of generics-explorer Show documentation
package org.hildan.generics;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
public class MentionedClassesExplorer implements GenericTypeHandler>> {
/**
* Returns all classes/interfaces appearing in the given type declaration. This method recursively explores type
* parameters and array components to find the involved types.
*
* For instance, for the type {@code Map[]>}, we get [Map, Custom, List, Integer].
*
* @param type
* the type to explore
*
* @return a non-null set of all classes involved in the given type declaration
*/
@NotNull
public static Set> getClassesInDeclaration(@NotNull Type type) {
return GenericDeclarationExplorer.explore(type, new MentionedClassesExplorer());
}
@Override
public Set> handleVoid() {
return Collections.emptySet();
}
@Override
public Set> handleSimpleClass(@NotNull Class> clazz) {
return Collections.singleton(clazz);
}
@Override
public Set> handleEnumClass(@NotNull Class> clazz) {
return handleSimpleClass(clazz);
}
@Override
public Set> handleArrayClass(@NotNull Class> arrayClass, Set> handledComponentClass) {
return handledComponentClass;
}
@Override
public Set> handleGenericArray(@NotNull GenericArrayType type, Set> handledComponentClass) {
return handledComponentClass;
}
@Override
public Set> handleParameterizedType(@NotNull ParameterizedType type, Set> handledRawType,
@NotNull List>> handledTypeParameters) {
Set> result = new HashSet<>(handledRawType);
handledTypeParameters.forEach(result::addAll);
return result;
}
@Override
public Set> handleTypeVariable(@NotNull TypeVariable type, @NotNull List>> handledBounds) {
return handledBounds.stream().flatMap(Collection::stream).collect(Collectors.toSet());
}
@Override
public Set> handleWildcardType(@NotNull WildcardType type, @NotNull List>> handledUpperBounds,
@NotNull List>> handledLowerBounds) {
Stream>> upperBoundsStream = handledUpperBounds.stream();
Stream>> lowerBoundsStream = handledLowerBounds.stream();
return Stream.concat(upperBoundsStream, lowerBoundsStream)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
}