Add suspend lambda annotations to invokeSuspend.

For non-suspend lambdas annotations are carried over to the
invoke method so that tooling can find the annotation there.
It seems reasonable that annotations are carried over to
the invokeSuspend method on suspend lambdas as well so that
similar tooling can be built and work for suspend lambdas.
This commit is contained in:
Mads Ager
2022-08-18 12:24:08 +02:00
committed by Alexander Udalov
parent 8bdb8ba232
commit b7a7fce34e
7 changed files with 71 additions and 3 deletions
@@ -27,8 +27,6 @@ fun testClass(clazz: Class<*>, name: String) {
fun box(): String {
testClass(foo0(@Ann("OK") { }), "1")
testClass(foo0( @Ann("OK") { }), "2")
testClass(foo0() @Ann("OK") { }, "3")
testClass(foo0() @Ann("OK") { }, "2")
return "OK"
}
@@ -0,0 +1,45 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
// Only implemented in the IR backend.
// IGNORE_BACKEND: JVM
import java.lang.reflect.Method
import kotlin.test.assertEquals
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Ann(val x: String)
fun foo0(block: suspend () -> Unit) = block.javaClass
fun testHasAnnotation(method: Method, name: String) {
assertEquals(
"OK",
method.getAnnotation(Ann::class.java)?.x,
"Missing or incorrect annotation on method `${method.name}` of test named `$name`"
)
}
fun testDoesNotHaveAnnotation(method: Method, name: String) {
assertEquals(
null,
method.getAnnotation(Ann::class.java),
"Unexpected annotation on method `${method.name}` of test named `$name`"
)
}
fun testClass(clazz: Class<*>, name: String) {
// Check that non-bridge `invokeSuspend` contains the suspend lambda annotation.
val invokeSuspends = clazz.getDeclaredMethods().filter { !it.isBridge() && it.name == "invokeSuspend" }
invokeSuspends.forEach { testHasAnnotation(it, name) }
// Check that non-bridge `invoke` does not contain the suspend lambda annotation.
val invokes = clazz.getDeclaredMethods().filter { !it.isBridge() && it.name == "invoke" }
invokes.forEach { testDoesNotHaveAnnotation(it, name) }
}
fun box(): String {
testClass(foo0(@Ann("OK") { }), "1")
testClass(foo0() @Ann("OK") { }, "2")
return "OK"
}