Resolve invoke on any kind of expressions, not only on simple name expressions
This commit is contained in:
@@ -14,11 +14,11 @@ L0:
|
||||
r(11)
|
||||
call(array[11], get)
|
||||
r(3)
|
||||
call(array[11], <for expression array[11]>)
|
||||
call(array[11], invoke)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -11,11 +11,11 @@ L0:
|
||||
mark((f)())
|
||||
mark((f))
|
||||
r(f)
|
||||
call((f), <for expression (f)>)
|
||||
call((f), invoke)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -7,12 +7,11 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ this() })
|
||||
mark(this())
|
||||
r(this)
|
||||
call(this, <for expression this>)
|
||||
call(this, invoke)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
class A
|
||||
|
||||
class B {
|
||||
fun A.invoke() = "##"
|
||||
fun A.invoke(i: Int) = "#${i}"
|
||||
}
|
||||
|
||||
fun foo() = A()
|
||||
|
||||
fun B.test(): String {
|
||||
if (A()() != "##") return "fail1"
|
||||
if (A()(1) != "#1") return "fail2"
|
||||
if (foo()() != "##") return "fail3"
|
||||
if (foo()(42) != "#42") return "fail4"
|
||||
if ((foo())(42) != "#42") return "fail5"
|
||||
if ({() -> A()}()() != "##") return "fail6"
|
||||
if ({() -> A()}()(37) != "#37") return "fail7"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun box(): String = B().test()
|
||||
@@ -0,0 +1,20 @@
|
||||
//KT-3217 Invoke convention after function invocation doesn't work
|
||||
//KT-2728 Can't compile A()()
|
||||
|
||||
class A {
|
||||
fun invoke() = "##"
|
||||
fun invoke(i: Int) = "#${i}"
|
||||
}
|
||||
|
||||
fun foo() = A()
|
||||
|
||||
fun box(): String {
|
||||
if (A()() != "##") return "fail1"
|
||||
if (A()(1) != "#1") return "fail2"
|
||||
if (foo()() != "##") return "fail3"
|
||||
if (foo()(42) != "#42") return "fail4"
|
||||
if ((foo())(42) != "#42") return "fail5"
|
||||
if ({() -> A()}()() != "##") return "fail6"
|
||||
if ({() -> A()}()(37) != "#37") return "fail7"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//KT-3450 get and invoke are not parsed in one expression
|
||||
|
||||
public class A(val s: String) {
|
||||
|
||||
public fun get(i: Int) : A = A("$s + $i")
|
||||
|
||||
public fun invoke(builder : A.() -> String): String = builder()
|
||||
}
|
||||
fun x(y : String) : A = A(y)
|
||||
|
||||
fun foo() = x("aaa")[42] { "$s!!" }
|
||||
|
||||
fun box() = if (foo() == "aaa + 42!!") "OK" else "fail"
|
||||
@@ -0,0 +1,5 @@
|
||||
//KT-3631 String.invoke doesn't work with literals
|
||||
|
||||
fun String.invoke(i: Int) = "$this$i"
|
||||
|
||||
fun box() = if ("a"(12) == "a12") "OK" else "fail"
|
||||
@@ -0,0 +1,21 @@
|
||||
//KT-3772 Invoke and overload resolution ambiguity
|
||||
|
||||
open class A {
|
||||
fun invoke(f: A.() -> Unit) = 1
|
||||
}
|
||||
|
||||
class B {
|
||||
fun invoke(f: B.() -> Unit) = 2
|
||||
}
|
||||
|
||||
open class C
|
||||
val C.attr = A()
|
||||
|
||||
open class D: C()
|
||||
val D.attr = B()
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val d = D()
|
||||
return if (d.attr {} == 2) "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
//KT-3821 Invoke convention doesn't work for `this`
|
||||
|
||||
class A() {
|
||||
fun invoke() = 42
|
||||
fun foo() = this() // Expecting a function type, but found A
|
||||
}
|
||||
|
||||
fun box() = if (A().foo() == 42) "OK" else "fail"
|
||||
@@ -0,0 +1,9 @@
|
||||
//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T>
|
||||
|
||||
class B() : Function0<Boolean> {
|
||||
override fun invoke() = true
|
||||
|
||||
fun foo() = this() // Exception
|
||||
}
|
||||
|
||||
fun box() = if (B().foo()) "OK" else "fail"
|
||||
@@ -7,4 +7,4 @@ class Z{
|
||||
}
|
||||
}
|
||||
|
||||
// 2 invoke \(LZ;I\)V
|
||||
// 1 invoke \(LZ;I\)V
|
||||
@@ -2,4 +2,4 @@ fun test() {
|
||||
1.{Int.() -> 2}()
|
||||
}
|
||||
|
||||
// 2 invoke \(I\)I
|
||||
// 1 invoke \(I\)I
|
||||
@@ -0,0 +1,23 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
public class A {
|
||||
public fun get(vararg attrs : Pair<String, String>) : A = this
|
||||
}
|
||||
fun String.plus() : A = A()
|
||||
fun A.div(s : String) : A = A()
|
||||
|
||||
fun test() {
|
||||
(+"node2" / "node3" / "zzz") ["attr" to "value", "a2" to "v2"]
|
||||
}
|
||||
|
||||
//---------
|
||||
class B {
|
||||
public fun get(s : String, q : String) : B = this
|
||||
public fun get(s : Pair<String, String>) : B = this
|
||||
public fun invoke(q : B.() -> Unit) : B = this
|
||||
}
|
||||
val x = B()["a", "v"]["a" to "b"] {} ["q" to "p"] // does not parses around {}
|
||||
|
||||
//from library
|
||||
data class Pair<out A, out B> (val first: A, val second: B)
|
||||
fun <A,B> A.to(that: B) = Pair(this, that)
|
||||
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun Int.invoke(i: Int, a: Any) {}
|
||||
fun Int.invoke(a: Any, i: Int) {}
|
||||
|
||||
fun foo(i: Int) {
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>i<!>(1, 1)
|
||||
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>5<!>(1, 2)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class My {
|
||||
private fun Int.invoke(s: String) {}
|
||||
}
|
||||
|
||||
fun My.foo(i: Int) {
|
||||
<!INVISIBLE_MEMBER!>i<!>("")
|
||||
<!INVISIBLE_MEMBER!>1<!>("")
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class A<T>
|
||||
|
||||
fun <T> T.invoke(a: A<T>) {}
|
||||
|
||||
fun foo(s: String, ai: A<Int>) {
|
||||
1(ai)
|
||||
|
||||
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>s<!>(ai)
|
||||
|
||||
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>""<!>(ai)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo(i: Int) {
|
||||
<!FUNCTION_EXPECTED!>i<!>()
|
||||
<!CALLEE_NOT_A_FUNCTION!>1<!>()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun String.invoke(i: Int) {}
|
||||
|
||||
fun foo(s: String?) {
|
||||
<!UNSAFE_CALL!>s<!>(1)
|
||||
|
||||
<!UNSAFE_CALL!>(s ?: null)<!>(1)
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun String.invoke(i: Int) {}
|
||||
|
||||
fun foo(i: Int) {
|
||||
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>i<!>(1)
|
||||
|
||||
<!CALLEE_NOT_A_FUNCTION!>1<!>(1)
|
||||
}
|
||||
Reference in New Issue
Block a user