diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 113779305b9..9a104f58f2d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -233,10 +233,7 @@ public class ClosureCodegen extends MemberCodegen { protected void generateKotlinMetadataAnnotation() { FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(funDescriptor); Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, funDescriptor); - - // Can be null for named suspend function - if (method == null) return; - + assert method != null : "No method for " + funDescriptor; v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method); final DescriptorSerializer serializer = diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index 6a95f8791ee..cca8ff3b679 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtDeclarationWithBody import org.jetbrains.kotlin.psi.KtElement @@ -43,6 +44,7 @@ import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.singletonOrEmptyList +import org.jetbrains.org.objectweb.asm.AnnotationVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type @@ -301,6 +303,17 @@ class CoroutineCodegen( ) } + override fun generateKotlinMetadataAnnotation() { + if (originalSuspendLambdaDescriptor != null) { + super.generateKotlinMetadataAnnotation() + } + else { + writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { + // Do not write method metadata for raw coroutine state machines + } + } + } + companion object { @JvmStatic diff --git a/compiler/testData/codegen/bytecodeListing/coroutineFields.txt b/compiler/testData/codegen/bytecodeListing/coroutineFields.txt index 9ff6a69ece4..f34bfcc8d48 100644 --- a/compiler/testData/codegen/bytecodeListing/coroutineFields.txt +++ b/compiler/testData/codegen/bytecodeListing/coroutineFields.txt @@ -1,3 +1,4 @@ +@kotlin.Metadata final class Controller$multipleSuspensions$1 { synthetic final field this$0: Controller inner class Controller$multipleSuspensions$1 @@ -5,6 +6,7 @@ final class Controller$multipleSuspensions$1 { public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object } +@kotlin.Metadata final class Controller$nonTailCall$1 { synthetic final field this$0: Controller inner class Controller$nonTailCall$1 diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java index a8546c42f6b..d6e877b8eee 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java @@ -918,6 +918,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta doTest(fileName); } + @TestMetadata("suspendWithStateMachine") + public void testSuspendWithStateMachine() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/"); + doTest(fileName); + } + @TestMetadata("topLevelFunctionSameSignature") public void testTopLevelFunctionSameSignature() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/topLevelFunctionSameSignature/"); diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java index 27b7e07f341..39d92ad1aca 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java @@ -918,6 +918,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest { doTest(fileName); } + @TestMetadata("suspendWithStateMachine") + public void testSuspendWithStateMachine() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/"); + doTest(fileName); + } + @TestMetadata("topLevelFunctionSameSignature") public void testTopLevelFunctionSameSignature() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/topLevelFunctionSameSignature/"); diff --git a/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/Counter.kt b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/Counter.kt new file mode 100644 index 00000000000..c43e7a6a7d9 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/Counter.kt @@ -0,0 +1,10 @@ +package test + +class Counter { + suspend fun one() {} + suspend fun two() {} + suspend fun both() { + one() + two() + } +} diff --git a/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/build.log b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/build.log new file mode 100644 index 00000000000..ce955a3768c --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/build.log @@ -0,0 +1,11 @@ +================ Step #1 ================= + +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test/OtherKt.class +End of files +Compiling files: + src/other.kt +End of files +Exit code: OK +------------------------------------------ diff --git a/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/other.kt b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/other.kt new file mode 100644 index 00000000000..092462c70e0 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/other.kt @@ -0,0 +1,4 @@ +package test + +fun dummyFunction() { +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/other.kt.touch b/jps-plugin/testData/incremental/pureKotlin/suspendWithStateMachine/other.kt.touch new file mode 100644 index 00000000000..e69de29bb2d