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:
Stephane Nicoll
2019-04-04 15:55:55 +02:00
parent 8a04e2cc86
commit fbb5ffe0a4
4 changed files with 112 additions and 4 deletions

View File

@@ -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