Use wrapper class of an inline one as a result for javaClass

#KT-28185 Fixed
 #KT-28246 Open
This commit is contained in:
Mikhail Zarechenskiy
2018-11-14 14:06:54 +03:00
parent 1a2579d8e8
commit 090d3327c0
5 changed files with 86 additions and 2 deletions
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.UNIT_TYPE
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.Type
@@ -42,13 +44,29 @@ object JavaClassProperty : IntrinsicPropertyGetter() {
}
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
fun invokeVirtualGetClassMethod() {
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
}
val type = receiver.type
val kotlinType = receiver.kotlinType
when {
type == Type.VOID_TYPE -> {
receiver.put(Type.VOID_TYPE, v)
StackValue.unit().put(UNIT_TYPE, v)
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
invokeVirtualGetClassMethod()
}
kotlinType?.isInlineClassType() == true -> {
receiver.put(type, kotlinType, v)
StackValue.coerce(
type, kotlinType,
AsmTypes.OBJECT_TYPE, kotlinType.constructor.builtIns.nullableAnyType,
v
)
invokeVirtualGetClassMethod()
}
isPrimitive(type) -> {
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
receiver.put(type, v)
@@ -56,9 +74,10 @@ object JavaClassProperty : IntrinsicPropertyGetter() {
}
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
}
else -> {
receiver.put(type, v)
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
invokeVirtualGetClassMethod()
}
}
@@ -0,0 +1,50 @@
// WITH_RUNTIME
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
package root
inline class IcInt(val x: Int)
inline class IcLong(val l: Long)
inline class IcAny(val a: Any?)
inline class IcOverIc(val o: IcLong)
fun check(c: Class<*>, s: String) {
if (c.toString() != s) error("Fail, expected: $s, actual: $c")
}
fun box(): String {
val i = IcInt(0)
val l = IcLong(0)
val a = IcAny("foo")
val o = IcOverIc(IcLong(0))
check(i.javaClass, "class root.IcInt")
check(l.javaClass, "class root.IcLong")
check(a.javaClass, "class root.IcAny")
check(o.javaClass, "class root.IcOverIc")
check(1u.javaClass, "class kotlin.UInt")
check(i::class.java, "class root.IcInt")
check(l::class.java, "class root.IcLong")
check(a::class.java, "class root.IcAny")
check(o::class.java, "class root.IcOverIc")
check(1u::class.java, "class kotlin.UInt")
val arrI = arrayOf(i)
check(arrI[0].javaClass, "class root.IcInt")
val arrL = arrayOf(l)
check(arrL[0].javaClass, "class root.IcLong")
val arrA = arrayOf(a)
check(arrA[0].javaClass, "class root.IcAny")
val arrO = arrayOf(o)
check(arrO[0].javaClass, "class root.IcOverIc")
val arrU = arrayOf(1u)
check(arrU[0].javaClass, "class kotlin.UInt")
return "OK"
}
@@ -11970,6 +11970,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
}
@TestMetadata("javaClassIntrinsicOnInlineClasses.kt")
public void testJavaClassIntrinsicOnInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/javaClassIntrinsicOnInlineClasses.kt");
}
@TestMetadata("jvmFieldInInlineClassCompanion.kt")
public void testJvmFieldInInlineClassCompanion() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvmFieldInInlineClassCompanion.kt");
@@ -11970,6 +11970,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
}
@TestMetadata("javaClassIntrinsicOnInlineClasses.kt")
public void testJavaClassIntrinsicOnInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/javaClassIntrinsicOnInlineClasses.kt");
}
@TestMetadata("jvmFieldInInlineClassCompanion.kt")
public void testJvmFieldInInlineClassCompanion() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvmFieldInInlineClassCompanion.kt");
@@ -11975,6 +11975,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
}
@TestMetadata("javaClassIntrinsicOnInlineClasses.kt")
public void testJavaClassIntrinsicOnInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/javaClassIntrinsicOnInlineClasses.kt");
}
@TestMetadata("jvmFieldInInlineClassCompanion.kt")
public void testJvmFieldInInlineClassCompanion() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvmFieldInInlineClassCompanion.kt");