Avoid infinite cycle resolving generic type that refers itself
This commit improves type resolution for a unresolved generic type that uses itself in its upper bound declaration. Closes gh-16451
This commit is contained in:
@@ -248,15 +248,28 @@ class TypeUtils {
|
||||
TypeMirror typeMirror = descriptor.resolveGeneric(t);
|
||||
if (typeMirror != null) {
|
||||
if (typeMirror instanceof TypeVariable) {
|
||||
// Still unresolved, let's use upper bound
|
||||
return visit(((TypeVariable) typeMirror).getUpperBound(), descriptor);
|
||||
TypeVariable typeVariable = (TypeVariable) typeMirror;
|
||||
// Still unresolved, let's use the upper bound, checking first if
|
||||
// a cycle may exist
|
||||
if (!hasCycle(typeVariable)) {
|
||||
return visit(typeVariable.getUpperBound(), descriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return visit(typeMirror, descriptor);
|
||||
}
|
||||
}
|
||||
// Unresolved generics, use upper bound
|
||||
return visit(t.getUpperBound(), descriptor);
|
||||
// Fallback to simple representation of the upper bound
|
||||
return defaultAction(t.getUpperBound(), descriptor);
|
||||
}
|
||||
|
||||
private boolean hasCycle(TypeVariable variable) {
|
||||
TypeMirror upperBound = variable.getUpperBound();
|
||||
if (upperBound instanceof DeclaredType) {
|
||||
return ((DeclaredType) upperBound).getTypeArguments().stream()
|
||||
.anyMatch((candidate) -> candidate.equals(variable));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user