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:
committed by
Alexander Udalov
parent
8bdb8ba232
commit
b7a7fce34e
+6
@@ -421,6 +421,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testSamLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendLambda.kt")
|
||||
public void testSuspendLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/suspendLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+2
@@ -254,6 +254,8 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
|
||||
}, null)
|
||||
context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET, localVals.filterNotNull() + body.statements)
|
||||
}
|
||||
|
||||
copyAnnotationsFrom(irFunction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
+6
@@ -403,6 +403,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testSamLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendLambda.kt")
|
||||
public void testSuspendLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/suspendLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -421,6 +421,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testSamLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendLambda.kt")
|
||||
public void testSuspendLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/suspendLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -322,6 +322,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AnnotatedLambda extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("suspendLambda.kt")
|
||||
public void ignoreSuspendLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedLambda/suspendLambda.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user