[FE] Make whens on expect sealed classes and enums not exhaustive
This commit is contained in:
+28
@@ -17989,6 +17989,34 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Exhaustiveness {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectEnum.kt")
|
||||||
|
public void testExpectEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectSealedClass.kt")
|
||||||
|
public void testExpectSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectSealedInterface.kt")
|
||||||
|
public void testExpectSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/generic")
|
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/generic")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+28
@@ -24594,6 +24594,34 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Exhaustiveness {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonEnum.kt")
|
||||||
|
public void testCommonEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedClass.kt")
|
||||||
|
public void testCommonSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedInterface.kt")
|
||||||
|
public void testCommonSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -17,6 +17,16 @@ sealed class WhenMissingCase {
|
|||||||
override val branchConditionText: String = "else"
|
override val branchConditionText: String = "else"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class ConditionTypeIsExpect(val typeOfDeclaration: String) : WhenMissingCase() {
|
||||||
|
object SealedClass : ConditionTypeIsExpect("sealed class")
|
||||||
|
object SealedInterface : ConditionTypeIsExpect("sealed interface")
|
||||||
|
object Enum : ConditionTypeIsExpect("enum")
|
||||||
|
|
||||||
|
override val branchConditionText: String = "else"
|
||||||
|
|
||||||
|
override fun toString(): String = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
object NullIsMissing : WhenMissingCase() {
|
object NullIsMissing : WhenMissingCase() {
|
||||||
override val branchConditionText: String = "null"
|
override val branchConditionText: String = "null"
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -1003,6 +1004,10 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
if (usedAsExpression && missingCases.isNotEmpty()) {
|
if (usedAsExpression && missingCases.isNotEmpty()) {
|
||||||
if (elseEntry != null) continue
|
if (elseEntry != null) continue
|
||||||
trace.report(NO_ELSE_IN_WHEN.on(element, missingCases))
|
trace.report(NO_ELSE_IN_WHEN.on(element, missingCases))
|
||||||
|
missingCases.firstOrNull { it is WhenMissingCase.ConditionTypeIsExpect }?.let {
|
||||||
|
require(it is WhenMissingCase.ConditionTypeIsExpect)
|
||||||
|
trace.report(EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE.on(element, it.typeOfDeclaration))
|
||||||
|
}
|
||||||
} else if (subjectExpression != null) {
|
} else if (subjectExpression != null) {
|
||||||
val subjectType = trace.getType(subjectExpression)
|
val subjectType = trace.getType(subjectExpression)
|
||||||
if (elseEntry != null) {
|
if (elseEntry != null) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cfg
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.cfg.WhenOnEnumExhaustivenessChecker.enumEntries
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -40,11 +41,13 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
val List<WhenMissingCase>.hasUnknown: Boolean
|
val List<WhenMissingCase>.hasUnknown: Boolean
|
||||||
get() = firstOrNull() == WhenMissingCase.Unknown
|
get() = any { it == WhenMissingCase.Unknown || it is WhenMissingCase.ConditionTypeIsExpect }
|
||||||
|
|
||||||
private interface WhenExhaustivenessChecker {
|
private interface WhenExhaustivenessChecker {
|
||||||
fun getMissingCases(
|
fun getMissingCases(
|
||||||
@@ -57,6 +60,21 @@ private interface WhenExhaustivenessChecker {
|
|||||||
fun isApplicable(subjectType: KotlinType): Boolean = false
|
fun isApplicable(subjectType: KotlinType): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's not a regular exhaustiveness checker, invoke it only inside other checkers
|
||||||
|
private object WhenOnExpectExhaustivenessChecker {
|
||||||
|
fun getMissingCase(subjectDescriptor: ClassDescriptor?): WhenMissingCase? {
|
||||||
|
return runIf(subjectDescriptor?.isExpect == true) {
|
||||||
|
when (subjectDescriptor!!.kind) {
|
||||||
|
ClassKind.CLASS -> WhenMissingCase.ConditionTypeIsExpect.SealedClass
|
||||||
|
ClassKind.INTERFACE -> WhenMissingCase.ConditionTypeIsExpect.SealedInterface
|
||||||
|
ClassKind.ENUM_CLASS -> WhenMissingCase.ConditionTypeIsExpect.Enum
|
||||||
|
else -> WhenMissingCase.Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// It's not a regular exhaustiveness checker, invoke it only inside other checkers
|
// It's not a regular exhaustiveness checker, invoke it only inside other checkers
|
||||||
private object WhenOnNullableExhaustivenessChecker /* : WhenExhaustivenessChecker*/ {
|
private object WhenOnNullableExhaustivenessChecker /* : WhenExhaustivenessChecker*/ {
|
||||||
fun getMissingCases(expression: KtWhenExpression, context: BindingContext, nullable: Boolean) =
|
fun getMissingCases(expression: KtWhenExpression, context: BindingContext, nullable: Boolean) =
|
||||||
@@ -209,6 +227,7 @@ internal abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
override fun getMissingCases(
|
override fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
context: BindingContext,
|
context: BindingContext,
|
||||||
@@ -216,8 +235,11 @@ private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecke
|
|||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): List<WhenMissingCase> {
|
): List<WhenMissingCase> {
|
||||||
assert(isEnumClass(subjectDescriptor)) { "isWhenOnEnumExhaustive should be called with an enum class descriptor" }
|
assert(isEnumClass(subjectDescriptor)) { "isWhenOnEnumExhaustive should be called with an enum class descriptor" }
|
||||||
return getMissingClassCases(expression, subjectDescriptor!!.enumEntries, context) +
|
return buildList {
|
||||||
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, nullable)
|
addAll(getMissingClassCases(expression, subjectDescriptor!!.enumEntries, context))
|
||||||
|
addAll(WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, nullable))
|
||||||
|
addIfNotNull(WhenOnExpectExhaustivenessChecker.getMissingCase(subjectDescriptor))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType): Boolean {
|
override fun isApplicable(subjectType: KotlinType): Boolean {
|
||||||
@@ -226,7 +248,7 @@ private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecke
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
internal object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
override fun getMissingCases(
|
override fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
context: BindingContext,
|
context: BindingContext,
|
||||||
@@ -238,8 +260,11 @@ internal object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChe
|
|||||||
}
|
}
|
||||||
|
|
||||||
val allSubclasses = subjectDescriptor!!.deepSealedSubclasses
|
val allSubclasses = subjectDescriptor!!.deepSealedSubclasses
|
||||||
return getMissingClassCases(expression, allSubclasses.toSet(), context) +
|
return buildList {
|
||||||
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, nullable)
|
addAll(getMissingClassCases(expression, allSubclasses.toSet(), context))
|
||||||
|
addAll(WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, nullable))
|
||||||
|
addIfNotNull(WhenOnExpectExhaustivenessChecker.getMissingCase(subjectDescriptor))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType): Boolean {
|
override fun isApplicable(subjectType: KotlinType): Boolean {
|
||||||
|
|||||||
@@ -1057,6 +1057,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
||||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>>
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>>
|
||||||
NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS = DiagnosticFactory1.create(INFO, WHEN_EXPRESSION);
|
NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS = DiagnosticFactory1.create(INFO, WHEN_EXPRESSION);
|
||||||
|
DiagnosticFactory1<KtWhenExpression, String> EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION);
|
||||||
|
|
||||||
DiagnosticFactory0<PsiElement> COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> DUPLICATE_LABEL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<PsiElement> DUPLICATE_LABEL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
||||||
|
|||||||
+1
@@ -610,6 +610,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES);
|
MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
MAP.put(NON_EXHAUSTIVE_WHEN, "''when'' expression on enum is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
MAP.put(NON_EXHAUSTIVE_WHEN, "''when'' expression on enum is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
MAP.put(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS, "''when'' expression on sealed classes is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
MAP.put(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS, "''when'' expression on sealed classes is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
|
MAP.put(EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE, "'when' with expect {0} as subject can not be exhaustive without else branch", STRING);
|
||||||
|
|
||||||
MAP.put(TYPE_MISMATCH_IN_RANGE, "Type mismatch: incompatible types of range and element checked in it");
|
MAP.put(TYPE_MISMATCH_IN_RANGE, "Type mismatch: incompatible types of range and element checked in it");
|
||||||
MAP.put(CYCLIC_INHERITANCE_HIERARCHY, "There's a cycle in the inheritance hierarchy for this type");
|
MAP.put(CYCLIC_INHERITANCE_HIERARCHY, "There's a cycle in the inheritance hierarchy for this type");
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// ISSUE: KT-20306
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
enum class Base {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be Ok
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun testPlatform(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = "OK"
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
sealed class Base()
|
||||||
|
|
||||||
|
class A : Base()
|
||||||
|
object B : Base()
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be Ok
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun testPlatform(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = "OK"
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
sealed interface Base
|
||||||
|
|
||||||
|
interface A : Base
|
||||||
|
object B : Base
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be Ok
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun testPlatform(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = "OK"
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-20306
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect enum class Base {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be an error
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual enum class Base {
|
||||||
|
A, B, C
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
Base.C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-20306
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect enum class Base {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = <!EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE("enum"), NO_ELSE_IN_WHEN("'else' branch"), NO_ELSE_IN_WHEN{JVM}("'C' branch or 'else' branch instead")!>when<!> (base) { // must be an error
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual enum class Base {
|
||||||
|
A, B, C
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
Base.C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
Base.A -> 1
|
||||||
|
Base.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
// -- Module: <m1-common> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final expect enum class Base : kotlin.Enum<Base> {
|
||||||
|
expect enum entry A
|
||||||
|
|
||||||
|
expect enum entry B
|
||||||
|
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Base): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Base
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<Base>
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Module: <m1-jvm> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformBad(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformGood(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final actual enum class Base : kotlin.Enum<Base> {
|
||||||
|
enum entry A
|
||||||
|
|
||||||
|
enum entry B
|
||||||
|
|
||||||
|
enum entry C
|
||||||
|
|
||||||
|
private constructor Base()
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Base): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||||
|
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Base!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Base
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<Base>
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect sealed class Base()
|
||||||
|
|
||||||
|
class A : Base()
|
||||||
|
object B : Base()
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual sealed class Base
|
||||||
|
|
||||||
|
// FILE: C.kt
|
||||||
|
|
||||||
|
class C : Base()
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
is C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect sealed class Base()
|
||||||
|
|
||||||
|
class A : Base()
|
||||||
|
object B : Base()
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = <!EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE("sealed class"), NO_ELSE_IN_WHEN("'else' branch"), NO_ELSE_IN_WHEN{JVM}("'is C' branch or 'else' branch instead")!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual sealed class Base
|
||||||
|
|
||||||
|
// FILE: C.kt
|
||||||
|
|
||||||
|
class C : Base()
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
is C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
// -- Module: <m1-common> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A : Base {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object B : Base {
|
||||||
|
private constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed expect class Base {
|
||||||
|
protected constructor Base()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Module: <m1-jvm> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformBad(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformGood(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A : Base {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object B : Base {
|
||||||
|
private constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed actual class Base {
|
||||||
|
protected constructor Base()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class C : Base {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Vendored
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect sealed interface Base
|
||||||
|
|
||||||
|
class A : Base
|
||||||
|
object B : Base
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = when (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual sealed interface Base
|
||||||
|
|
||||||
|
// FILE: C.kt
|
||||||
|
|
||||||
|
interface C : Base
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
is C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// ISSUE: KT-44474
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect sealed interface Base
|
||||||
|
|
||||||
|
class A : Base
|
||||||
|
object B : Base
|
||||||
|
|
||||||
|
fun testCommon(base: Base) {
|
||||||
|
val x = <!EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE("sealed interface"), NO_ELSE_IN_WHEN("'else' branch"), NO_ELSE_IN_WHEN{JVM}("'is C' branch or 'else' branch instead")!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm(m1-common)
|
||||||
|
// FILE: Base.kt
|
||||||
|
actual sealed interface Base
|
||||||
|
|
||||||
|
// FILE: C.kt
|
||||||
|
|
||||||
|
interface C : Base
|
||||||
|
|
||||||
|
fun testPlatformGood(base: Base) {
|
||||||
|
val x = when (base) { // must be OK
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
is C -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPlatformBad(base: Base) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) { // must be an error
|
||||||
|
is A -> 1
|
||||||
|
B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
// -- Module: <m1-common> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A : Base {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object B : Base {
|
||||||
|
private constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed expect interface Base {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Module: <m1-jvm> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun testCommon(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformBad(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun testPlatformGood(/*0*/ base: Base): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A : Base {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object B : Base {
|
||||||
|
private constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed actual interface Base {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface C : Base {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
Generated
+28
@@ -17995,6 +17995,34 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Exhaustiveness {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectEnum.kt")
|
||||||
|
public void testExpectEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectSealedClass.kt")
|
||||||
|
public void testExpectSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectSealedInterface.kt")
|
||||||
|
public void testExpectSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/exhaustiveness/expectSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/generic")
|
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/generic")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+28
@@ -24594,6 +24594,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Exhaustiveness {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonEnum.kt")
|
||||||
|
public void testCommonEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedClass.kt")
|
||||||
|
public void testCommonSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedInterface.kt")
|
||||||
|
public void testCommonSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+28
@@ -24594,6 +24594,34 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Exhaustiveness {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonEnum.kt")
|
||||||
|
public void testCommonEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedClass.kt")
|
||||||
|
public void testCommonSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonSealedInterface.kt")
|
||||||
|
public void testCommonSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+28
@@ -20877,6 +20877,34 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Exhaustiveness extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("commonEnum.kt")
|
||||||
|
public void testCommonEnum() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonEnum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("commonSealedClass.kt")
|
||||||
|
public void testCommonSealedClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("commonSealedInterface.kt")
|
||||||
|
public void testCommonSealedInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multiplatform/exhaustiveness/commonSealedInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -90,8 +90,10 @@ class AddWhenRemainingBranchesFix(
|
|||||||
(whenCloseBrace.prevSibling as? PsiWhiteSpace)?.replace(psiFactory.createNewLine())
|
(whenCloseBrace.prevSibling as? PsiWhiteSpace)?.replace(psiFactory.createNewLine())
|
||||||
for (case in missingCases) {
|
for (case in missingCases) {
|
||||||
val branchConditionText = when (case) {
|
val branchConditionText = when (case) {
|
||||||
WhenMissingCase.Unknown, WhenMissingCase.NullIsMissing, is WhenMissingCase.BooleanIsMissing ->
|
WhenMissingCase.Unknown,
|
||||||
case.branchConditionText
|
WhenMissingCase.NullIsMissing,
|
||||||
|
is WhenMissingCase.BooleanIsMissing,
|
||||||
|
is WhenMissingCase.ConditionTypeIsExpect -> case.branchConditionText
|
||||||
is WhenMissingCase.IsTypeCheckIsMissing ->
|
is WhenMissingCase.IsTypeCheckIsMissing ->
|
||||||
if (case.isSingleton) {
|
if (case.isSingleton) {
|
||||||
""
|
""
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ expect sealed class <!LINE_MARKER("descr='Is subclassed by CommonAImplTestClass
|
|||||||
class CommonImplTestClass: TestClass()
|
class CommonImplTestClass: TestClass()
|
||||||
|
|
||||||
|
|
||||||
fun checkCommon(t: TestClass): Int = when (t) {
|
fun checkCommon(t: TestClass): Int = <!EXPECT_TYPE_IN_WHEN_WITHOUT_ELSE, NO_ELSE_IN_WHEN!>when<!> (t) {
|
||||||
is CommonImplTestClass -> 0
|
is CommonImplTestClass -> 0
|
||||||
}
|
}
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+13
@@ -16457,6 +16457,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Exhaustiveness extends AbstractIrJsCodegenBoxES6Test {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+13
@@ -15942,6 +15942,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Exhaustiveness extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+13
@@ -16007,6 +16007,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Exhaustiveness extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+13
@@ -9833,6 +9833,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Exhaustiveness extends AbstractIrCodegenBoxWasmTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExhaustiveness() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/exhaustiveness"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user