Inline (wrapper) class IC extends erased inline class IC$Erased
This commit is contained in:
@@ -14,11 +14,14 @@ import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErasedInlineClassOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class ErasedInlineClassBodyCodegen(
|
||||
aClass: KtClass,
|
||||
@@ -28,9 +31,8 @@ class ErasedInlineClassBodyCodegen(
|
||||
parentCodegen: MemberCodegen<*>?
|
||||
) : ClassBodyCodegen(aClass, context, v, state, parentCodegen) {
|
||||
|
||||
private val superClassAsmType: Type by lazy {
|
||||
SuperClassInfo.getSuperClassInfo(descriptor, typeMapper).type
|
||||
}
|
||||
private val wrapperSuperClassAsmType = AsmTypes.OBJECT_TYPE
|
||||
private val erasedSuperClassAsmType = AsmTypes.OBJECT_TYPE
|
||||
|
||||
private val classAsmType = typeMapper.mapErasedInlineClass(descriptor)
|
||||
|
||||
@@ -40,7 +42,7 @@ class ErasedInlineClassBodyCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(
|
||||
myClass.psiOrParent, state.classFileVersion, Opcodes.ACC_FINAL or Opcodes.ACC_STATIC or Opcodes.ACC_PUBLIC,
|
||||
myClass.psiOrParent, state.classFileVersion, Opcodes.ACC_STATIC or Opcodes.ACC_PUBLIC,
|
||||
classAsmType.internalName, null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.containingKtFile.name, null)
|
||||
@@ -49,15 +51,30 @@ class ErasedInlineClassBodyCodegen(
|
||||
override fun generateConstructors() {
|
||||
val delegationFieldsInfo = DelegationFieldsInfo(classAsmType, descriptor, state, bindingContext)
|
||||
|
||||
constructorCodegen.generatePrimaryConstructor(
|
||||
delegationFieldsInfo.getDelegationFieldsInfo(myClass.superTypeListEntries), superClassAsmType
|
||||
)
|
||||
generateDefaultConstructorForErasedInlineClass()
|
||||
|
||||
constructorCodegen.generatePrimaryConstructor(delegationFieldsInfo, wrapperSuperClassAsmType)
|
||||
|
||||
for (secondaryConstructor in descriptor.secondaryConstructors) {
|
||||
constructorCodegen.generateSecondaryConstructor(secondaryConstructor, superClassAsmType)
|
||||
constructorCodegen.generateSecondaryConstructor(secondaryConstructor, wrapperSuperClassAsmType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDefaultConstructorForErasedInlineClass() {
|
||||
val mv = v.newMethod(
|
||||
ErasedInlineClassOrigin(myClass.psiOrParent, descriptor), 0,
|
||||
"<init>", "()V", null, ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
mv.visitCode()
|
||||
InstructionAdapter(mv).apply {
|
||||
load(0, AsmTypes.OBJECT_TYPE)
|
||||
invokespecial(erasedSuperClassAsmType.internalName, "<init>", "()V", false)
|
||||
areturn(Type.VOID_TYPE)
|
||||
}
|
||||
mv.visitMaxs(1, 1)
|
||||
mv.visitEnd()
|
||||
}
|
||||
|
||||
override fun generateSyntheticPartsAfterBody() {
|
||||
super.generateSyntheticPartsAfterBody()
|
||||
|
||||
|
||||
@@ -131,7 +131,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateDeclaration() {
|
||||
getSuperClass();
|
||||
superClassInfo = SuperClassInfo.getSuperClassInfo(descriptor, typeMapper);
|
||||
superClassAsmType = superClassInfo.getType();
|
||||
|
||||
JvmClassSignature signature = signature();
|
||||
|
||||
@@ -404,11 +405,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
new ArrayList<>(superInterfaces), sw.makeJavaGenericSignature());
|
||||
}
|
||||
|
||||
private void getSuperClass() {
|
||||
superClassInfo = SuperClassInfo.getSuperClassInfo(descriptor, typeMapper);
|
||||
superClassAsmType = superClassInfo.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticPartsBeforeBody() {
|
||||
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
|
||||
|
||||
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class SuperClassInfo(
|
||||
val type: Type,
|
||||
// null means java/lang/Object
|
||||
val kotlinType: KotlinType?
|
||||
val type: Type,
|
||||
// null means java/lang/Object or irrelevant
|
||||
val kotlinType: KotlinType?
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -37,6 +37,10 @@ class SuperClassInfo(
|
||||
return SuperClassInfo(OBJECT_TYPE, null)
|
||||
}
|
||||
|
||||
if (descriptor.isInline) {
|
||||
return SuperClassInfo(typeMapper.mapErasedInlineClass(descriptor), null)
|
||||
}
|
||||
|
||||
for (supertype in descriptor.typeConstructor.supertypes) {
|
||||
val superClass = supertype.constructor.declarationDescriptor
|
||||
if (superClass != null && !isJvmInterface(superClass)) {
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
interface IFoo {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
inline class IC(val x: String) : IFoo {
|
||||
private fun privateFun() = x
|
||||
override fun foo() = privateFun()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val x: IFoo = IC("OK")
|
||||
return x.foo()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
inline class IC(val x: String) {
|
||||
private fun privateFun() = x
|
||||
override fun toString() = privateFun()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val x: Any = IC("OK")
|
||||
return x.toString()
|
||||
}
|
||||
+2
@@ -14,6 +14,8 @@ inline class A(val x: Int) {
|
||||
inline fun stub() {}
|
||||
|
||||
// FILE: 2.kt
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// ^ TODO
|
||||
|
||||
import test.*
|
||||
|
||||
|
||||
Vendored
+2
-1
@@ -7,7 +7,8 @@ public final class Foo$Companion {
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final static class Foo$Erased {
|
||||
public static class Foo$Erased {
|
||||
method <init>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(p0: int): Foo
|
||||
public static method constructor(p0: int): int
|
||||
public static method equals(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean
|
||||
|
||||
Vendored
+2
-1
@@ -1,5 +1,6 @@
|
||||
@kotlin.Metadata
|
||||
public final static class Foo$Erased {
|
||||
public static class Foo$Erased {
|
||||
method <init>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(p0: int): Foo
|
||||
public static method constructor(p0: int): int
|
||||
public static method equals(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ public interface A {
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final static class Foo$Erased {
|
||||
public static class Foo$Erased {
|
||||
method <init>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(p0: long): Foo
|
||||
public static method constructor(p0: long): long
|
||||
public static method equals(p0: long, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean
|
||||
|
||||
Vendored
+2
-1
@@ -1,5 +1,6 @@
|
||||
@kotlin.Metadata
|
||||
public final static class Foo$Erased {
|
||||
public static class Foo$Erased {
|
||||
method <init>(): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(p0: long): Foo
|
||||
public static method constructor(p0: long): long
|
||||
public final static method empty(p0: long): void
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class Z(val x: Int)
|
||||
|
||||
interface IFoo
|
||||
interface IBar
|
||||
inline class FooBar(val x: Int) : IFoo, IBar
|
||||
|
||||
// 1 public final class Z extends Z\$Erased
|
||||
// 1 static class Z\$Erased
|
||||
// 0 public static class Z\$Erased
|
||||
|
||||
// 1 public final class FooBar extends FooBar\$Erased implements IFoo IBar
|
||||
// 1 static class FooBar\$Erased
|
||||
// 0 public static class FooBar\$Erased
|
||||
+10
@@ -11731,6 +11731,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overridingFunCallingPrivateFun.kt")
|
||||
public void testOverridingFunCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringCallingPrivateFun.kt")
|
||||
public void testToStringCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
|
||||
@@ -2088,6 +2088,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassBoxingUnboxingInsideInlinedLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassExtendsErasedClass.kt")
|
||||
public void testInlineClassExtendsErasedClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassExtendsErasedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassesUnboxingAfterAssertionOperator.kt")
|
||||
public void testInlineClassesUnboxingAfterAssertionOperator() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassesUnboxingAfterAssertionOperator.kt");
|
||||
|
||||
+10
@@ -11731,6 +11731,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overridingFunCallingPrivateFun.kt")
|
||||
public void testOverridingFunCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringCallingPrivateFun.kt")
|
||||
public void testToStringCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
|
||||
+10
@@ -11731,6 +11731,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overridingFunCallingPrivateFun.kt")
|
||||
public void testOverridingFunCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringCallingPrivateFun.kt")
|
||||
public void testToStringCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
|
||||
@@ -26,7 +26,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
public final class JvmAbi {
|
||||
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
||||
public static final String ERASED_INLINE_CONSTRUCTOR_NAME = "constructor";
|
||||
private static final String ERASED_INLINE_CLASS_NAME = "Erased";
|
||||
public static final FqName JVM_FIELD_ANNOTATION_FQ_NAME = new FqName("kotlin.jvm.JvmField");
|
||||
|
||||
/**
|
||||
@@ -58,6 +57,7 @@ public final class JvmAbi {
|
||||
public static final String LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT = "$i$a$";
|
||||
public static final String LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION = "$i$f$";
|
||||
|
||||
private static final String ERASED_INLINE_CLASS_NAME = "Erased";
|
||||
public static final String ERASED_INLINE_CLASS_SUFFIX = "$" + ERASED_INLINE_CLASS_NAME;
|
||||
|
||||
@NotNull
|
||||
|
||||
+10
@@ -10266,6 +10266,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overridingFunCallingPrivateFun.kt")
|
||||
public void testOverridingFunCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
@@ -10296,6 +10301,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringCallingPrivateFun.kt")
|
||||
public void testToStringCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
|
||||
+10
@@ -11331,6 +11331,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overridingFunCallingPrivateFun.kt")
|
||||
public void testOverridingFunCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
@@ -11361,6 +11366,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringCallingPrivateFun.kt")
|
||||
public void testToStringCallingPrivateFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
|
||||
Reference in New Issue
Block a user