[AA] Render reflection functional types as class types.

Render KFunctionN and KSuspendFunctionN by their class names, rather
than using arrow syntax. These types have additional functionality
beyond purely being able to invoke them (e.g. getting the name of the
referred function), so using arrow syntax throws away that functionality
and may cause breakages in the resulting code.
This commit is contained in:
Justin Paupore
2023-01-11 15:36:45 -08:00
committed by Ilya Kirillov
parent cd61f545a8
commit 16f14a21e2
7 changed files with 18 additions and 3 deletions
@@ -53,6 +53,9 @@ internal class KtFe10FunctionalType(
override val isSuspend: Boolean
get() = withValidityAssertion { descriptor.functionKind.isSuspendType }
override val isReflectType: Boolean
get() = withValidityAssertion { descriptor.functionKind.isReflectType }
override val arity: Int
get() = withValidityAssertion { descriptor.arity }
@@ -50,6 +50,9 @@ internal class KtFirFunctionalType(
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val isSuspend: Boolean get() = withValidityAssertion { coneType.isSuspendOrKSuspendFunctionType(builder.rootSession) }
override val isReflectType: Boolean get() = withValidityAssertion { coneType.isKFunctionType(builder.rootSession) }
override val arity: Int
get() = withValidityAssertion {
if (coneType.isExtensionFunctionType) coneType.typeArguments.size - 2
@@ -18,7 +18,7 @@ public object KtTypeRendererForSource {
definitelyNotNullTypeRenderer = KtDefinitelyNotNullTypeRenderer.AS_TYPE_INTERSECTION
dynamicTypeRenderer = KtDynamicTypeRenderer.AS_DYNAMIC_WORD
flexibleTypeRenderer = KtFlexibleTypeRenderer.AS_SHORT
functionalTypeRenderer = KtFunctionalTypeRenderer.AS_FUNCTIONAL_TYPE
functionalTypeRenderer = KtFunctionalTypeRenderer.AS_CLASS_TYPE_FOR_REFLECTION_TYPES
integerLiteralTypeRenderer = KtIntegerLiteralTypeRenderer.AS_ILT_WITH_VALUE
intersectionTypeRenderer = KtIntersectionTypeRenderer.AS_INTERSECTION
typeErrorTypeRenderer = KtTypeErrorTypeRenderer.AS_CODE_IF_POSSIBLE
@@ -63,4 +63,12 @@ public interface KtFunctionalTypeRenderer {
}
}
public object AS_CLASS_TYPE_FOR_REFLECTION_TYPES : KtFunctionalTypeRenderer {
context(KtAnalysisSession, KtTypeRenderer)
override fun renderType(type: KtFunctionalType, printer: PrettyPrinter): Unit {
val renderer = if (type.isReflectType) AS_CLASS_TYPE else AS_FUNCTIONAL_TYPE
renderer.renderType(type, printer)
}
}
}
@@ -55,6 +55,7 @@ public sealed class KtNonErrorClassType : KtClassType() {
public abstract class KtFunctionalType : KtNonErrorClassType(), KtContextReceiversOwner {
public abstract val isSuspend: Boolean
public abstract val isReflectType: Boolean
public abstract val arity: Int
public abstract val hasContextReceivers: Boolean
public abstract val receiverType: KtType?
@@ -1,3 +1,3 @@
expression: xy
expected type: (kotlin.Int) -> kotlin.String
expected type: kotlin.reflect.KFunction1<kotlin.Int, kotlin.String>
functionClassKind: KFunction
@@ -1,3 +1,3 @@
expression: xy
expected type: suspend () -> kotlin.Unit
expected type: kotlin.reflect.KSuspendFunction0<kotlin.Unit>
functionClassKind: KSuspendFunction