Preserve sources properly for coroutine parts
Otherwise incremental reporting leads to exception when inlining into coroutine body happens
This commit is contained in:
@@ -84,11 +84,17 @@ class CoroutineCodegen(
|
|||||||
|
|
||||||
val resumeFunctionDescriptor =
|
val resumeFunctionDescriptor =
|
||||||
createSynthesizedImplementationByName(
|
createSynthesizedImplementationByName(
|
||||||
"resume", interfaceSupertype = continuationSuperType, implementationClass = classDescriptor)
|
"resume",
|
||||||
|
interfaceSupertype = continuationSuperType,
|
||||||
|
implementationClass = classDescriptor,
|
||||||
|
sourceElement = funDescriptor.source)
|
||||||
|
|
||||||
val resumeWithExceptionFunctionDescriptor =
|
val resumeWithExceptionFunctionDescriptor =
|
||||||
createSynthesizedImplementationByName(
|
createSynthesizedImplementationByName(
|
||||||
"resumeWithException", interfaceSupertype = continuationSuperType, implementationClass = classDescriptor)
|
"resumeWithException",
|
||||||
|
interfaceSupertype = continuationSuperType,
|
||||||
|
implementationClass = classDescriptor,
|
||||||
|
sourceElement = funDescriptor.source)
|
||||||
|
|
||||||
// private fun resume(result, throwable)
|
// private fun resume(result, throwable)
|
||||||
val combinedResumeFunctionDescriptor =
|
val combinedResumeFunctionDescriptor =
|
||||||
@@ -96,6 +102,7 @@ class CoroutineCodegen(
|
|||||||
.setVisibility(Visibilities.PRIVATE)
|
.setVisibility(Visibilities.PRIVATE)
|
||||||
.setName(Name.identifier("doResume"))
|
.setName(Name.identifier("doResume"))
|
||||||
.setCopyOverrides(false)
|
.setCopyOverrides(false)
|
||||||
|
.setPreserveSourceElement()
|
||||||
.setValueParameters(
|
.setValueParameters(
|
||||||
listOf(
|
listOf(
|
||||||
resumeFunctionDescriptor.valueParameters[0].copy(
|
resumeFunctionDescriptor.valueParameters[0].copy(
|
||||||
@@ -120,10 +127,11 @@ class CoroutineCodegen(
|
|||||||
private fun createSynthesizedImplementationByName(
|
private fun createSynthesizedImplementationByName(
|
||||||
name: String,
|
name: String,
|
||||||
interfaceSupertype: KotlinType,
|
interfaceSupertype: KotlinType,
|
||||||
implementationClass: ClassDescriptor
|
implementationClass: ClassDescriptor,
|
||||||
|
sourceElement: SourceElement
|
||||||
): SimpleFunctionDescriptor {
|
): SimpleFunctionDescriptor {
|
||||||
val inSuperType = interfaceSupertype.memberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
|
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)
|
result.setSingleOverridden(inSuperType)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -174,7 +182,7 @@ class CoroutineCodegen(
|
|||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val descriptorWithContinuationReturnType =
|
val descriptorWithContinuationReturnType =
|
||||||
originalCoroutineLambdaDescriptor.newCopyBuilder().setReturnType(continuationSupertype).build()!!
|
originalCoroutineLambdaDescriptor.newCopyBuilder().setPreserveSourceElement().setReturnType(continuationSupertype).build()!!
|
||||||
|
|
||||||
val state = expressionCodegen.state
|
val state = expressionCodegen.state
|
||||||
return CoroutineCodegen(
|
return CoroutineCodegen(
|
||||||
|
|||||||
+5
-4
@@ -55,7 +55,7 @@ class DeserializedSimpleFunctionDescriptor(
|
|||||||
) : DeserializedCallableMemberDescriptor,
|
) : DeserializedCallableMemberDescriptor,
|
||||||
SimpleFunctionDescriptorImpl(
|
SimpleFunctionDescriptorImpl(
|
||||||
containingDeclaration, original, annotations, name, kind,
|
containingDeclaration, original, annotations, name, kind,
|
||||||
source ?: org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE) {
|
source ?: SourceElement.NO_SOURCE) {
|
||||||
|
|
||||||
override fun createSubstitutedCopy(
|
override fun createSubstitutedCopy(
|
||||||
newOwner: DeclarationDescriptor,
|
newOwner: DeclarationDescriptor,
|
||||||
@@ -114,9 +114,10 @@ class DeserializedConstructorDescriptor(
|
|||||||
override val proto: ProtoBuf.Constructor,
|
override val proto: ProtoBuf.Constructor,
|
||||||
override val nameResolver: NameResolver,
|
override val nameResolver: NameResolver,
|
||||||
override val typeTable: TypeTable,
|
override val typeTable: TypeTable,
|
||||||
override val containerSource: SourceElement?
|
override val containerSource: SourceElement?,
|
||||||
|
source: SourceElement? = null
|
||||||
) : DeserializedCallableMemberDescriptor,
|
) : DeserializedCallableMemberDescriptor,
|
||||||
ConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, SourceElement.NO_SOURCE) {
|
ConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) {
|
||||||
|
|
||||||
override fun createSubstitutedCopy(
|
override fun createSubstitutedCopy(
|
||||||
newOwner: DeclarationDescriptor,
|
newOwner: DeclarationDescriptor,
|
||||||
@@ -128,7 +129,7 @@ class DeserializedConstructorDescriptor(
|
|||||||
): DeserializedConstructorDescriptor {
|
): DeserializedConstructorDescriptor {
|
||||||
return DeserializedConstructorDescriptor(
|
return DeserializedConstructorDescriptor(
|
||||||
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
|
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
|
||||||
proto, nameResolver, typeTable, source
|
proto, nameResolver, typeTable, containerSource, source
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -1124,6 +1124,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutine")
|
||||||
|
public void testCoroutine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/coroutine/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("function")
|
@TestMetadata("function")
|
||||||
public void testFunction() throws Exception {
|
public void testFunction() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/function/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/function/");
|
||||||
|
|||||||
+6
@@ -1124,6 +1124,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutine")
|
||||||
|
public void testCoroutine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/coroutine/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("function")
|
@TestMetadata("function")
|
||||||
public void testFunction() throws Exception {
|
public void testFunction() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/inlineFunCallSite/function/");
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user