[FIR] Render k2-specific flexible types in a more compact way in diagnostic messages

^KT-62031 fixed
This commit is contained in:
Ilya Kirillov
2023-09-21 21:28:46 +02:00
committed by Space Team
parent e2252f5e6b
commit 252c59a8a3
3 changed files with 30 additions and 9 deletions
@@ -0,0 +1,4 @@
FILE: main.kt
public final fun foo(p: R|AAA<kotlin/String>|, s: R|kotlin/Int?|): R|kotlin/Unit| {
R|<local>/p|.R|SubstitutionOverride</AAA.process: R|kotlin/Unit|><Inapplicable(INAPPLICABLE): /AAA.process>#|<<ERROR TYPE REF: Cannot infer argument for type parameter Q>>(R|<local>/s|)
}
@@ -1,7 +1,7 @@
// FILE: main.kt // FILE: main.kt
fun foo(p: AAA<String>, s: Int?) { fun foo(p: AAA<String>, s: Int?) {
p.process(<!ARGUMENT_TYPE_MISMATCH("ft<Q & Any, Q?>; kotlin.Int?")!>s<!>) p.process(<!ARGUMENT_TYPE_MISMATCH("Q!; kotlin.Int?")!>s<!>)
} }
// FILE: AAA.java // FILE: AAA.java
@@ -6,11 +6,13 @@
package org.jetbrains.kotlin.fir.renderer package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.builtins.StandardNames 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.ConeFlexibleType
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.renderer.replacePrefixesInTypeRepresentations import org.jetbrains.kotlin.renderer.replacePrefixesInTypeRepresentations
import org.jetbrains.kotlin.renderer.typeStringsDifferOnlyInNullability import org.jetbrains.kotlin.renderer.typeStringsDifferOnlyInNullability
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
class ConeTypeRendererForReadability( class ConeTypeRendererForReadability(
private val idRendererCreator: () -> ConeIdRenderer, private val idRendererCreator: () -> ConeIdRenderer,
@@ -22,14 +24,30 @@ class ConeTypeRendererForReadability(
} }
override fun render(flexibleType: ConeFlexibleType) { override fun render(flexibleType: ConeFlexibleType) {
val lowerRenderer = ConeTypeRendererForReadability(StringBuilder(), idRendererCreator) val lower = flexibleType.lowerBound
lowerRenderer.render(flexibleType.lowerBound)
val upperRenderer = ConeTypeRendererForReadability(StringBuilder(), idRendererCreator) val lowerRendered = renderBound(lower)
upperRenderer.render(flexibleType.upperBound) val upperRendered = renderBound(flexibleType.upperBound)
builder.append(renderFlexibleType(lowerRenderer.builder.toString(), upperRenderer.builder.toString()))
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 (typeStringsDifferOnlyInNullability(lowerRendered, upperRendered)) {
if (upperRendered.startsWith("(")) { if (upperRendered.startsWith("(")) {
// the case of complex type, e.g. (() -> Unit)? // the case of complex type, e.g. (() -> Unit)?
@@ -69,8 +87,7 @@ class ConeTypeRendererForReadability(
foldedPrefix = kotlinPrefix + "Array<(out) " foldedPrefix = kotlinPrefix + "Array<(out) "
) )
if (array != null) return array if (array != null) return array
return null
return "ft<$lowerRendered, $upperRendered>"
} }
override fun render(type: ConeIntegerLiteralType) { override fun render(type: ConeIntegerLiteralType) {