From 16ae83bde0b6261b8e4bbf9f5ac65324facb2f2f Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Thu, 7 Sep 2023 12:17:59 +0200 Subject: [PATCH] [FIR] Fix Java sealed class inheritors This fixes NO_ELSE_IN_WHEN diagnostics when using java sealed classes in an exhaustive when. #KT-58216 Fixed --- ...ClassInheritorsProcessorFactoryForTests.kt | 7 +- .../kotlin/fir/java/FirJavaFacade.kt | 2 +- .../javaSealedClassExhaustiveness.fir.kt | 44 ------------- .../javaSealedClassExhaustiveness.kt | 1 + .../javaSealedInterfaceExhaustiveness.fir.kt | 64 ------------------- .../javaSealedInterfaceExhaustiveness.kt | 1 + 6 files changed, 8 insertions(+), 111 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.fir.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt index 0e7a0a94d5e..c25d8bca0d9 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirMo import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider +import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderInternals +import org.jetbrains.kotlin.fir.declarations.sealedInheritorsAttr import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.name.ClassId @@ -28,10 +30,11 @@ internal class LLFirSealedClassInheritorsProcessorFactoryForTests : FirSealedCla private class SealedClassInheritorsProviderForTests( private val inheritorsByModule: Map>> ) : SealedClassInheritorsProvider() { + @OptIn(SealedClassInheritorsProviderInternals::class) override fun getSealedClassInheritors(firClass: FirRegularClass): List { val ktModule = firClass.llFirModuleData.ktModule val inheritorsForModuleMap = inheritorsByModule.getValue(ktModule) - return inheritorsForModuleMap[firClass.classId].orEmpty() + return inheritorsForModuleMap[firClass.classId] ?: firClass.sealedInheritorsAttr?.value ?: emptyList() } -} \ No newline at end of file +} diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt index 3927e3a1b0f..0942b5f22bf 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt @@ -394,7 +394,7 @@ abstract class FirJavaFacade( setSealedClassInheritors { permittedTypes.mapNotNull { classifierType -> val classifier = classifierType.classifier as? JavaClass - classifier?.let { JavaToKotlinClassMap.mapJavaToKotlin(it.fqName!!) } + classifier?.let { JavaToKotlinClassMap.mapJavaToKotlin(it.fqName!!) ?: it.classId } } } } diff --git a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.fir.kt deleted file mode 100644 index cce64dd75a8..00000000000 --- a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.fir.kt +++ /dev/null @@ -1,44 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_VARIABLE -// ISSUE: KT-41215, KT-43551 - -// FILE: Base.java -public sealed class Base permits A, B {} - -// FILE: A.java -public final class A extends Base {} - -// FILE: B.java -public sealed class B extends Base permits B.C, B.D { - public static final class C implements B {} - - public static non-sealed class D extends B {} -} - -// FILE: main.kt -fun test_ok_1(base: Base) { - val x = when (base) { - is A -> 1 - is B -> 2 - } -} - -fun test_ok_2(base: Base) { - val x = when (base) { - is A -> 1 - is B.C -> 2 - is B.D -> 3 - } -} - -fun test_error_1(base: Base) { - val x = when (base) { - is A -> 1 - } -} - -fun test_error_2(base: Base) { - val x = when (base) { - is A -> 1 - is B.C -> 2 - } -} diff --git a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt index 0ae9771eb1f..e7972fb507b 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VARIABLE // ISSUE: KT-41215, KT-43551 diff --git a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.fir.kt deleted file mode 100644 index 3e478edc7ec..00000000000 --- a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.fir.kt +++ /dev/null @@ -1,64 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_VARIABLE -// ISSUE: KT-41215, KT-43551 - -// FILE: Base.java -public sealed interface Base permits A, B, E {} - -// FILE: A.java -public non-sealed interface A extends Base {} - -// FILE: B.java -public sealed interface B extends Base permits B.C, B.D { - public static final class C implements B {} - - public static non-sealed interface D extends B {} -} - -// FILE: E.java -public enum E implements Base { - First, Second -} - -// FILE: main.kt -fun test_ok_1(base: Base) { - val x = when (base) { - is A -> 1 - is B -> 2 - is E -> 3 - } -} - -fun test_ok_2(base: Base) { - val x = when (base) { - is A -> 1 - is B.C -> 2 - is B.D -> 3 - E.First -> 4 - E.Second -> 5 - } -} - -fun test_error_1(base: Base) { - val x = when (base) { - is A -> 1 - is B -> 2 - } -} - -fun test_error_2(base: Base) { - val x = when (base) { - is A -> 1 - is B.C -> 2 - is B.D -> 3 - E.Second -> 5 - } -} - -fun test_error_3(base: Base) { - val x = when (base) { - is A -> 1 - is B.C -> 2 - E.First -> 4 - E.Second -> 5 - } -} diff --git a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt index 3419f18de62..4cc7b5e56b5 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VARIABLE // ISSUE: KT-41215, KT-43551