From b0efcec392ce025442cb48d81f7473dc131a6c6e Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Fri, 23 Oct 2015 13:49:07 +0300 Subject: [PATCH] Fix for KT-9711: Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE #KT-9711 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 10 +++++----- .../jetbrains/kotlin/codegen/FieldInfo.java | 2 +- .../jetbrains/kotlin/codegen/StackValue.java | 12 +++++++++++- compiler/testData/codegen/box/enum/kt9711.kt | 13 +++++++++++++ compiler/testData/codegen/box/enum/kt9711_2.kt | 18 ++++++++++++++++++ .../BlackBoxCodegenTestGenerated.java | 12 ++++++++++++ 6 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/enum/kt9711.kt create mode 100644 compiler/testData/codegen/box/enum/kt9711_2.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 13a3e8363fc..f5c19eb10e8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2025,10 +2025,7 @@ public class ExpressionCodegen extends KtVisitor impleme return StackValue.singleton(classDescriptor, typeMapper); } if (isEnumEntry(classDescriptor)) { - DeclarationDescriptor enumClass = classDescriptor.getContainingDeclaration(); - assert DescriptorUtils.isEnumClass(enumClass) : "Enum entry should be declared in enum class: " + descriptor; - Type type = typeMapper.mapType((ClassDescriptor) enumClass); - return StackValue.field(type, type, descriptor.getName().asString(), true, StackValue.none(), classDescriptor); + return StackValue.enumEntry(classDescriptor, typeMapper); } ClassDescriptor companionObjectDescriptor = classDescriptor.getCompanionObjectDescriptor(); if (companionObjectDescriptor != null) { @@ -2568,7 +2565,7 @@ public class ExpressionCodegen extends KtVisitor impleme } } else { - return StackValue.thisOrOuter(this, receiverDescriptor, false, false); + return StackValue.thisOrOuter(this, receiverDescriptor, false, isEnumEntry(receiverDescriptor)); } } else if (receiverValue instanceof ScriptReceiver) { @@ -2638,6 +2635,9 @@ public class ExpressionCodegen extends KtVisitor impleme !AnnotationUtilKt.isPlatformStaticInObjectOrClass(context.getContextDescriptor())) { return StackValue.local(0, typeMapper.mapType(calleeContainingClass)); } + else if (isEnumEntry(calleeContainingClass)) { + return StackValue.enumEntry(calleeContainingClass, typeMapper); + } else { return StackValue.singleton(calleeContainingClass, typeMapper); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FieldInfo.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FieldInfo.java index 3eec2bd48d2..35080bee57a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FieldInfo.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FieldInfo.java @@ -38,7 +38,7 @@ public class FieldInfo { @NotNull public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) { - if (!classDescriptor.getKind().isSingleton()) { + if (!classDescriptor.getKind().isSingleton() || DescriptorUtils.isEnumEntry(classDescriptor)) { throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 6e5b6424c31..bc738c41ed3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor; import org.jetbrains.kotlin.psi.KtExpression; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; @@ -575,7 +576,16 @@ public abstract class StackValue { return receiverWithParameter; } - public static Field singleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) { + @NotNull + public static Field enumEntry(@NotNull ClassDescriptor descriptor, @NotNull JetTypeMapper typeMapper) { + DeclarationDescriptor enumClass = descriptor.getContainingDeclaration(); + assert DescriptorUtils.isEnumClass(enumClass) : "Enum entry should be declared in enum class: " + descriptor; + Type type = typeMapper.mapType((ClassDescriptor) enumClass); + return field(type, type, descriptor.getName().asString(), true, none(), descriptor); + } + + @NotNull + public static Field singleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) { return field(FieldInfo.createForSingleton(classDescriptor, typeMapper)); } diff --git a/compiler/testData/codegen/box/enum/kt9711.kt b/compiler/testData/codegen/box/enum/kt9711.kt new file mode 100644 index 00000000000..096316ed24b --- /dev/null +++ b/compiler/testData/codegen/box/enum/kt9711.kt @@ -0,0 +1,13 @@ +enum class X { + + B { + val value2 = "OK" + override val value = { value2 } + }; + + abstract val value: () -> String +} + +fun box(): String { + return X.B.value() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/enum/kt9711_2.kt b/compiler/testData/codegen/box/enum/kt9711_2.kt new file mode 100644 index 00000000000..1ead4684c4b --- /dev/null +++ b/compiler/testData/codegen/box/enum/kt9711_2.kt @@ -0,0 +1,18 @@ +enum class IssueState { + + FIXED { + override fun ToString() = D().k + + fun s() = "OK" + + class D { + val k = s() + } + }; + + open fun ToString() : String = "fail" +} + +fun box(): String { + return IssueState.FIXED.ToString() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 90494d428f5..20c9c03e4d3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3496,6 +3496,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt9711.kt") + public void testKt9711() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt9711.kt"); + doTest(fileName); + } + + @TestMetadata("kt9711_2.kt") + public void testKt9711_2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt9711_2.kt"); + doTest(fileName); + } + @TestMetadata("name.kt") public void testName() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/name.kt");