KT-3189 Function invoke is called with no reason
prioritize tasks specially for invoke #KT-3189 Fixed #KT-3190 Fixed #KT-3297 Fixed
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
//KT-3189 Function invoke is called with no reason
|
||||
|
||||
fun box(): String {
|
||||
|
||||
val bad = Bad({ 1 })
|
||||
|
||||
return if (bad.test() == 1) "OK" else "fail"
|
||||
}
|
||||
|
||||
class Bad(val a: () -> Int) {
|
||||
|
||||
fun test(): Int = a()
|
||||
|
||||
fun invoke(): Int = 2
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//KT-3190 Compiler crash if function called 'invoke' calls a closure
|
||||
|
||||
fun box(): String {
|
||||
val test = Cached<Int,Int>({ it + 2 })
|
||||
return if (test(1) == 3) "OK" else "fail"
|
||||
}
|
||||
|
||||
class Cached<K, V>(private val generate: (K)->V): jet.Function1<K, V> {
|
||||
val store = java.util.HashMap<K, V>()
|
||||
|
||||
// Everything works just fine if 'invoke' method is renamed to, for example, 'get'
|
||||
override fun invoke(p1: K) = store.getOrPut(p1) { generate(p1) }
|
||||
}
|
||||
|
||||
//from library
|
||||
fun <K,V> MutableMap<K,V>.getOrPut(key: K, defaultValue: ()-> V) : V {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key) as V
|
||||
} else {
|
||||
val answer = defaultValue()
|
||||
this.put(key, answer)
|
||||
return answer
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//KT-3297 Calling the wrong function inside an extension method to the Function0 class
|
||||
|
||||
fun <R> Function0<R>.or(alt: () -> R): R {
|
||||
try {
|
||||
return this()
|
||||
} catch (e: Exception) {
|
||||
return alt()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return {
|
||||
throw RuntimeException("fail")
|
||||
} or {
|
||||
"OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
class Foo {}
|
||||
|
||||
fun Foo.invoke() {}
|
||||
|
||||
//no variable
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait A {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
|
||||
fun test(a: A) {
|
||||
a.foo()
|
||||
|
||||
with (a) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as extension
|
||||
trait B {
|
||||
}
|
||||
val B.foo = Foo()
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait C
|
||||
|
||||
trait D {
|
||||
val C.foo: Foo
|
||||
|
||||
fun test(c: C) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(d: D, c: C) {
|
||||
with (d) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
@@ -0,0 +1,62 @@
|
||||
class Foo {
|
||||
fun invoke() {}
|
||||
}
|
||||
|
||||
//no variable
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait A {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
a.foo()
|
||||
|
||||
with (a) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as extension
|
||||
trait B {}
|
||||
val B.foo = Foo()
|
||||
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait C
|
||||
|
||||
trait D {
|
||||
val C.foo: Foo
|
||||
|
||||
fun test(c: C) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(d: D, c: C) {
|
||||
with (d) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
@@ -0,0 +1,125 @@
|
||||
class Foo
|
||||
|
||||
//no variable
|
||||
trait A {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait B {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
class C {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(c: C, b: B) {
|
||||
with (c) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//variable as extension,
|
||||
trait D {
|
||||
}
|
||||
val D.foo = Foo()
|
||||
|
||||
class E {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(d: D) {
|
||||
d.foo()
|
||||
|
||||
with (d) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(e: E, d: D) {
|
||||
with (e) {
|
||||
d.foo()
|
||||
|
||||
with (d) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait F
|
||||
|
||||
trait G {
|
||||
val F.foo: Foo
|
||||
fun Foo.invoke()
|
||||
|
||||
fun test(f: F) {
|
||||
f.foo()
|
||||
|
||||
with (f) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(g: G, f: F) {
|
||||
with (g) {
|
||||
f.foo()
|
||||
|
||||
with (f) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension (2)
|
||||
trait X
|
||||
|
||||
trait U {
|
||||
val X.foo: Foo
|
||||
}
|
||||
|
||||
trait V {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun U.test(x: X) {
|
||||
x.foo()
|
||||
|
||||
with (x) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(u: U, v: V, x: X) {
|
||||
with (v) {
|
||||
with (u) {
|
||||
x.foo()
|
||||
|
||||
with (x) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
trait A
|
||||
trait Foo {
|
||||
fun A.invoke()
|
||||
}
|
||||
|
||||
fun test(a: A, foo: Foo) {
|
||||
a.foo()
|
||||
}
|
||||
|
||||
fun test(a: Int, foo: Int.()->Unit) {
|
||||
a.foo()
|
||||
}
|
||||
Reference in New Issue
Block a user