diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt index f65432cfa15..9910cf00320 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.lazy +import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin @@ -154,15 +155,16 @@ class Fir2IrLazyClass( for (declaration in fir.declarations) { when (declaration) { is FirSimpleFunction -> { - if (declaration.name !in processedNames) { + if (fir.classKind == ClassKind.ENUM_CLASS && declaration.isStatic && + (declaration.source == null || declaration.source?.kind == KtFakeSourceElementKind.EnumGeneratedDeclaration) + ) { + // Handle generated methods for enum classes (values(), valueOf(String)). + // TODO we also come here for all deserialized static enum members (with declaration.source == null). + // For such members we currently can't tell whether they are compiler-generated methods or not. + result += declarationStorage.getIrFunctionSymbol(declaration.symbol).owner + } else if (declaration.name !in processedNames) { processedNames += declaration.name - if (fir.classKind == ClassKind.ENUM_CLASS && declaration.isStatic && - declaration.returnTypeRef is FirResolvedTypeRef - ) { - // Handle values() / valueOf() separately - // TODO: handle other static functions / properties properly - result += declarationStorage.getIrFunctionSymbol(declaration.symbol).owner - } else if (fir.classKind == ClassKind.ANNOTATION_CLASS && declaration.origin == FirDeclarationOrigin.Java) { + if (fir.classKind == ClassKind.ANNOTATION_CLASS && declaration.origin == FirDeclarationOrigin.Java) { // Java annotation values are exposed as properties. scope.processPropertiesByName(declaration.name) { if (it is FirPropertySymbol && it.dispatchReceiverClassOrNull() == fir.symbol.toLookupTag()) { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index e028b719ec3..f6b5593d261 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -15330,12 +15330,30 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/enum/javaClassWithNestedEnum.kt"); } + @Test + @TestMetadata("javaEnumValueOf.kt") + public void testJavaEnumValueOf() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValueOf.kt"); + } + @Test @TestMetadata("javaEnumValues.kt") public void testJavaEnumValues() throws Exception { runTest("compiler/testData/codegen/box/enum/javaEnumValues.kt"); } + @Test + @TestMetadata("javaEnumValues2.kt") + public void testJavaEnumValues2() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues2.kt"); + } + + @Test + @TestMetadata("javaEnumValues3.kt") + public void testJavaEnumValues3() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues3.kt"); + } + @Test @TestMetadata("kt1119.kt") public void testKt1119() throws Exception { diff --git a/compiler/testData/codegen/box/enum/javaEnumValueOf.kt b/compiler/testData/codegen/box/enum/javaEnumValueOf.kt new file mode 100644 index 00000000000..7402c67ddde --- /dev/null +++ b/compiler/testData/codegen/box/enum/javaEnumValueOf.kt @@ -0,0 +1,14 @@ +// TARGET_BACKEND: JVM +// FILE: E.java +public enum E { + OK(); + public static String valueOf(E x) { + return x.toString(); + } +} + +// FILE: test.kt + +// check that both 'valueOf(String): E' and 'valueOf(E): String' are invoked correctly +fun box() = + E.valueOf(E.valueOf("OK")) diff --git a/compiler/testData/codegen/box/enum/javaEnumValues.kt b/compiler/testData/codegen/box/enum/javaEnumValues.kt index 3301eddb93e..e81a02de51a 100644 --- a/compiler/testData/codegen/box/enum/javaEnumValues.kt +++ b/compiler/testData/codegen/box/enum/javaEnumValues.kt @@ -1,8 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR -// FIR status: V -// Caused by: java.util.NoSuchElementException: Sequence contains no element matching the predicate. -// at org.jetbrains.kotlin.backend.jvm.lower.MappedEnumWhenLowering.visitClassNew(MappedEnumWhenLowering.kt:232) // FILE: E.java public enum E { A(); diff --git a/compiler/testData/codegen/box/enum/javaEnumValues2.kt b/compiler/testData/codegen/box/enum/javaEnumValues2.kt new file mode 100644 index 00000000000..757bc21bb3a --- /dev/null +++ b/compiler/testData/codegen/box/enum/javaEnumValues2.kt @@ -0,0 +1,18 @@ +// TARGET_BACKEND: JVM +// FILE: E.java +public enum E { + A(); + public static String values(String s) { + return s; + } +} + +// FILE: test.kt + +fun f(e: E) = when (e) { + E.A -> E.values("OK") +} + +fun box(): String { + return f(E.A) +} diff --git a/compiler/testData/codegen/box/enum/javaEnumValues3.kt b/compiler/testData/codegen/box/enum/javaEnumValues3.kt new file mode 100644 index 00000000000..8233cf685e7 --- /dev/null +++ b/compiler/testData/codegen/box/enum/javaEnumValues3.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// FILE: E.java +public enum E { + OK(), A(); + public static void values(boolean b) {} +} + +// FILE: test.kt + +fun f(e: E) = when (e) { + E.A -> E.values()[0].toString() + else -> "?" +} + +fun box(): String { + return f(E.A) +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index cf0b7ff8b66..ba30dffb431 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -15252,12 +15252,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/enum/javaClassWithNestedEnum.kt"); } + @Test + @TestMetadata("javaEnumValueOf.kt") + public void testJavaEnumValueOf() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValueOf.kt"); + } + @Test @TestMetadata("javaEnumValues.kt") public void testJavaEnumValues() throws Exception { runTest("compiler/testData/codegen/box/enum/javaEnumValues.kt"); } + @Test + @TestMetadata("javaEnumValues2.kt") + public void testJavaEnumValues2() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues2.kt"); + } + + @Test + @TestMetadata("javaEnumValues3.kt") + public void testJavaEnumValues3() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues3.kt"); + } + @Test @TestMetadata("kt1119.kt") public void testKt1119() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index ade773e1388..463719a56f7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -15330,12 +15330,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/enum/javaClassWithNestedEnum.kt"); } + @Test + @TestMetadata("javaEnumValueOf.kt") + public void testJavaEnumValueOf() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValueOf.kt"); + } + @Test @TestMetadata("javaEnumValues.kt") public void testJavaEnumValues() throws Exception { runTest("compiler/testData/codegen/box/enum/javaEnumValues.kt"); } + @Test + @TestMetadata("javaEnumValues2.kt") + public void testJavaEnumValues2() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues2.kt"); + } + + @Test + @TestMetadata("javaEnumValues3.kt") + public void testJavaEnumValues3() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues3.kt"); + } + @Test @TestMetadata("kt1119.kt") public void testKt1119() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 49d24054950..8dda270e6d9 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12517,11 +12517,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/enum/javaClassWithNestedEnum.kt"); } + @TestMetadata("javaEnumValueOf.kt") + public void testJavaEnumValueOf() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValueOf.kt"); + } + @TestMetadata("javaEnumValues.kt") public void testJavaEnumValues() throws Exception { runTest("compiler/testData/codegen/box/enum/javaEnumValues.kt"); } + @TestMetadata("javaEnumValues2.kt") + public void testJavaEnumValues2() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues2.kt"); + } + + @TestMetadata("javaEnumValues3.kt") + public void testJavaEnumValues3() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues3.kt"); + } + @TestMetadata("kt1119.kt") public void testKt1119() throws Exception { runTest("compiler/testData/codegen/box/enum/kt1119.kt"); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java index eb87f843db3..d68e9660402 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java @@ -15508,12 +15508,30 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest { runTest("compiler/testData/codegen/box/enum/javaClassWithNestedEnum.kt"); } + @Test + @TestMetadata("javaEnumValueOf.kt") + public void testJavaEnumValueOf() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValueOf.kt"); + } + @Test @TestMetadata("javaEnumValues.kt") public void testJavaEnumValues() throws Exception { runTest("compiler/testData/codegen/box/enum/javaEnumValues.kt"); } + @Test + @TestMetadata("javaEnumValues2.kt") + public void testJavaEnumValues2() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues2.kt"); + } + + @Test + @TestMetadata("javaEnumValues3.kt") + public void testJavaEnumValues3() throws Exception { + runTest("compiler/testData/codegen/box/enum/javaEnumValues3.kt"); + } + @Test @TestMetadata("kt1119.kt") public void testKt1119() throws Exception {