[FIR] Add pretty rendering of functional types

This commit is contained in:
Dmitriy Novozhilov
2019-11-07 18:19:01 +03:00
parent 18dc652404
commit e910653d6f
66 changed files with 201 additions and 143 deletions
@@ -5,6 +5,10 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun ConeKotlinType.render(): String {
val nullabilitySuffix = if (this !is ConeKotlinErrorType && this !is ConeClassErrorType) nullability.suffix else ""
return when (this) {
@@ -17,12 +21,7 @@ fun ConeKotlinType.render(): String {
append(lookupTag.classId.asString())
if (typeArguments.isNotEmpty()) {
append(typeArguments.joinToString(prefix = "<", postfix = ">") {
when (it) {
ConeStarProjection -> "*"
is ConeKotlinTypeProjectionIn -> "in ${it.type.render()}"
is ConeKotlinTypeProjectionOut -> "out ${it.type.render()}"
is ConeKotlinType -> it.render()
}
it.render()
})
}
}
@@ -49,3 +48,43 @@ fun ConeKotlinType.render(): String {
is ConeStubType -> "stub type: $variable"
} + nullabilitySuffix
}
private fun ConeKotlinTypeProjection.render(): String {
return when (this) {
ConeStarProjection -> "*"
is ConeKotlinTypeProjectionIn -> "in ${type.render()}"
is ConeKotlinTypeProjectionOut -> "out ${type.render()}"
is ConeKotlinType -> render()
}
}
fun ConeKotlinType.renderFunctionType(kind: FunctionClassDescriptor.Kind?, isExtension: Boolean): String {
if (!kind.withPrettyRender()) return render()
return buildString {
if (kind == FunctionClassDescriptor.Kind.SuspendFunction) {
append("suspend ")
}
val (receiver, otherTypeArguments) = if (isExtension && typeArguments.first() != ConeStarProjection) {
typeArguments.first() to typeArguments.drop(1)
} else {
null to typeArguments.toList()
}
val arguments = otherTypeArguments.subList(0, otherTypeArguments.size - 1)
val returnType = otherTypeArguments.last()
if (receiver != null) {
append(receiver.render())
append(".")
}
append(arguments.joinToString(", ", "(", ")") { it.render() })
append(" -> ")
append(returnType.render())
}
}
@UseExperimental(ExperimentalContracts::class)
fun FunctionClassDescriptor.Kind?.withPrettyRender(): Boolean {
contract {
returns(true) implies (this@withPrettyRender != null)
}
return this != null && this != FunctionClassDescriptor.Kind.KSuspendFunction && this != FunctionClassDescriptor.Kind.KFunction
}