FIR2IR fix enum special methods generation

This commit is contained in:
Dmitry Petrov
2021-11-22 17:10:25 +03:00
committed by Space
parent 2a263eca65
commit 2179987de7
10 changed files with 146 additions and 12 deletions
@@ -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()) {
@@ -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 {
+14
View File
@@ -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"))
-4
View File
@@ -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();
+18
View File
@@ -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)
}
+17
View File
@@ -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)
}
@@ -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 {
@@ -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 {
@@ -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");
@@ -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 {