Inline classes. Use inline class instead of underlying type

in annotations if underlying type is not nullable reference type.
Previously, it worked only for inline classes with primitive
underlying type and nullable reference type.

 #KT-44133
This commit is contained in:
Ilmir Usmanov
2021-09-20 23:25:18 +02:00
committed by Space
parent 80fbc262b3
commit e74e267d16
3 changed files with 45 additions and 15 deletions
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
import org.jetbrains.kotlin.backend.jvm.ir.isWithFlexibleNullability
import org.jetbrains.kotlin.builtins.StandardNames
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.FqName
@@ -275,12 +277,12 @@ abstract class AnnotationCodegen(
visitor.visitEnd()
}
is IrClassReference -> {
var classType = value.classType
val classType = value.classType
classType.classOrNull?.owner?.let(innerClassConsumer::addInnerClassInfoFromAnnotation)
if (classType.isInlineClassType()) {
classType = classType.makeNullable()
}
annotationVisitor.visit(name, typeMapper.mapType(classType))
val mappedType =
if (classType.isInlineClassType()) typeMapper.mapClass(classType.erasedUpperBound)
else typeMapper.mapType(classType)
annotationVisitor.visit(name, mappedType)
}
is IrErrorExpression -> error("Don't know how to compile annotation value ${ir2string(value)}")
else -> error("Unsupported compile-time value ${ir2string(value)}")
@@ -1,17 +1,45 @@
// WITH_REFLECT
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
package test
import kotlin.reflect.KClass
inline class IC(val i: Int)
@JvmInline
value class ICInt(val i: Int)
@JvmInline
value class ICIntN(val i: Int?)
@JvmInline
value class ICAny(val a: Any)
annotation class Ann(val c: KClass<*>)
@Ann(IC::class)
class C
@Ann(ICInt::class)
class CInt
@Ann(ICIntN::class)
class CIntN
@Ann(ICAny::class)
class CAny
@Ann(Result::class)
class CResult
fun box(): String {
val klass = (C::class.annotations.first() as Ann).c.toString()
return if (klass == "class test.IC") "OK" else klass
var klass = (CInt::class.annotations.first() as Ann).c.toString()
if (klass != "class test.ICInt") return "Expected class test.ICInt, got $klass"
klass = (CIntN::class.annotations.first() as Ann).c.toString()
if (klass != "class test.ICIntN") return "Expected class test.ICIntN, got $klass"
klass = (CAny::class.annotations.first() as Ann).c.toString()
if (klass != "class test.ICAny") return "Expected class test.ICAny, got $klass"
klass = (CResult::class.annotations.first() as Ann).c.toString()
if (klass != "class kotlin.Result") return "Expected class kotlin.Result, got $klass"
return "OK"
}
@@ -15174,6 +15174,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassWithCustomEquals.kt");
}
@TestMetadata("kclassInAnnotation.kt")
public void ignoreKclassInAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/kclassInAnnotation.kt");
}
@TestMetadata("kt31994.kt")
public void ignoreKt31994() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/kt31994.kt");
@@ -15702,11 +15707,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/jvmStaticVarInInlineClassCompanion.kt");
}
@TestMetadata("kclassInAnnotation.kt")
public void testKclassInAnnotation() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/kclassInAnnotation.kt");
}
@TestMetadata("kt25246.kt")
public void testKt25246() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/kt25246.kt");