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
This commit is contained in:
Mikhail Glukhikh
2017-03-22 20:33:37 +03:00
parent 1cb4580380
commit 1780f7c9a2
6 changed files with 32 additions and 10 deletions
@@ -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<KotlinType>
@@ -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<KotlinType>
@@ -122,12 +122,12 @@ internal class DelegatingDataFlowInfo private constructor(
val enrichedTypes = newLinkedHashSetWithExpectedSize<KotlinType>(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
}
+14
View File
@@ -0,0 +1,14 @@
// See KT-15901
<info>enum</info> 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 = <info descr="Smart cast to En">en2</info>
return a
}
return ""
}
+6 -6
View File
@@ -15,7 +15,7 @@ fun f9(a : A?) {
a<info>?.</info><error descr="[UNRESOLVED_REFERENCE] Unresolved reference: bar">bar</error>()
if (a is B) {
<info descr="Smart cast to B">a</info>.bar()
<info descr="Smart cast to A">a</info>.foo()
<info descr="Smart cast to B">a</info>.foo()
}
a<info>?.</info>foo()
a<info>?.</info><error descr="[UNRESOLVED_REFERENCE] Unresolved reference: bar">bar</error>()
@@ -30,7 +30,7 @@ fun f9(a : A?) {
return;
}
<info descr="Smart cast to B">a</info>.bar()
<info descr="Smart cast to A">a</info>.foo()
<info descr="Smart cast to B">a</info>.foo()
}
fun fAny(a : Any?) {
@@ -96,7 +96,7 @@ fun f12(a : A?) {
fun f13(a : A?) {
if (a is B) {
<info descr="Smart cast to A">a</info>.foo()
<info descr="Smart cast to B">a</info>.foo()
<info descr="Smart cast to B">a</info>.bar()
}
else {
@@ -109,12 +109,12 @@ fun f13(a : A?) {
a<info>?.</info>foo()
}
else {
<info descr="Smart cast to A">a</info>.foo()
<info descr="Smart cast to B">a</info>.foo()
}
a<info>?.</info>foo()
if (a is B && <info descr="Smart cast to A">a</info>.foo() == Unit) {
<info descr="Smart cast to A">a</info>.foo()
if (a is B && <info descr="Smart cast to B">a</info>.foo() == Unit) {
<info descr="Smart cast to B">a</info>.foo()
<info descr="Smart cast to B">a</info>.bar()
}
else {
+1 -1
View File
@@ -16,7 +16,7 @@ fun test(a: A?) {
}
if (a is B && a is C) {
<info descr="Smart cast to A">a</info>.foo()
<info descr="Smart cast to B">a</info>.foo()
}
if (a is B? && a is C?) {
@@ -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");