KT-12152 : constructor consistency analysis, base cases

This commit is contained in:
Mikhail Glukhikh
2015-08-10 14:35:54 +03:00
parent 8544b9a1d6
commit 8e18165065
46 changed files with 751 additions and 24 deletions
@@ -0,0 +1,6 @@
class My(val x: Int) {
val y: Int = x + 3
val z: Int? = foo()
fun foo() = if (x >= 0) x else if (y >= 0) y else null
}
@@ -0,0 +1,12 @@
package
public final class My {
public constructor My(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final val y: kotlin.Int
public final val z: kotlin.Int?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,29 @@
fun foo() = 42
class Your {
fun bar() = 13
}
class My {
val your = Your()
val x = foo()
val y = Your().bar()
val z = your.bar()
// This extension function also can use our properties,
// so the call is also dangerous
val w = your.<!DEBUG_INFO_LEAKING_THIS!>gav<!>()
val v = Your().<!DEBUG_INFO_LEAKING_THIS!>gav<!>()
val t = your.other()
val r = Your().other()
fun Your.gav() = if (your.bar() == 0) t else r
}
fun Your.other() = "3"
@@ -0,0 +1,28 @@
package
public fun foo(): kotlin.Int
public fun Your.other(): kotlin.String
public final class My {
public constructor My()
public final val r: kotlin.String
public final val t: kotlin.String
public final val v: kotlin.String
public final val w: kotlin.String
public final val x: kotlin.Int
public final val y: kotlin.Int
public final val your: Your
public final val z: 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun Your.gav(): kotlin.String
}
public final class Your {
public constructor Your()
public final fun bar(): 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,11 @@
class My {
val x: String
constructor() {
val temp = <!DEBUG_INFO_LEAKING_THIS!>this<!>
x = bar(temp)
}
}
fun bar(arg: My) = arg.x
@@ -0,0 +1,11 @@
package
public fun bar(/*0*/ arg: My): kotlin.String
public final class My {
public constructor My()
public final val x: 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,13 @@
class My {
val x: String
constructor() {
val y = bar(<!DEBUG_INFO_LEAKING_THIS!>this<!>)
val z = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
x = "$y$z"
}
fun foo() = x
}
fun bar(arg: My) = arg.x
@@ -0,0 +1,12 @@
package
public fun bar(/*0*/ arg: My): kotlin.String
public final class My {
public constructor My()
public final val x: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,19 @@
class My {
val x = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
val w = bar()
fun foo() = 0
companion object {
val y = <!UNRESOLVED_REFERENCE!>foo<!>()
val u = <!DEBUG_INFO_LEAKING_THIS!>bar<!>()
val z: String? = bar()
fun bar() = "1"
}
}
@@ -0,0 +1,22 @@
package
public final class My {
public constructor My()
public final val w: kotlin.String
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public companion object Companion {
private constructor Companion()
public final val u: kotlin.String
public final val y: [ERROR : Type for foo()]
public final val z: kotlin.String?
public 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,10 @@
val instance = My()
class My {
val equalsInstance = (<!DEBUG_INFO_LEAKING_THIS!>this<!> == instance)
val isInstance = if (this === instance) "true" else "false"
override fun equals(other: Any?) =
other is My && isInstance.hashCode() == <!DEBUG_INFO_SMARTCAST!>other<!>.isInstance.hashCode()
}
@@ -0,0 +1,12 @@
package
public val instance: My
public final class My {
public constructor My()
public final val equalsInstance: kotlin.Boolean
public final val isInstance: kotlin.String
public open override /*1*/ 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,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.reflect.KProperty
class Delegate(val x: Int) {
operator fun getValue(t: Any?, p: KProperty<*>): Int = x
}
class My {
val x: Int by Delegate(this.foo())
fun foo(): Int = x
}
@@ -0,0 +1,19 @@
package
public final class Delegate {
public constructor Delegate(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final operator fun getValue(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.reflect.KProperty<*>): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class My {
public constructor My()
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,11 @@
open class Base(val x: String) {
fun foo() = bar()
open fun bar() = -1
}
class Derived(x: String): Base(x) {
// It's still dangerous: we're not sure that foo() does not call some open function inside
val y = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
val z = x
}
@@ -0,0 +1,23 @@
package
public open class Base {
public constructor Base(/*0*/ x: kotlin.String)
public final val x: kotlin.String
public open fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Derived : Base {
public constructor Derived(/*0*/ x: kotlin.String)
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val y: kotlin.Int
public final val z: kotlin.String
public open override /*1*/ /*fake_override*/ fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,9 @@
class My {
val x: String
init {
x = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
}
fun foo(): String = x
}
@@ -0,0 +1,10 @@
package
public final class My {
public constructor My()
public final val x: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,18 @@
interface Wise {
fun doIt(): Int
}
fun Wise(f: () -> Int) = object: Wise {
override fun doIt() = f()
}
class My {
// Still dangerous (???), nobogy can guarantee what Wise() will do with this lambda
val x = Wise { foo() }
val y = 42
fun foo() = y
fun bar() = x.doIt()
}
@@ -0,0 +1,21 @@
package
public fun Wise(/*0*/ f: () -> kotlin.Int): Wise
public final class My {
public constructor My()
public final val x: Wise
public final val y: kotlin.Int = 42
public final fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Wise {
public abstract fun doIt(): 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,15 @@
class WithLateInit {
lateinit var x: String
fun init(xx: String) {
x = xx
}
init {
// This is obviously a bug,
// but with lateinit we explicitly want it to occur in runtime
use()
}
fun use() = x
}
@@ -0,0 +1,11 @@
package
public final class WithLateInit {
public constructor WithLateInit()
public final lateinit var x: 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 final fun init(/*0*/ xx: kotlin.String): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun use(): kotlin.String
}
@@ -0,0 +1,19 @@
open class Wise {
val x = 1
open fun doIt(): Int = 42
}
class My {
fun foo(): Int {
val wise = object: Wise() {
var xx = 1
override fun doIt() = super.doIt() + bar(this) + xx
}
return wise.doIt()
}
}
fun bar(wise: Wise): Int = wise.x
@@ -0,0 +1,20 @@
package
public fun bar(/*0*/ wise: Wise): kotlin.Int
public final class My {
public constructor My()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class Wise {
public constructor Wise()
public final val x: kotlin.Int = 1
public open fun doIt(): 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,12 @@
class My {
val x: Int
get() = 1
init {
// x has no backing field, so the call is safe
foo()
}
fun foo() {}
}
@@ -0,0 +1,10 @@
package
public final class My {
public constructor My()
public final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,11 @@
class Outer {
fun foo() = 1
inner class Inner {
val x = this@Outer.foo()
val y = foo()
}
}
@@ -0,0 +1,18 @@
package
public final class Outer {
public constructor Outer()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final inner class Inner {
public constructor Inner()
public final val x: kotlin.Int
public final val y: 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,5 @@
class My(x: String) {
val y: String = <!DEBUG_INFO_LEAKING_THIS!>foo<!>(x)
fun foo(x: String) = "$x$y"
}
@@ -0,0 +1,10 @@
package
public final class My {
public constructor My(/*0*/ x: kotlin.String)
public final val y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(/*0*/ x: kotlin.String): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,7 @@
class My {
val x: Int
constructor(x: Int) {
this.x = x
}
}
@@ -0,0 +1,9 @@
package
public final class My {
public constructor My(/*0*/ x: kotlin.Int)
public final val x: 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
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}