From d62a6a2631638206d8c2a8db4a7fc9fe85723b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Fri, 17 Jul 2020 16:16:07 +0200 Subject: [PATCH] JVM IR: Do not create accessors for enum entry constructors --- .../jvm/lower/SyntheticAccessorLowering.kt | 6 +++++- .../bytecodeText/enum/constructorAccessors.kt | 15 +++++++++++++++ .../kotlin/codegen/BytecodeTextTestGenerated.java | 5 +++++ .../codegen/ir/IrBytecodeTextTestGenerated.java | 5 +++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 2bfe33ea9c8..e1dce6affb6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -582,13 +582,17 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle // `internal` maps to public and requires no accessor. if (!withSuper && !declaration.visibility.isPrivate && !declaration.visibility.isProtected) return true - //`toArray` is always accessible cause mapped to public functions + // `toArray` is always accessible cause mapped to public functions if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray(context) || symbolOwner.isGenericToArray(context))) { if (symbolOwner.parentAsClass.isCollectionSubClass) { return true } } + // EnumEntry constructors are always accessible (they are only called from the enclosing Enum class) + if (symbolOwner is IrConstructor && symbolOwner.parentClassOrNull?.isEnumEntry == true) + return true + // If local variables are accessible by Kotlin rules, they also are by Java rules. val ownerClass = declaration.parent as? IrClass ?: return true diff --git a/compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt b/compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt new file mode 100644 index 00000000000..d62cd0fb72f --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt @@ -0,0 +1,15 @@ +enum class E(private val value: Int) { + A(0) { + override fun f() {} + }, + B(1) { + override fun f() {} + }; + + abstract fun f() +} + +// The JVM BE creates an accessor for the constructor of `E`, but not for the constructors of the enum entry classes E$A and E$B. +// 1 public synthetic \(Ljava/lang/String;IILkotlin/jvm/internal/DefaultConstructorMarker;\)V +// 2 INVOKESPECIAL E. \(Ljava/lang/String;IILkotlin/jvm/internal/DefaultConstructorMarker;\)V +// 3 kotlin/jvm/internal/DefaultConstructorMarker;\) \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 9f4abb318ca..2f6e5601cb6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1870,6 +1870,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/enum"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("constructorAccessors.kt") + public void testConstructorAccessors() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt"); + } + @TestMetadata("enumCheckcasts.kt") public void testEnumCheckcasts() throws Exception { runTest("compiler/testData/codegen/bytecodeText/enum/enumCheckcasts.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index 87b76cdeb59..befed43539f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -1825,6 +1825,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/enum"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("constructorAccessors.kt") + public void testConstructorAccessors() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/enum/constructorAccessors.kt"); + } + @TestMetadata("enumCheckcasts.kt") public void testEnumCheckcasts() throws Exception { runTest("compiler/testData/codegen/bytecodeText/enum/enumCheckcasts.kt");