From 1780f7c9a25ca21f4f98e4b2f24b5b991162d2f5 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 22 Mar 2017 20:33:37 +0300 Subject: [PATCH] Put not-null original type as last possible smart cast target This fixes muted tests testSmartCast (IDE highlighting) and testNestedSealed (Diagnostics). Together with commit 555b3f12 this makes #KT-15901 Fixed --- .../resolve/calls/smartcasts/DataFlowInfo.kt | 2 ++ .../calls/smartcasts/DelegatingDataFlowInfo.kt | 6 +++--- idea/testData/checker/infos/SmartCastTarget.kt | 14 ++++++++++++++ idea/testData/checker/infos/SmartCasts.kt | 12 ++++++------ .../checker/infos/SmartCastsWithSafeAccess.kt | 2 +- .../kotlin/checkers/PsiCheckerTestGenerated.java | 6 ++++++ 6 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 idea/testData/checker/infos/SmartCastTarget.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowInfo.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowInfo.kt index 01ee09571e4..b3f033290ce 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowInfo.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DataFlowInfo.kt @@ -46,6 +46,7 @@ interface DataFlowInfo { * * IMPORTANT: by default, the original (native) type for this value * are NOT included. So it's quite possible to get an empty set here. + * Also, type order in the result set MAKES SENSE so keep it stable and do not change without reason */ fun getCollectedTypes(key: DataFlowValue): Set @@ -55,6 +56,7 @@ interface DataFlowInfo { * * IMPORTANT: by default, the original (native) type for this value * are NOT included. So it's quite possible to get an empty set here. + * Also, type order in the result set MAKES SENSE so keep it stable and do not change without reason */ fun getStableTypes(key: DataFlowValue): Set diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt index 30c19e106fe..7a068811262 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt @@ -122,12 +122,12 @@ internal class DelegatingDataFlowInfo private constructor( val enrichedTypes = newLinkedHashSetWithExpectedSize(types.size + 1) val originalType = key.type - if (originalType.isMarkedNullable) { - enrichedTypes.add(TypeUtils.makeNotNullable(originalType)) - } for (type in types) { enrichedTypes.add(TypeUtils.makeNotNullable(type)) } + if (originalType.isMarkedNullable) { + enrichedTypes.add(TypeUtils.makeNotNullable(originalType)) + } return enrichedTypes } diff --git a/idea/testData/checker/infos/SmartCastTarget.kt b/idea/testData/checker/infos/SmartCastTarget.kt new file mode 100644 index 00000000000..7fc42156bfd --- /dev/null +++ b/idea/testData/checker/infos/SmartCastTarget.kt @@ -0,0 +1,14 @@ +// See KT-15901 + +enum class En { A } + +fun foo(): Any { + val en2: Any? = En.A + if (en2 is En) { + // Here we had smart casts to En / Any + // should be always En + val a: Any = en2 + return a + } + return "" +} \ No newline at end of file diff --git a/idea/testData/checker/infos/SmartCasts.kt b/idea/testData/checker/infos/SmartCasts.kt index 24ff66f5828..70f634e5a84 100644 --- a/idea/testData/checker/infos/SmartCasts.kt +++ b/idea/testData/checker/infos/SmartCasts.kt @@ -15,7 +15,7 @@ fun f9(a : A?) { a?.bar() if (a is B) { a.bar() - a.foo() + a.foo() } a?.foo() a?.bar() @@ -30,7 +30,7 @@ fun f9(a : A?) { return; } a.bar() - a.foo() + a.foo() } fun fAny(a : Any?) { @@ -96,7 +96,7 @@ fun f12(a : A?) { fun f13(a : A?) { if (a is B) { - a.foo() + a.foo() a.bar() } else { @@ -109,12 +109,12 @@ fun f13(a : A?) { a?.foo() } else { - a.foo() + a.foo() } a?.foo() - if (a is B && a.foo() == Unit) { - a.foo() + if (a is B && a.foo() == Unit) { + a.foo() a.bar() } else { diff --git a/idea/testData/checker/infos/SmartCastsWithSafeAccess.kt b/idea/testData/checker/infos/SmartCastsWithSafeAccess.kt index e4dcac1483f..e34b3f23323 100644 --- a/idea/testData/checker/infos/SmartCastsWithSafeAccess.kt +++ b/idea/testData/checker/infos/SmartCastsWithSafeAccess.kt @@ -16,7 +16,7 @@ fun test(a: A?) { } if (a is B && a is C) { - a.foo() + a.foo() } if (a is B? && a is C?) { diff --git a/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java index 921fddcd634..fd061bda154 100644 --- a/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/checkers/PsiCheckerTestGenerated.java @@ -917,6 +917,12 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest { doTestWithInfos(fileName); } + @TestMetadata("SmartCastTarget.kt") + public void testSmartCastTarget() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCastTarget.kt"); + doTestWithInfos(fileName); + } + @TestMetadata("SmartCastToEnum.kt") public void testSmartCastToEnum() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCastToEnum.kt");