[J2KT] Detect recursion at TypeVariables only (this is consistent with how it's done in AST).
@@ -65,8 +65,8 @@ private data class TypeDescriptorRenderer(
/** The underlying renderer. */
val renderer: Renderer,
- /** Set of seen type descriptors used to detect recursion. */
- val seenTypeDescriptors: Set<TypeDescriptor> = setOf(),
+ /** Set of seen type variables used to detect recursion. */
+ val seenTypeVariables: Set<TypeVariable> = setOf(),
// TODO(b/246842682): Remove when bridge types are materialized as TypeDescriptors
/** Whether to render a super-type, using bridge name if present. */
@@ -80,7 +80,6 @@ private data class TypeDescriptorRenderer(
get() = copy(asSuperType = false)
fun render(typeDescriptor: TypeDescriptor) {
- withSeen(typeDescriptor).run {
when (typeDescriptor) {
is ArrayTypeDescriptor -> renderArray(typeDescriptor)
is DeclaredTypeDescriptor -> renderDeclared(typeDescriptor)
@@ -90,7 +89,6 @@ private data class TypeDescriptorRenderer(
else -> throw InternalCompilerError("Unexpected ${typeDescriptor::class.java.simpleName}")
}
}
- }
fun renderArray(arrayTypeDescriptor: ArrayTypeDescriptor) {
renderer.renderQualifiedName(arrayTypeDescriptor)
@@ -131,6 +129,10 @@ private data class TypeDescriptorRenderer(
}
fun renderVariable(typeVariable: TypeVariable) {
+ if (didSee(typeVariable)) {
+ renderer.render("*")
+ } else {
+ withSeen(typeVariable).run {
if (typeVariable.isWildcardOrCapture) {
val lowerBoundTypeDescriptor = typeVariable.lowerBoundTypeDescriptor
if (lowerBoundTypeDescriptor != null) {
@@ -138,8 +140,7 @@ private data class TypeDescriptorRenderer(
child.render(lowerBoundTypeDescriptor)
} else {
val boundTypeDescriptor = typeVariable.upperBoundTypeDescriptor
- val isRecursive = didSee(boundTypeDescriptor)
- if (isRecursive || boundTypeDescriptor.isImplicitUpperBound) {
+ if (boundTypeDescriptor.isImplicitUpperBound) {
renderer.render("*")
} else {
renderer.render("out ")
@@ -151,6 +152,8 @@ private data class TypeDescriptorRenderer(
renderNullableSuffix(typeVariable)
}
}
+ }
+ }
fun renderIntersection(typeDescriptor: IntersectionTypeDescriptor) {
renderer.renderSeparatedWith(typeDescriptor.intersectionTypeDescriptors, " & ") {
@@ -162,9 +165,9 @@ private data class TypeDescriptorRenderer(
if (typeDescriptor.isNullable) renderer.render("?")
}
- private fun withSeen(typeDescriptor: TypeDescriptor) =
- copy(seenTypeDescriptors = seenTypeDescriptors + typeDescriptor.toNonNullable())
+ private fun withSeen(typeVariable: TypeVariable) =
+ copy(seenTypeVariables = seenTypeVariables + typeVariable.toNonNullable())
- private fun didSee(typeDescriptor: TypeDescriptor) =
- seenTypeDescriptors.contains(typeDescriptor.toNonNullable())
+ private fun didSee(typeVariable: TypeVariable) =
+ seenTypeVariables.contains(typeVariable.toNonNullable())
}
