Preserve sources properly for coroutine parts

Otherwise incremental reporting leads to exception when inlining into coroutine body happens
This commit is contained in:
Denis Zharkov
2016-05-30 14:35:54 +03:00
parent 7dda2d9f62
commit 07592398c1
8 changed files with 82 additions and 9 deletions
@@ -84,11 +84,17 @@ class CoroutineCodegen(
val resumeFunctionDescriptor =
createSynthesizedImplementationByName(
"resume", interfaceSupertype = continuationSuperType, implementationClass = classDescriptor)
"resume",
interfaceSupertype = continuationSuperType,
implementationClass = classDescriptor,
sourceElement = funDescriptor.source)
val resumeWithExceptionFunctionDescriptor =
createSynthesizedImplementationByName(
"resumeWithException", interfaceSupertype = continuationSuperType, implementationClass = classDescriptor)
"resumeWithException",
interfaceSupertype = continuationSuperType,
implementationClass = classDescriptor,
sourceElement = funDescriptor.source)
// private fun resume(result, throwable)
val combinedResumeFunctionDescriptor =
@@ -96,6 +102,7 @@ class CoroutineCodegen(
.setVisibility(Visibilities.PRIVATE)
.setName(Name.identifier("doResume"))
.setCopyOverrides(false)
.setPreserveSourceElement()
.setValueParameters(
listOf(
resumeFunctionDescriptor.valueParameters[0].copy(
@@ -120,10 +127,11 @@ class CoroutineCodegen(
private fun createSynthesizedImplementationByName(
name: String,
interfaceSupertype: KotlinType,
implementationClass: ClassDescriptor
implementationClass: ClassDescriptor,
sourceElement: SourceElement
): SimpleFunctionDescriptor {
val inSuperType = interfaceSupertype.memberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
val result = inSuperType.newCopyBuilder().setOwner(implementationClass).setModality(Modality.FINAL).build()!!
val result = inSuperType.newCopyBuilder().setSource(sourceElement).setOwner(implementationClass).setModality(Modality.FINAL).build()!!
result.setSingleOverridden(inSuperType)
return result
@@ -174,7 +182,7 @@ class CoroutineCodegen(
} ?: return null
val descriptorWithContinuationReturnType =
originalCoroutineLambdaDescriptor.newCopyBuilder().setReturnType(continuationSupertype).build()!!
originalCoroutineLambdaDescriptor.newCopyBuilder().setPreserveSourceElement().setReturnType(continuationSupertype).build()!!
val state = expressionCodegen.state
return CoroutineCodegen(
@@ -55,7 +55,7 @@ class DeserializedSimpleFunctionDescriptor(
) : DeserializedCallableMemberDescriptor,
SimpleFunctionDescriptorImpl(
containingDeclaration, original, annotations, name, kind,
source ?: org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE) {
source ?: SourceElement.NO_SOURCE) {
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
@@ -114,9 +114,10 @@ class DeserializedConstructorDescriptor(
override val proto: ProtoBuf.Constructor,
override val nameResolver: NameResolver,
override val typeTable: TypeTable,
override val containerSource: SourceElement?
override val containerSource: SourceElement?,
source: SourceElement? = null
) : DeserializedCallableMemberDescriptor,
ConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, SourceElement.NO_SOURCE) {
ConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) {
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
@@ -128,7 +129,7 @@ class DeserializedConstructorDescriptor(
): DeserializedConstructorDescriptor {
return DeserializedConstructorDescriptor(
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
proto, nameResolver, typeTable, source
proto, nameResolver, typeTable, containerSource, source
)
}
@@ -1124,6 +1124,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
doTest(fileName);
}
@TestMetadata("coroutine")
public void testCoroutine() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/coroutine/");
doTest(fileName);
}
@TestMetadata("function")
public void testFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/function/");
@@ -1124,6 +1124,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
doTest(fileName);
}
@TestMetadata("coroutine")
public void testCoroutine() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/coroutine/");
doTest(fileName);
}
@TestMetadata("function")
public void testFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/function/");
@@ -0,0 +1,24 @@
================ Step #1 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/inline/InlineKt.class
End of files
Compiling files:
src/inline.kt
End of files
Marked as dirty by Kotlin:
src/usage.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/usage/Controller.class
out/production/module/usage/UsageKt$bar$1.class
out/production/module/usage/UsageKt.class
End of files
Compiling files:
src/usage.kt
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,5 @@
package inline
inline fun f(x: Int): Int {
return x - 1
}
@@ -0,0 +1,5 @@
package inline
inline fun f(x: Int): Int {
return x + 1
}
@@ -0,0 +1,18 @@
package usage
fun async(coroutine x: Controller.() -> Continuation<Unit>) {
x(Controller()).resume(Unit)
}
class Controller {
suspend fun step(param: Int, next: Continuation<Int>) {
next.resume(param + 1)
}
}
fun bar() {
async {
val result = step(1)
inline.f(result)
}
}