[JVM IR] Do not generate clinit as enclosing method.
The JVM and newer Android runtimes treats that the same as if there is no enclosing method. However, older Android runtimes for Android 5 and 6 throw exceptions on reflective access and even older runtimes have different behavior. To avoid those issues, exclude <clinit> from enclosing method attributes. ^ KT-48754 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
56867d9c7e
commit
b61389f6f9
+16
@@ -4857,6 +4857,22 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/outerClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class OuterClass {
|
||||
@Test
|
||||
public void testAllFilesPresentInOuterClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/outerClass"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("classInClinit.kt")
|
||||
public void testClassInClinit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/outerClass/classInClinit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/parameterlessMain")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+1
-1
@@ -446,7 +446,7 @@ class ClassCodegen private constructor(
|
||||
?: error("Class in a non-static initializer found, but container has no constructors: ${containerClass.render()}")
|
||||
} else parentFunction
|
||||
if (enclosingFunction != null || irClass.isAnonymousInnerClass) {
|
||||
val method = enclosingFunction?.let(context.methodSignatureMapper::mapAsmMethod)
|
||||
val method = enclosingFunction?.let(context.methodSignatureMapper::mapAsmMethod)?.takeIf { it.name != "<clinit>" }
|
||||
visitor.visitOuterClass(parentClassCodegen!!.type.internalName, method?.name, method?.descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public final class H1 {
|
||||
@kotlin.Metadata
|
||||
final class H2$Companion$property$2 {
|
||||
// source: 'delegatedPropertiesInCompanionObject.kt'
|
||||
enclosing method H2.<clinit>()V
|
||||
enclosing class H2
|
||||
public final static field INSTANCE: H2$Companion$property$2
|
||||
inner (anonymous) class H2$Companion$property$2
|
||||
static method <clinit>(): void
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
@kotlin.Metadata
|
||||
final class FileClassWithPrivateDeclarationsOnly_afterKt$b$2 {
|
||||
// source: 'fileClassWithPrivateDeclarationsOnly_after.kt'
|
||||
enclosing method FileClassWithPrivateDeclarationsOnly_afterKt.<clinit>()V
|
||||
enclosing class FileClassWithPrivateDeclarationsOnly_afterKt
|
||||
public final static field INSTANCE: FileClassWithPrivateDeclarationsOnly_afterKt$b$2
|
||||
inner (anonymous) class FileClassWithPrivateDeclarationsOnly_afterKt$b$2
|
||||
static method <clinit>(): void
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
@kotlin.Metadata
|
||||
final class FileClassWithPrivateDeclarationsOnly_beforeKt$b$2 {
|
||||
// source: 'fileClassWithPrivateDeclarationsOnly_before.kt'
|
||||
enclosing method FileClassWithPrivateDeclarationsOnly_beforeKt.<clinit>()V
|
||||
enclosing class FileClassWithPrivateDeclarationsOnly_beforeKt
|
||||
public final static field INSTANCE: FileClassWithPrivateDeclarationsOnly_beforeKt$b$2
|
||||
inner (anonymous) class FileClassWithPrivateDeclarationsOnly_beforeKt$b$2
|
||||
static method <clinit>(): void
|
||||
|
||||
+4
-4
@@ -10,7 +10,7 @@ public final class A {
|
||||
@kotlin.Metadata
|
||||
synthetic final class NoReceiverInCallableReferenceClassesKt$A_bar$1 {
|
||||
// source: 'noReceiverInCallableReferenceClasses.kt'
|
||||
enclosing method NoReceiverInCallableReferenceClassesKt.<clinit>()V
|
||||
enclosing class NoReceiverInCallableReferenceClassesKt
|
||||
public final static field INSTANCE: NoReceiverInCallableReferenceClassesKt$A_bar$1
|
||||
inner (anonymous) class NoReceiverInCallableReferenceClassesKt$A_bar$1
|
||||
static method <clinit>(): void
|
||||
@@ -21,7 +21,7 @@ synthetic final class NoReceiverInCallableReferenceClassesKt$A_bar$1 {
|
||||
@kotlin.Metadata
|
||||
synthetic final class NoReceiverInCallableReferenceClassesKt$A_foo$1 {
|
||||
// source: 'noReceiverInCallableReferenceClasses.kt'
|
||||
enclosing method NoReceiverInCallableReferenceClassesKt.<clinit>()V
|
||||
enclosing class NoReceiverInCallableReferenceClassesKt
|
||||
public final static field INSTANCE: NoReceiverInCallableReferenceClassesKt$A_foo$1
|
||||
inner (anonymous) class NoReceiverInCallableReferenceClassesKt$A_foo$1
|
||||
static method <clinit>(): void
|
||||
@@ -33,7 +33,7 @@ synthetic final class NoReceiverInCallableReferenceClassesKt$A_foo$1 {
|
||||
@kotlin.Metadata
|
||||
synthetic final class NoReceiverInCallableReferenceClassesKt$aBar$1 {
|
||||
// source: 'noReceiverInCallableReferenceClasses.kt'
|
||||
enclosing method NoReceiverInCallableReferenceClassesKt.<clinit>()V
|
||||
enclosing class NoReceiverInCallableReferenceClassesKt
|
||||
inner (anonymous) class NoReceiverInCallableReferenceClassesKt$aBar$1
|
||||
method <init>(p0: java.lang.Object): void
|
||||
public @org.jetbrains.annotations.Nullable method get(): java.lang.Object
|
||||
@@ -42,7 +42,7 @@ synthetic final class NoReceiverInCallableReferenceClassesKt$aBar$1 {
|
||||
@kotlin.Metadata
|
||||
synthetic final class NoReceiverInCallableReferenceClassesKt$aFoo$1 {
|
||||
// source: 'noReceiverInCallableReferenceClasses.kt'
|
||||
enclosing method NoReceiverInCallableReferenceClassesKt.<clinit>()V
|
||||
enclosing class NoReceiverInCallableReferenceClassesKt
|
||||
inner (anonymous) class NoReceiverInCallableReferenceClassesKt$aFoo$1
|
||||
method <init>(p0: java.lang.Object): void
|
||||
public synthetic bridge method invoke(): java.lang.Object
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// FILE: test.kt
|
||||
|
||||
// This should *not* have enclosing method <clinit>. See https://youtrack.jetbrains.com/issue/KT-48754.
|
||||
val a = {}
|
||||
|
||||
// @TestKt$a$1.class:
|
||||
// 1 OUTERCLASS TestKt null
|
||||
+16
@@ -4713,6 +4713,22 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/outerClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class OuterClass {
|
||||
@Test
|
||||
public void testAllFilesPresentInOuterClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/outerClass"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("classInClinit.kt")
|
||||
public void testClassInClinit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/outerClass/classInClinit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/parameterlessMain")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+16
@@ -4857,6 +4857,22 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/outerClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class OuterClass {
|
||||
@Test
|
||||
public void testAllFilesPresentInOuterClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/outerClass"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("classInClinit.kt")
|
||||
public void testClassInClinit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/outerClass/classInClinit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/parameterlessMain")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user