JVM/JVM_IR: fix mapping of KClass in annotation classes
* JVM incorrectly mapped T<KClass<...>> to T<Class<...>> because the annotation-ness of the type mapping mode was inherited one level down into a generic signature independent of T * JVM_IR was even worse as it did not use VALUE_FOR_ANNOTATION at all, mapping T<T<KClass<...>> to T<T<Class<...>> as well. The correct behavior is to map KClass to Class only at top level or as an argument of Array.
This commit is contained in:
+1
-1
@@ -137,7 +137,7 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
|
|||||||
arrayElementType = AsmTypes.OBJECT_TYPE
|
arrayElementType = AsmTypes.OBJECT_TYPE
|
||||||
sw?.writeClass(arrayElementType)
|
sw?.writeClass(arrayElementType)
|
||||||
} else {
|
} else {
|
||||||
arrayElementType = mapType(memberType, mode.toGenericArgumentMode(variance), sw)
|
arrayElementType = mapType(memberType, mode.toGenericArgumentMode(variance, ofArray = true), sw)
|
||||||
}
|
}
|
||||||
sw?.writeArrayEnd()
|
sw?.writeArrayEnd()
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
annotation class Ann(val arg: Array<out KClass<out KClass<*>>>)
|
annotation class Ann(val arg: Array<out KClass<out KClass<*>>>)
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
annotation class Ann(val arg: KClass<out KClass<*>>)
|
||||||
|
|
||||||
|
// method: Ann::arg
|
||||||
|
// jvm signature: ()Ljava/lang/Class;
|
||||||
|
// generic signature: ()Ljava/lang/Class<+Lkotlin/reflect/KClass<*>;>;
|
||||||
+5
@@ -170,6 +170,11 @@ public class IrWriteSignatureTestGenerated extends AbstractIrWriteSignatureTest
|
|||||||
public void testKClassInt() throws Exception {
|
public void testKClassInt() throws Exception {
|
||||||
runTest("compiler/testData/writeSignature/annotations/kClassInt.kt");
|
runTest("compiler/testData/writeSignature/annotations/kClassInt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kClassOfKClass.kt")
|
||||||
|
public void testKClassOfKClass() throws Exception {
|
||||||
|
runTest("compiler/testData/writeSignature/annotations/kClassOfKClass.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/writeSignature/callableReference")
|
@TestMetadata("compiler/testData/writeSignature/callableReference")
|
||||||
|
|||||||
+5
@@ -169,6 +169,11 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest {
|
|||||||
public void testKClassInt() throws Exception {
|
public void testKClassInt() throws Exception {
|
||||||
runTest("compiler/testData/writeSignature/annotations/kClassInt.kt");
|
runTest("compiler/testData/writeSignature/annotations/kClassInt.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kClassOfKClass.kt")
|
||||||
|
public void testKClassOfKClass() throws Exception {
|
||||||
|
runTest("compiler/testData/writeSignature/annotations/kClassOfKClass.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/writeSignature/callableReference")
|
@TestMetadata("compiler/testData/writeSignature/callableReference")
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class TypeMappingMode private constructor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kotlin.reflect.KClass mapped to java.lang.Class
|
* kotlin.reflect.KClass mapped to java.lang.Class when at top level or in an array;
|
||||||
* primitive types and inline class types are not boxed because types in annotations cannot be nullable
|
* primitive types and inline class types are not boxed because types in annotations cannot be nullable
|
||||||
* Other types mapped as DEFAULT
|
* Other types mapped as DEFAULT
|
||||||
*/
|
*/
|
||||||
@@ -77,7 +77,7 @@ class TypeMappingMode private constructor(
|
|||||||
isForAnnotationParameter = true,
|
isForAnnotationParameter = true,
|
||||||
needPrimitiveBoxing = false,
|
needPrimitiveBoxing = false,
|
||||||
needInlineClassWrapping = false,
|
needInlineClassWrapping = false,
|
||||||
genericArgumentMode = TypeMappingMode(isForAnnotationParameter = true, genericArgumentMode = GENERIC_ARGUMENT)
|
genericArgumentMode = GENERIC_ARGUMENT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -89,48 +89,37 @@ class TypeMappingMode private constructor(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getOptimalModeForValueParameter(
|
fun getOptimalModeForValueParameter(
|
||||||
type: KotlinType
|
type: KotlinType
|
||||||
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = false, canBeUsedInSupertypePosition = true)
|
) = getOptimalModeForSignaturePart(type, canBeUsedInSupertypePosition = true)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getOptimalModeForReturnType(
|
fun getOptimalModeForReturnType(
|
||||||
type: KotlinType,
|
type: KotlinType,
|
||||||
isAnnotationMethod: Boolean
|
isAnnotationMethod: Boolean
|
||||||
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = isAnnotationMethod, canBeUsedInSupertypePosition = false)
|
) = if (isAnnotationMethod) VALUE_FOR_ANNOTATION else getOptimalModeForSignaturePart(type, canBeUsedInSupertypePosition = false)
|
||||||
|
|
||||||
private fun getOptimalModeForSignaturePart(
|
private fun getOptimalModeForSignaturePart(type: KotlinType, canBeUsedInSupertypePosition: Boolean): TypeMappingMode {
|
||||||
type: KotlinType,
|
|
||||||
isForAnnotationParameter: Boolean,
|
|
||||||
canBeUsedInSupertypePosition: Boolean
|
|
||||||
): TypeMappingMode {
|
|
||||||
if (type.arguments.isEmpty()) return DEFAULT
|
if (type.arguments.isEmpty()) return DEFAULT
|
||||||
|
|
||||||
if (type.isInlineClassType() && shouldUseUnderlyingType(type)) {
|
if (type.isInlineClassType() && shouldUseUnderlyingType(type)) {
|
||||||
val underlyingType = computeUnderlyingType(type)
|
val underlyingType = computeUnderlyingType(type)
|
||||||
if (underlyingType != null) {
|
if (underlyingType != null) {
|
||||||
return getOptimalModeForSignaturePart(
|
return getOptimalModeForSignaturePart(underlyingType, canBeUsedInSupertypePosition).dontWrapInlineClassesMode()
|
||||||
underlyingType, isForAnnotationParameter, canBeUsedInSupertypePosition
|
|
||||||
).dontWrapInlineClassesMode()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val contravariantArgumentMode =
|
val contravariantArgumentMode =
|
||||||
if (!canBeUsedInSupertypePosition)
|
if (!canBeUsedInSupertypePosition)
|
||||||
TypeMappingMode(
|
TypeMappingMode(skipDeclarationSiteWildcards = false, skipDeclarationSiteWildcardsIfPossible = true)
|
||||||
isForAnnotationParameter = isForAnnotationParameter,
|
|
||||||
skipDeclarationSiteWildcards = false,
|
|
||||||
skipDeclarationSiteWildcardsIfPossible = true
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
val invariantArgumentMode =
|
val invariantArgumentMode =
|
||||||
if (canBeUsedInSupertypePosition)
|
if (canBeUsedInSupertypePosition)
|
||||||
getOptimalModeForSignaturePart(type, isForAnnotationParameter, canBeUsedInSupertypePosition = false)
|
getOptimalModeForSignaturePart(type, canBeUsedInSupertypePosition = false)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
return TypeMappingMode(
|
return TypeMappingMode(
|
||||||
isForAnnotationParameter = isForAnnotationParameter,
|
|
||||||
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
|
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
|
||||||
skipDeclarationSiteWildcardsIfPossible = true,
|
skipDeclarationSiteWildcardsIfPossible = true,
|
||||||
genericContravariantArgumentMode = contravariantArgumentMode,
|
genericContravariantArgumentMode = contravariantArgumentMode,
|
||||||
@@ -153,8 +142,8 @@ class TypeMappingMode private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toGenericArgumentMode(effectiveVariance: Variance): TypeMappingMode =
|
fun toGenericArgumentMode(effectiveVariance: Variance, ofArray: Boolean = false): TypeMappingMode =
|
||||||
when (effectiveVariance) {
|
if (ofArray && isForAnnotationParameter) this else when (effectiveVariance) {
|
||||||
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
|
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
|
||||||
Variance.INVARIANT -> genericInvariantArgumentMode ?: this
|
Variance.INVARIANT -> genericInvariantArgumentMode ?: this
|
||||||
else -> genericArgumentMode ?: this
|
else -> genericArgumentMode ?: this
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ fun <T : Any> mapType(
|
|||||||
descriptorTypeWriter?.writeArrayType()
|
descriptorTypeWriter?.writeArrayType()
|
||||||
|
|
||||||
arrayElementType = mapType(
|
arrayElementType = mapType(
|
||||||
memberType, factory, mode.toGenericArgumentMode(memberProjection.projectionKind), typeMappingConfiguration,
|
memberType, factory, mode.toGenericArgumentMode(memberProjection.projectionKind, ofArray = true),
|
||||||
descriptorTypeWriter, writeGenericType
|
typeMappingConfiguration, descriptorTypeWriter, writeGenericType
|
||||||
)
|
)
|
||||||
|
|
||||||
descriptorTypeWriter?.writeArrayEnd()
|
descriptorTypeWriter?.writeArrayEnd()
|
||||||
|
|||||||
Reference in New Issue
Block a user