Created
December 13, 2019 09:16
-
-
Save FroMage/95510ae3dc8c388bf90d1245ee3abdd6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private List<org.jboss.jandex.Type> findArgumentsToSuperType(DotName currentClass, List<org.jboss.jandex.Type> args, | |
DotName soughtSuperType) { | |
// stop if we didn't find it | |
if (currentClass.equals(OBJECT_DOT_NAME)) { | |
return null; | |
} | |
final ClassInfo classByName = indexView.getClassByName(currentClass); | |
// build a map of this classe's type params to their arguments | |
Map<TypeVariable, org.jboss.jandex.Type> typeArgs = new HashMap<>(); | |
List<TypeVariable> typeParameters = classByName.typeParameters(); | |
for (int i = 0; i < typeParameters.size(); i++) { | |
TypeVariable typeVariable = typeParameters.get(i); | |
// default to first bound instead? | |
org.jboss.jandex.Type arg; | |
if (i < args.size()) | |
arg = args.get(i); | |
else | |
arg = typeVariable; | |
typeArgs.put(typeVariable, arg); | |
} | |
// look at the interfaces for a direct implementation | |
for (org.jboss.jandex.Type type : classByName.interfaceTypes()) { | |
if (type.name().equals(soughtSuperType)) { | |
// found the type args | |
return substitute(type.asParameterizedType().arguments(), typeArgs); | |
} | |
// look at super-interfaces | |
// FIXME: add cache to avoid visiting the same interface more than once | |
List<org.jboss.jandex.Type> superArgs = findSuperArgs(type, typeArgs); | |
List<org.jboss.jandex.Type> ret = findArgumentsToSuperType(type.name(), superArgs, soughtSuperType); | |
if(ret != null) | |
return ret; | |
} | |
// look at super-type | |
List<org.jboss.jandex.Type> superArgs = findSuperArgs(classByName.superClassType(), typeArgs); | |
return findArgumentsToSuperType(classByName.superName(), superArgs, soughtSuperType); | |
} | |
private List<org.jboss.jandex.Type> findSuperArgs(org.jboss.jandex.Type superClassType, | |
Map<TypeVariable, org.jboss.jandex.Type> typeArgs) { | |
switch (superClassType.kind()) { | |
case CLASS: | |
return Collections.emptyList(); | |
case PARAMETERIZED_TYPE: | |
return substitute(superClassType.asParameterizedType().arguments(), typeArgs); | |
default: | |
throw new RuntimeException("Invalid supertype kind: " + superClassType); | |
} | |
} | |
private List<org.jboss.jandex.Type> substitute(List<org.jboss.jandex.Type> types, | |
Map<TypeVariable, org.jboss.jandex.Type> typeArgs){ | |
List<org.jboss.jandex.Type> substitutedArgs = new ArrayList<>(types); | |
for (int i = 0; i < substitutedArgs.size(); i++) { | |
substitutedArgs.set(i, substitute(substitutedArgs.get(i), typeArgs)); | |
} | |
return substitutedArgs; | |
} | |
private org.jboss.jandex.Type substitute(org.jboss.jandex.Type type, | |
Map<TypeVariable, org.jboss.jandex.Type> typeArgs) { | |
switch (type.kind()) { | |
case ARRAY: | |
ArrayType arrayType = type.asArrayType(); | |
org.jboss.jandex.Type substitutedComponent = substitute(arrayType.component(), typeArgs); | |
return ArrayType.create(substitutedComponent, arrayType.dimensions()); | |
case TYPE_VARIABLE: | |
org.jboss.jandex.Type substitutedArgument = typeArgs.get(type.asTypeVariable()); | |
return substitutedArgument != null ? substitutedArgument : type; | |
case VOID: | |
case PRIMITIVE: | |
case CLASS: | |
return type; | |
case PARAMETERIZED_TYPE: | |
ParameterizedType parameterizedType = type.asParameterizedType(); | |
org.jboss.jandex.Type substitutedOwner = parameterizedType.owner() != null | |
? substitute(parameterizedType.owner(), typeArgs) | |
: null; | |
List<org.jboss.jandex.Type> arguments = parameterizedType.arguments(); | |
org.jboss.jandex.Type[] substitutedArguments = new org.jboss.jandex.Type[arguments.size()]; | |
for (int i = 0; i < arguments.size(); i++) { | |
org.jboss.jandex.Type argument = arguments.get(i); | |
substitutedArguments[i] = substitute(argument, typeArgs); | |
} | |
return ParameterizedType.create(parameterizedType.name(), substitutedArguments, substitutedOwner); | |
case UNRESOLVED_TYPE_VARIABLE: | |
return type; | |
case WILDCARD_TYPE: | |
WildcardType wildcardType = type.asWildcardType(); | |
org.jboss.jandex.Type superBound = wildcardType.superBound(); | |
// do erasure to bounds | |
if (superBound != null) | |
return substitute(superBound, typeArgs); | |
return substitute(wildcardType.extendsBound(), typeArgs); | |
default: | |
throw new RuntimeException("Invalid supertype kind: " + type); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment