FIR IDE: render KtFunctionalType in KtTypeRenderer
This commit is contained in:
+75
-4
@@ -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)
|
||||
}
|
||||
}
|
||||
+51
-3
@@ -83,7 +83,7 @@ class KtTypeRendererTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
type = "Map<List<Int?>, V?>?",
|
||||
expected = "Map<List<Int?>, V?>?",
|
||||
typeArguments = listOf("V"),
|
||||
rendererOptions = KtTypeRendererOptions(renderFqNames = false)
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,55 @@ class KtTypeRendererTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
doTestByExpression(
|
||||
expression = "java.lang.String.CASE_INSENSITIVE_ORDER",
|
||||
expected = "(Comparator<(String..String?)>..Comparator<(String..String?)>?)",
|
||||
rendererOptions = KtTypeRendererOptions(renderFqNames = false)
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testFunctionalType() {
|
||||
doTestByTypeText(
|
||||
type = "(String, Int?) -> Long",
|
||||
expected = "(String, Int?) -> Long",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testNullableFunctionalType() {
|
||||
doTestByTypeText(
|
||||
type = "((String, Int?) -> Long)?",
|
||||
expected = "((String, Int?) -> Long)?",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testFunctionalTypeNoArguments() {
|
||||
doTestByTypeText(
|
||||
type = "() -> Long",
|
||||
expected = "() -> Long",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testFunctionalTypeReceiver() {
|
||||
doTestByTypeText(
|
||||
type = "Int.(String) -> Long",
|
||||
expected = "Int.(String) -> Long",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testFunctionalTypeUnitReturnType() {
|
||||
doTestByTypeText(
|
||||
type = "(String) -> Unit",
|
||||
expected = "(String) -> Unit",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
|
||||
fun testFunctionalTypeRenderAsUsualClassType() {
|
||||
doTestByTypeText(
|
||||
type = "Int.(String, Long) -> Char",
|
||||
expected = "Function3<Int, String, Long, Char>",
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES.copy(renderFunctionTypes = false)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -103,7 +151,7 @@ class KtTypeRendererTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
if (x is String && x is Int) x else null
|
||||
}""".trimIndent(),
|
||||
expected = "(String?&Int?)",
|
||||
rendererOptions = KtTypeRendererOptions(renderFqNames = false)
|
||||
rendererOptions = KtTypeRendererOptions.SHORT_NAMES
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user