FIR IDE: render KtFunctionalType in KtTypeRenderer

This commit is contained in:
Ilya Kirillov
2021-02-02 21:13:34 +01:00
parent a10f54befa
commit b114a45f23
2 changed files with 126 additions and 7 deletions
@@ -16,10 +16,16 @@ abstract class KtTypeRenderer : KtAnalysisSessionComponent() {
data class KtTypeRendererOptions(
val renderFqNames: Boolean,
val renderFunctionTypes: Boolean
) {
companion object {
val DEFAULT = KtTypeRendererOptions(
renderFqNames = true
renderFqNames = true,
renderFunctionTypes = true,
)
val SHORT_NAMES = KtTypeRendererOptions(
renderFqNames = false,
renderFunctionTypes = true,
)
}
}
@@ -33,9 +39,7 @@ class KtDefaultTypeRenderer(override val analysisSession: KtAnalysisSession, ove
when (type) {
is KtDenotableType -> when (type) {
is KtClassType -> {
render(type.classId, options)
renderTypeArgumentsIfNotEmpty(type.typeArguments, options)
renderNullability(type.nullability)
renderClassType(type, options)
}
is KtTypeParameterType -> {
append(type.name.asString())
@@ -64,6 +68,67 @@ class KtDefaultTypeRenderer(override val analysisSession: KtAnalysisSession, ove
}
}
private fun StringBuilder.renderClassType(
type: KtClassType,
options: KtTypeRendererOptions
) {
when {
type is KtUsualClassType || !options.renderFunctionTypes -> {
renderClassTypeAsNonFunctional(type, options)
}
type is KtFunctionalType -> {
renderFunctionalType(type, options)
}
}
}
private fun StringBuilder.renderClassTypeAsNonFunctional(
type: KtClassType,
options: KtTypeRendererOptions
) {
render(type.classId, options)
renderTypeArgumentsIfNotEmpty(type.typeArguments, options)
renderNullability(type.nullability)
}
private fun StringBuilder.renderFunctionalType(
type: KtFunctionalType,
options: KtTypeRendererOptions
) {
wrapIf(type.nullability == KtTypeNullability.NULLABLE, left = "(", right = ")?") {
if (type.isSuspend) append("suspend ")
renderReceiverTypeOfFunctionalType(type, options)
renderParametersOfFunctionalType(type, options)
append(" -> ")
render(type.typeArguments.last(), options)
}
}
private fun StringBuilder.renderReceiverTypeOfFunctionalType(
type: KtFunctionalType,
options: KtTypeRendererOptions
) {
type.receiverType?.let { receiverType ->
render(receiverType, options)
append(".")
}
}
private fun StringBuilder.renderParametersOfFunctionalType(
type: KtFunctionalType,
options: KtTypeRendererOptions
) {
append("(")
val parameterTypes = type.parameterTypes
type.parameterTypes.forEachIndexed { index, parameterType ->
render(parameterType, options)
if (index != parameterTypes.lastIndex) {
append(", ")
}
}
append(")")
}
private fun StringBuilder.renderTypeArgumentsIfNotEmpty(typeArguments: List<KtTypeArgument>, options: KtTypeRendererOptions) {
if (typeArguments.isNotEmpty()) {
append("<")
@@ -113,4 +178,10 @@ class KtDefaultTypeRenderer(override val analysisSession: KtAnalysisSession, ove
render()
append(")")
}
private inline fun StringBuilder.wrapIf(condition: Boolean, left: String, right: String, render: StringBuilder.() -> Unit) {
if (condition) append(left)
render()
if (condition) append(right)
}
}