diff --git a/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.fir.txt b/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.fir.txt new file mode 100644 index 00000000000..e1264ed94d1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.fir.txt @@ -0,0 +1,4 @@ +FILE: main.kt + public final fun foo(p: R|AAA|, s: R|kotlin/Int?|): R|kotlin/Unit| { + R|/p|.R|SubstitutionOverride#|<>(R|/s|) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.kt b/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.kt index e43e6d5e4be..0e2baf37e7a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.kt +++ b/compiler/fir/analysis-tests/testData/resolve/flexibleTypeRendering.kt @@ -1,7 +1,7 @@ // FILE: main.kt fun foo(p: AAA, s: Int?) { - p.process(; kotlin.Int?")!>s) + p.process(s) } // FILE: AAA.java diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForReadability.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForReadability.kt index 0c1422e20f1..07af17602d0 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForReadability.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForReadability.kt @@ -6,11 +6,13 @@ package org.jetbrains.kotlin.fir.renderer import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.fir.types.ConeDefinitelyNotNullType import org.jetbrains.kotlin.fir.types.ConeFlexibleType import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.renderer.replacePrefixesInTypeRepresentations import org.jetbrains.kotlin.renderer.typeStringsDifferOnlyInNullability +import org.jetbrains.kotlin.utils.addToStdlib.applyIf class ConeTypeRendererForReadability( private val idRendererCreator: () -> ConeIdRenderer, @@ -22,14 +24,30 @@ class ConeTypeRendererForReadability( } override fun render(flexibleType: ConeFlexibleType) { - val lowerRenderer = ConeTypeRendererForReadability(StringBuilder(), idRendererCreator) - lowerRenderer.render(flexibleType.lowerBound) - val upperRenderer = ConeTypeRendererForReadability(StringBuilder(), idRendererCreator) - upperRenderer.render(flexibleType.upperBound) - builder.append(renderFlexibleType(lowerRenderer.builder.toString(), upperRenderer.builder.toString())) + val lower = flexibleType.lowerBound + + val lowerRendered = renderBound(lower) + val upperRendered = renderBound(flexibleType.upperBound) + + val rendered = + renderFlexibleTypeCompact(lowerRendered, upperRendered) + ?: run { + if (lower is ConeDefinitelyNotNullType) { + renderFlexibleTypeCompact(renderBound(lower.original), upperRendered) + } else null + } + ?: "ft<$lowerRendered, $upperRendered>" + + builder.append(rendered) } - private fun renderFlexibleType(lowerRendered: String, upperRendered: String): String { + private fun renderBound(bound: ConeKotlinType): String { + val renderer = ConeTypeRendererForReadability(StringBuilder(), idRendererCreator) + renderer.render(bound) + return renderer.builder.toString() + } + + private fun renderFlexibleTypeCompact(lowerRendered: String, upperRendered: String): String? { if (typeStringsDifferOnlyInNullability(lowerRendered, upperRendered)) { if (upperRendered.startsWith("(")) { // the case of complex type, e.g. (() -> Unit)? @@ -69,8 +87,7 @@ class ConeTypeRendererForReadability( foldedPrefix = kotlinPrefix + "Array<(out) " ) if (array != null) return array - - return "ft<$lowerRendered, $upperRendered>" + return null } override fun render(type: ConeIntegerLiteralType) {