diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/AbstractKtFe10WhenMissingCasesTest.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/AbstractKtFe10WhenMissingCasesTest.kt new file mode 100644 index 00000000000..e3726c2bcd1 --- /dev/null +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/AbstractKtFe10WhenMissingCasesTest.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.descriptors.test.components + +import org.jetbrains.kotlin.analysis.api.descriptors.test.KtFe10FrontendApiTestConfiguratorService +import org.jetbrains.kotlin.analysis.api.impl.base.test.components.AbstractWhenMissingCasesTest + +abstract class AbstractKtFe10WhenMissingCasesTest : AbstractWhenMissingCasesTest(KtFe10FrontendApiTestConfiguratorService) \ No newline at end of file diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/KtFe10WhenMissingCasesTestGenerated.java b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/KtFe10WhenMissingCasesTestGenerated.java new file mode 100644 index 00000000000..4c891e48378 --- /dev/null +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/KtFe10WhenMissingCasesTestGenerated.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.descriptors.test.components; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/whenMissingCases") +@TestDataPath("$PROJECT_ROOT") +public class KtFe10WhenMissingCasesTestGenerated extends AbstractKtFe10WhenMissingCasesTest { + @Test + public void testAllFilesPresentInWhenMissingCases() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/whenMissingCases"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("boolean_else.kt") + public void testBoolean_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_else.kt"); + } + + @Test + @TestMetadata("boolean_empty.kt") + public void testBoolean_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.kt"); + } + + @Test + @TestMetadata("boolean_partial.kt") + public void testBoolean_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.kt"); + } + + @Test + @TestMetadata("enum_else.kt") + public void testEnum_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_else.kt"); + } + + @Test + @TestMetadata("enum_empty.kt") + public void testEnum_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_empty.kt"); + } + + @Test + @TestMetadata("enum_partial.kt") + public void testEnum_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_partial.kt"); + } + + @Test + @TestMetadata("nothing.kt") + public void testNothing() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nothing.kt"); + } + + @Test + @TestMetadata("nullableBoolean.kt") + public void testNullableBoolean() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.kt"); + } + + @Test + @TestMetadata("nullableEnum.kt") + public void testNullableEnum() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.kt"); + } + + @Test + @TestMetadata("nullableNothing.kt") + public void testNullableNothing() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.kt"); + } + + @Test + @TestMetadata("nullableSealedClass_empty.kt") + public void testNullableSealedClass_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.kt"); + } + + @Test + @TestMetadata("sealedClass_else.kt") + public void testSealedClass_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.kt"); + } + + @Test + @TestMetadata("sealedClass_empty.kt") + public void testSealedClass_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.kt"); + } + + @Test + @TestMetadata("sealedClass_partial.kt") + public void testSealedClass_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.kt"); + } +} diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractFirWhenMissingCasesTest.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractFirWhenMissingCasesTest.kt new file mode 100644 index 00000000000..b0848389f50 --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractFirWhenMissingCasesTest.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.components + +import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService +import org.jetbrains.kotlin.analysis.api.impl.base.test.components.AbstractWhenMissingCasesTest + +abstract class AbstractFirWhenMissingCasesTest : AbstractWhenMissingCasesTest(FirFrontendApiTestConfiguratorService) \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/FirWhenMissingCasesTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/FirWhenMissingCasesTestGenerated.java new file mode 100644 index 00000000000..5ddd865864f --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/FirWhenMissingCasesTestGenerated.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.components; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/whenMissingCases") +@TestDataPath("$PROJECT_ROOT") +public class FirWhenMissingCasesTestGenerated extends AbstractFirWhenMissingCasesTest { + @Test + public void testAllFilesPresentInWhenMissingCases() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/whenMissingCases"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("boolean_else.kt") + public void testBoolean_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_else.kt"); + } + + @Test + @TestMetadata("boolean_empty.kt") + public void testBoolean_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.kt"); + } + + @Test + @TestMetadata("boolean_partial.kt") + public void testBoolean_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.kt"); + } + + @Test + @TestMetadata("enum_else.kt") + public void testEnum_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_else.kt"); + } + + @Test + @TestMetadata("enum_empty.kt") + public void testEnum_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_empty.kt"); + } + + @Test + @TestMetadata("enum_partial.kt") + public void testEnum_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/enum_partial.kt"); + } + + @Test + @TestMetadata("nothing.kt") + public void testNothing() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nothing.kt"); + } + + @Test + @TestMetadata("nullableBoolean.kt") + public void testNullableBoolean() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.kt"); + } + + @Test + @TestMetadata("nullableEnum.kt") + public void testNullableEnum() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.kt"); + } + + @Test + @TestMetadata("nullableNothing.kt") + public void testNullableNothing() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.kt"); + } + + @Test + @TestMetadata("nullableSealedClass_empty.kt") + public void testNullableSealedClass_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.kt"); + } + + @Test + @TestMetadata("sealedClass_else.kt") + public void testSealedClass_else() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.kt"); + } + + @Test + @TestMetadata("sealedClass_empty.kt") + public void testSealedClass_empty() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.kt"); + } + + @Test + @TestMetadata("sealedClass_partial.kt") + public void testSealedClass_partial() throws Exception { + runTest("analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.kt"); + } +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/AbstractWhenMissingCasesTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/AbstractWhenMissingCasesTest.kt new file mode 100644 index 00000000000..9075557b99a --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/AbstractWhenMissingCasesTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.impl.base.test.components + +import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService +import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider +import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleFileTest +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtWhenExpression +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.assertions + +abstract class AbstractWhenMissingCasesTest( + configurator: FrontendApiTestConfiguratorService +) : AbstractHLApiSingleFileTest(configurator) { + override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { + super.doTestByFileStructure(ktFile, module, testServices) + + val whenExpression = testServices.expressionMarkerProvider.getElementOfTypAtCaret(ktFile) + + val actual = executeOnPooledThreadInReadAction { + analyseForTest(whenExpression) { + buildString { + for (missingCase in whenExpression.getMissingCases()) { + appendLine(missingCase::class.simpleName + " - " + missingCase.branchConditionText) + } + } + } + } + + testServices.assertions.assertEqualsToFile(testDataFileSibling(".txt"), actual) + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.kt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.kt new file mode 100644 index 00000000000..e49cdde4401 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.kt @@ -0,0 +1,5 @@ +fun test(b: Boolean) { + when(b) { + else -> {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.txt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.txt new file mode 100644 index 00000000000..8876194c620 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_else.txt @@ -0,0 +1,2 @@ +True - true +False - false diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.kt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.kt new file mode 100644 index 00000000000..b2b3cc92a4f --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.kt @@ -0,0 +1,4 @@ +fun test(b: Boolean) { + when(b) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.txt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.txt new file mode 100644 index 00000000000..8876194c620 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_empty.txt @@ -0,0 +1,2 @@ +True - true +False - false diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.kt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.kt new file mode 100644 index 00000000000..a4a7020148a --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.kt @@ -0,0 +1,5 @@ +fun test(b: Boolean) { + when(b) { + true -> {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.txt b/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.txt new file mode 100644 index 00000000000..57a52cb1aeb --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/boolean_partial.txt @@ -0,0 +1 @@ +False - false diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_else.kt b/analysis/analysis-api/testData/components/whenMissingCases/enum_else.kt new file mode 100644 index 00000000000..b7936459b10 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_else.kt @@ -0,0 +1,9 @@ +enum class MyEnum { + A, B, C +} + +fun test(e: MyEnum) { + when (e) { + else -> {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_else.txt b/analysis/analysis-api/testData/components/whenMissingCases/enum_else.txt new file mode 100644 index 00000000000..459033a34de --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_else.txt @@ -0,0 +1,3 @@ +EnumCheckIsMissing - MyEnum.A +EnumCheckIsMissing - MyEnum.B +EnumCheckIsMissing - MyEnum.C diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.kt b/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.kt new file mode 100644 index 00000000000..06d31843885 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.kt @@ -0,0 +1,8 @@ +enum class MyEnum { + A, B, C +} + +fun test(e: MyEnum) { + when (e) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.txt b/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.txt new file mode 100644 index 00000000000..459033a34de --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_empty.txt @@ -0,0 +1,3 @@ +EnumCheckIsMissing - MyEnum.A +EnumCheckIsMissing - MyEnum.B +EnumCheckIsMissing - MyEnum.C diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.kt b/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.kt new file mode 100644 index 00000000000..a33beef8cf3 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.kt @@ -0,0 +1,9 @@ +enum class MyEnum { + A, B, C +} + +fun test(e: MyEnum) { + when (e) { + MyEnum.A -> {} + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.txt b/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.txt new file mode 100644 index 00000000000..2687cd60ee4 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/enum_partial.txt @@ -0,0 +1,2 @@ +EnumCheckIsMissing - MyEnum.B +EnumCheckIsMissing - MyEnum.C diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nothing.kt b/analysis/analysis-api/testData/components/whenMissingCases/nothing.kt new file mode 100644 index 00000000000..97ad9326bfa --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nothing.kt @@ -0,0 +1,4 @@ +fun test(n: Nothing) { + when (n) { + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nothing.txt b/analysis/analysis-api/testData/components/whenMissingCases/nothing.txt new file mode 100644 index 00000000000..adb2a5ab3be --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nothing.txt @@ -0,0 +1 @@ +Unknown - else diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.kt b/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.kt new file mode 100644 index 00000000000..7880292887d --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.kt @@ -0,0 +1,4 @@ +fun test(b: Boolean?) { + when(b) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.txt b/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.txt new file mode 100644 index 00000000000..1a624075a03 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableBoolean.txt @@ -0,0 +1,3 @@ +True - true +False - false +NullIsMissing - null diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.kt b/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.kt new file mode 100644 index 00000000000..e83da80f3fc --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.kt @@ -0,0 +1,8 @@ +enum class MyEnum { + A, B, C +} + +fun test(e: MyEnum?) { + when (e) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.txt b/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.txt new file mode 100644 index 00000000000..5c627942eac --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableEnum.txt @@ -0,0 +1,4 @@ +EnumCheckIsMissing - MyEnum.A +EnumCheckIsMissing - MyEnum.B +EnumCheckIsMissing - MyEnum.C +NullIsMissing - null diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.descriptors.txt b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.descriptors.txt new file mode 100644 index 00000000000..164f1987ac7 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.descriptors.txt @@ -0,0 +1 @@ +unknown - else diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.kt b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.kt new file mode 100644 index 00000000000..ec66cf2b516 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.kt @@ -0,0 +1,4 @@ +fun test(n: Nothing?) { + when (n) { + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.txt b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.txt new file mode 100644 index 00000000000..5f0c99e4736 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableNothing.txt @@ -0,0 +1 @@ +NullIsMissing - null diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.kt b/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.kt new file mode 100644 index 00000000000..008d798bf28 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.kt @@ -0,0 +1,9 @@ +sealed class Foo { + object A : Foo() + class B(val i: Int) : Foo() +} + +fun test(e: Foo?) { + when (e) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.txt b/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.txt new file mode 100644 index 00000000000..08ee575fc1f --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/nullableSealedClass_empty.txt @@ -0,0 +1,3 @@ +IsTypeCheckIsMissing - Foo.A +IsTypeCheckIsMissing - is Foo.B +NullIsMissing - null diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.kt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.kt new file mode 100644 index 00000000000..7ed96313925 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.kt @@ -0,0 +1,10 @@ +sealed class Foo { + object A : Foo() + class B(val i: Int) : Foo() +} + +fun test(e: Foo) { + when (e) { + else -> {} + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.txt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.txt new file mode 100644 index 00000000000..1d38ac8975e --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_else.txt @@ -0,0 +1,2 @@ +IsTypeCheckIsMissing - Foo.A +IsTypeCheckIsMissing - is Foo.B diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.kt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.kt new file mode 100644 index 00000000000..88426fffe07 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.kt @@ -0,0 +1,9 @@ +sealed class Foo { + object A : Foo() + class B(val i: Int) : Foo() +} + +fun test(e: Foo) { + when (e) { + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.txt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.txt new file mode 100644 index 00000000000..1d38ac8975e --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_empty.txt @@ -0,0 +1,2 @@ +IsTypeCheckIsMissing - Foo.A +IsTypeCheckIsMissing - is Foo.B diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.kt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.kt new file mode 100644 index 00000000000..d246e44147a --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.kt @@ -0,0 +1,10 @@ +sealed class Foo { + object A : Foo() + class B(val i: Int) : Foo() +} + +fun test(e: Foo) { + when (e) { + Foo.A -> {} + } +} diff --git a/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.txt b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.txt new file mode 100644 index 00000000000..c944d2bb1f1 --- /dev/null +++ b/analysis/analysis-api/testData/components/whenMissingCases/sealedClass_partial.txt @@ -0,0 +1 @@ +IsTypeCheckIsMissing - is Foo.B diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt index 8617af874e5..633b634a628 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt @@ -8,6 +8,14 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based import com.intellij.mock.MockProject import com.intellij.openapi.Disposable import org.jetbrains.kotlin.analysis.api.impl.barebone.test.projectModuleProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getResolveState +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor +import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.test.services.* class ModuleRegistrarPreAnalysisHandler( @@ -29,6 +37,24 @@ class ModuleRegistrarPreAnalysisHandler( val project = testServices.compilerConfigurationProvider.getProject(testModule) moduleInfoProvider.registerModuleInfo(project, testModule, ktFiles) (project as MockProject).registerTestServices(testModule, allKtFiles, testServices) + + // Manually process all inheritors of sealed classes so that SealedClassInheritorsProviderTestImpl can work correctly for tests. + // In the actual IDE, SealedClassInheritorsProviderIdeImpl works by finding inheritors from the index instead of do a + // preprocessing of all files. Therefore, the IDE does not rely on such a pre-analysis pass of all files in the module. + val projectStructureProvider = project.getService(ProjectStructureProvider::class.java) + val allFirFiles = mutableListOf() + ktFiles.forEach { (_, ktFile) -> + val ktModule = projectStructureProvider.getKtModuleForKtElement(ktFile) + val resolveState = ktModule.getResolveState(project) + allFirFiles.add(ktFile.getOrBuildFirFile(resolveState)) + } + allFirFiles.groupBy { it.moduleData.session }.forEach { (session, firFiles) -> + for (firFile in firFiles) { + firFile.ensureResolved(FirResolvePhase.TYPES) + } + val sealedProcessor = FirSealedClassInheritorsProcessor(session, ScopeSession()) + sealedProcessor.process(firFiles) + } } } } \ No newline at end of file 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 959fbf78e88..1fa7cbba13c 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 @@ -245,12 +245,12 @@ private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker() ) { val flags = Flags() whenExpression.accept(ConditionChecker, flags) - if (!flags.containsFalse) { - destination.add(WhenMissingCase.BooleanIsMissing.False) - } if (!flags.containsTrue) { destination.add(WhenMissingCase.BooleanIsMissing.True) } + if (!flags.containsFalse) { + destination.add(WhenMissingCase.BooleanIsMissing.False) + } } private object ConditionChecker : AbstractConditionChecker() { diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateAnalysisApiTests.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateAnalysisApiTests.kt index b18da52e98b..beb75c7e425 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateAnalysisApiTests.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateAnalysisApiTests.kt @@ -5,8 +5,17 @@ package org.jetbrains.kotlin.generators.tests.analysis.api +import org.jetbrains.kotlin.analysis.api.descriptors.test.components.* +import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByFqNameTest +import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByReferenceTest import org.jetbrains.kotlin.analysis.api.fir.AbstractFirReferenceResolveTest import org.jetbrains.kotlin.analysis.api.fir.components.* +import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirDelegateMemberScopeTest +import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirFileScopeTest +import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirMemberScopeByFqNameTest +import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByFqNameTest +import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByPsiTest +import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByReferenceTest import org.jetbrains.kotlin.analysis.low.level.api.fir.* import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.AbstractDiagnosticTraversalCounterTest import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.AbstractFirContextCollectionTest @@ -14,23 +23,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataTest import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractFileStructureTest import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractInnerDeclarationsResolvePhaseTest +import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5 import org.jetbrains.kotlin.generators.util.TestGeneratorUtil -import org.jetbrains.kotlin.analysis.api.descriptors.test.components.* -import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByFqNameTest -import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByReferenceTest -import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirExpectedExpressionTypeTest -import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirHLExpressionTypeTest -import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirOverriddenDeclarationProviderTest -import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirRendererTest -import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirFileScopeTest -import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirMemberScopeByFqNameTest -import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByFqNameTest -import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByPsiTest -import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByReferenceTest -import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirDelegateMemberScopeTest import org.jetbrains.kotlin.spec.utils.GeneralConfiguration import org.jetbrains.kotlin.spec.utils.tasks.detectDirsWithTestsMapFileOnly -import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5 import org.jetbrains.kotlin.test.runners.AbstractFirDiagnosticTestSpec fun main(args: Array) { @@ -112,6 +108,10 @@ fun main(args: Array) { testClass { model("components/smartCastInfo") } + + testClass { + model("components/whenMissingCases") + } } testGroup("analysis/analysis-api-fe10/tests", "analysis/analysis-api/testData") { @@ -170,6 +170,10 @@ fun main(args: Array) { testClass { model("components/smartCastInfo") } + + testClass { + model("components/whenMissingCases") + } } testGroup("analysis/low-level-api-fir/tests", "compiler/fir/raw-fir/psi2fir/testData") {