diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java index 401c821afe7..ab5d409719d 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java @@ -58,6 +58,24 @@ public class Fe10IdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated exte runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_empty.kt"); } + @Test + @TestMetadata("boolean_noSubject.kt") + public void testBoolean_noSubject() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt"); + } + + @Test + @TestMetadata("boolean_noSubjectIncorrectCode.kt") + public void testBoolean_noSubjectIncorrectCode() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt"); + } + + @Test + @TestMetadata("boolean_noSubject_else.kt") + public void testBoolean_noSubject_else() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt"); + } + @Test @TestMetadata("boolean_partial.kt") public void testBoolean_partial() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleWhenMissingCasesTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleWhenMissingCasesTestGenerated.java index b0c842baacd..aa77c0cc0b4 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleWhenMissingCasesTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleWhenMissingCasesTestGenerated.java @@ -58,6 +58,24 @@ public class FirIdeDependentAnalysisSourceModuleWhenMissingCasesTestGenerated ex runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_empty.kt"); } + @Test + @TestMetadata("boolean_noSubject.kt") + public void testBoolean_noSubject() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt"); + } + + @Test + @TestMetadata("boolean_noSubjectIncorrectCode.kt") + public void testBoolean_noSubjectIncorrectCode() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt"); + } + + @Test + @TestMetadata("boolean_noSubject_else.kt") + public void testBoolean_noSubject_else() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt"); + } + @Test @TestMetadata("boolean_partial.kt") public void testBoolean_partial() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java index 383e8ea47e6..0a414215627 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java @@ -58,6 +58,24 @@ public class FirIdeNormalAnalysisSourceModuleWhenMissingCasesTestGenerated exten runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_empty.kt"); } + @Test + @TestMetadata("boolean_noSubject.kt") + public void testBoolean_noSubject() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt"); + } + + @Test + @TestMetadata("boolean_noSubjectIncorrectCode.kt") + public void testBoolean_noSubjectIncorrectCode() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt"); + } + + @Test + @TestMetadata("boolean_noSubject_else.kt") + public void testBoolean_noSubject_else() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt"); + } + @Test @TestMetadata("boolean_partial.kt") public void testBoolean_partial() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java index 0bea45a3e56..c0657fc5a01 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleWhenMissingCasesTestGenerated.java @@ -58,6 +58,24 @@ public class FirStandaloneNormalAnalysisSourceModuleWhenMissingCasesTestGenerate runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_empty.kt"); } + @Test + @TestMetadata("boolean_noSubject.kt") + public void testBoolean_noSubject() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt"); + } + + @Test + @TestMetadata("boolean_noSubjectIncorrectCode.kt") + public void testBoolean_noSubjectIncorrectCode() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt"); + } + + @Test + @TestMetadata("boolean_noSubject_else.kt") + public void testBoolean_noSubject_else() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt"); + } + @Test @TestMetadata("boolean_partial.kt") public void testBoolean_partial() throws Exception { diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionInfoProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionInfoProvider.kt index 450b8c3edbd..a130d48c2dd 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionInfoProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionInfoProvider.kt @@ -36,6 +36,15 @@ public interface KtExpressionInfoProviderMixIn : KtAnalysisSessionMixIn { * else -> 3 * } * + * If when-expression has no subject, then else-branch would be reported as missing even if it is explicitly present: + * + * fun test() { + * when { + * true -> {} + * else -> {} + * } + * } + * * Note that this function returns the same missing cases regardless of the existence of the else branch. * If you have to assume that it does not have the missing cases when it has an else branch, * you need a separate check whether it has an else branch or not. diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt new file mode 100644 index 00000000000..c80eb7576b7 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.kt @@ -0,0 +1,5 @@ +fun test() { + when { + true -> {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.txt new file mode 100644 index 00000000000..adb2a5ab3be --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject.txt @@ -0,0 +1 @@ +Unknown - else diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt new file mode 100644 index 00000000000..332e733f659 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.kt @@ -0,0 +1,5 @@ +fun test() { + when() { + true -> {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.txt new file mode 100644 index 00000000000..adb2a5ab3be --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubjectIncorrectCode.txt @@ -0,0 +1 @@ +Unknown - else diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt new file mode 100644 index 00000000000..60f3e6711c1 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.kt @@ -0,0 +1,6 @@ +fun test() { + when { + true -> {} + else -> { } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.txt new file mode 100644 index 00000000000..adb2a5ab3be --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionInfoProvider/whenMissingCases/boolean_noSubject_else.txt @@ -0,0 +1 @@ +Unknown - else diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index 54abf86f4f6..3fb6e8bb149 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.enumWhenTracker import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.ExhaustivenessStatus.NotExhaustive import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.reportEnumUsageInWhen import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents @@ -43,7 +44,8 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe ) fun computeAllMissingCases(session: FirSession, whenExpression: FirWhenExpression): List { - val subjectType = getSubjectType(session, whenExpression) ?: return emptyList() + val subjectType = + getSubjectType(session, whenExpression) ?: return NotExhaustive.NO_ELSE_BRANCH.reasons return buildList { for (type in subjectType.unwrapIntersectionType()) { val checkers = getCheckers(type, session)