Data flow information is no longer dropped while analyzing object literal expression. #KT-6293 Fixed. #KT-7110 Fixed.

A set of tests for KT-6293 / KT-7110 provided.
This commit is contained in:
Mikhail Glukhikh
2015-05-19 12:00:20 +03:00
parent 5bca1d3c8f
commit c8aa6defb6
19 changed files with 328 additions and 10 deletions
@@ -0,0 +1,19 @@
// See KT-6293: Smart cast doesn't work after object literal
abstract class Runnable {
abstract fun run()
}
fun foo(): Int {
val c: Int? = null
if (c is Int) {
var k: Runnable
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
k = object: Runnable() {
override fun run() = Unit
}
// Unnecessary but not important smart cast
<!DEBUG_INFO_SMARTCAST!>k<!>.run()
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
}
else return -1
}
@@ -0,0 +1,11 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,19 @@
// See KT-6293: Smart cast doesn't work after object literal
abstract class Runnable {
abstract fun run()
}
fun foo(): Int {
val c: Int? = null
if (c is Int) {
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
// This object breaks data flow info propagation
val k = object: Runnable() {
override fun run() = Unit
}
k.run()
// Smart cast should work but error is reported
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
}
else return -1
}
@@ -0,0 +1,11 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,22 @@
abstract class Runnable {
abstract fun run()
}
fun foo(): Int {
val c: Int? = null
var a: Int?
if (c is Int) {
a = 2
val k = object: Runnable() {
init {
a = null
}
override fun run() = Unit
}
k.run()
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
// a is captured so smart cast is not possible
return d + <!SMARTCAST_IMPOSSIBLE!>a<!>
}
else return -1
}
@@ -0,0 +1,11 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,21 @@
abstract class Runnable {
abstract fun run()
}
fun foo(): Int {
val c: Int? = null
val a: Int? = 1
if (c is Int) {
val k = object: Runnable() {
init {
a!!.toInt()
}
override fun run() = Unit
}
k.run()
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
// a is not null because of k constructor, but we do not know it
return a <!UNSAFE_INFIX_CALL!>+<!> d
}
else return -1
}
@@ -0,0 +1,11 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,17 @@
abstract class Runnable(val arg: Int) {
abstract fun run(): Int
}
fun foo(): Int {
val c: Int? = null
val a: Int? = 1
if (c is Int) {
val k = object: Runnable(a!!) {
override fun run() = arg
}
k.run()
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
return <!DEBUG_INFO_SMARTCAST!>a<!> + d
}
else return -1
}
@@ -0,0 +1,12 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable(/*0*/ arg: kotlin.Int)
internal final val arg: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,21 @@
abstract class Runnable(val arg: Int) {
abstract fun run(): Int
}
interface Wrapper {
fun run(): Int
}
fun foo(): Int {
val c: Int? = null
val a: Int? = 1
if (c is Int) {
val k = object: Wrapper, Runnable(a!!) {
override fun run() = arg
}
k.run()
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
return <!DEBUG_INFO_SMARTCAST!>a<!> + d
}
else return -1
}
@@ -0,0 +1,19 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable(/*0*/ arg: kotlin.Int)
internal final val arg: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal interface Wrapper {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,11 @@
// Anonymous object's initialization does not affect smart casts
abstract class A(val s: String) {
fun bar(): String = s
}
fun foo(o: String?): Int {
val a = object : A(o!!){}
a.bar()
return <!DEBUG_INFO_SMARTCAST!>o<!>.length()
}
@@ -0,0 +1,12 @@
package
internal fun foo(/*0*/ o: kotlin.String?): kotlin.Int
internal abstract class A {
public constructor A(/*0*/ s: kotlin.String)
internal final val s: kotlin.String
internal final fun bar(): kotlin.String
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
}
@@ -0,0 +1,16 @@
// See KT-6293: Smart cast doesn't work after object literal
abstract class Runnable {
abstract fun run()
}
fun foo(): Int {
val c: Int? = null
if (c is Int) {
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
object: Runnable() {
override fun run() = Unit
}.run()
return <!DEBUG_INFO_SMARTCAST!>c<!> + d
}
else return -1
}
@@ -0,0 +1,11 @@
package
internal fun foo(): kotlin.Int
internal abstract class Runnable {
public constructor Runnable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}