Fix unbound class literals for inline classes

#KT-28361 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2018-12-13 16:53:19 +03:00
parent 8f821c9ef5
commit c924a6efe8
6 changed files with 27 additions and 11 deletions
@@ -1217,8 +1217,16 @@ public class AsmUtil {
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName(); return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
} }
public static void putJavaLangClassInstance(@NotNull InstructionAdapter v, @NotNull Type type) { public static void putJavaLangClassInstance(
if (isPrimitive(type)) { @NotNull InstructionAdapter v,
@NotNull Type type,
@Nullable KotlinType kotlinType,
@NotNull GenerationState state
) {
if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
v.aconst(boxType(type, kotlinType, state));
}
else if (isPrimitive(type)) {
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;"); v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
} }
else { else {
@@ -402,7 +402,9 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
if (container instanceof ClassDescriptor) { if (container instanceof ClassDescriptor) {
// TODO: would it work for arrays? // TODO: would it work for arrays?
putJavaLangClassInstance(iv, state.getTypeMapper().mapClass((ClassDescriptor) container)); SimpleType containerKotlinType = ((ClassDescriptor) container).getDefaultType();
Type containerType = state.getTypeMapper().mapClass((ClassDescriptor) container);
putJavaLangClassInstance(iv, containerType, containerKotlinType, state);
} }
else if (container instanceof PackageFragmentDescriptor) { else if (container instanceof PackageFragmentDescriptor) {
iv.aconst(state.getTypeMapper().mapOwner(descriptor)); iv.aconst(state.getTypeMapper().mapOwner(descriptor));
@@ -3123,7 +3123,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS); putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
} }
putJavaLangClassInstance(v, typeMapper.mapType(type)); putJavaLangClassInstance(v, typeMapper.mapType(type), type, state);
} }
if (wrapIntoKClass) { if (wrapIntoKClass) {
@@ -1053,16 +1053,16 @@ class ExpressionCodegen(
} else { } else {
val classType = classReference.classType val classType = classReference.classType
if (classType is CrIrType) { if (classType is CrIrType) {
putJavaLangClassInstance(mv, classType.type) putJavaLangClassInstance(mv, classType.type, null, state)
return return
} else { } else {
val type = classType.toKotlinType() val kotlinType = classType.toKotlinType()
if (TypeUtils.isTypeParameter(type)) { if (TypeUtils.isTypeParameter(kotlinType)) {
assert(TypeUtils.isReifiedTypeParameter(type)) { "Non-reified type parameter under ::class should be rejected by type checker: " + type } assert(TypeUtils.isReifiedTypeParameter(kotlinType)) { "Non-reified type parameter under ::class should be rejected by type checker: " + kotlinType }
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this) putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this)
} }
putJavaLangClassInstance(mv, typeMapper.mapType(type)) putJavaLangClassInstance(mv, typeMapper.mapType(kotlinType), kotlinType, state)
} }
} }
@@ -63,5 +63,11 @@ fun box(): String {
val arrU = arrayOf(1u) val arrU = arrayOf(1u)
check(arrU[0]::class, "class kotlin.UInt") check(arrU[0]::class, "class kotlin.UInt")
check(IcInt::class, "class root.IcInt")
check(IcLong::class, "class root.IcLong")
check(IcAny::class, "class root.IcAny")
check(IcOverIc::class, "class root.IcOverIc")
check(UInt::class, "class kotlin.UInt")
return "OK" return "OK"
} }
@@ -16,7 +16,7 @@ inline class T(val s: S) {
fun box(): String { fun box(): String {
assertEquals(listOf(String::class.java, Int::class.java, String::class.java), S::foo.parameters.map { it.type.javaType }) assertEquals(listOf(String::class.java, Int::class.java, String::class.java), S::foo.parameters.map { it.type.javaType })
assertEquals(S::class.java, S::foo.returnType.javaType) assertEquals(String::class.java, S::foo.returnType.javaType)
/* /*
assertEquals(listOf(), T::bar.parameters.map { it.type.javaType }) assertEquals(listOf(), T::bar.parameters.map { it.type.javaType })