Fix assignment codegen for suspend operators plus and plusAssign
KT-16079: Fixed
This commit is contained in:
@@ -2171,15 +2171,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
resolvedCall, state.getProject(), state.getBindingContext()
|
resolvedCall, state.getProject(), state.getBindingContext()
|
||||||
);
|
);
|
||||||
if (callWithRealDescriptor != null) {
|
if (callWithRealDescriptor != null) {
|
||||||
StackValue coroutineInstanceValueForSuspensionPoint = getCoroutineInstanceValueForSuspensionPoint(resolvedCall);
|
prepareCoroutineArgumentForSuspendCall(resolvedCall, callWithRealDescriptor.getFakeContinuationExpression());
|
||||||
StackValue coroutineInstanceValue =
|
|
||||||
coroutineInstanceValueForSuspensionPoint != null
|
|
||||||
? coroutineInstanceValueForSuspensionPoint
|
|
||||||
: getContinuationParameterFromEnclosingSuspendFunction(resolvedCall);
|
|
||||||
tempVariables.put(callWithRealDescriptor.getFakeContinuationExpression(), coroutineInstanceValue);
|
|
||||||
|
|
||||||
return invokeFunction(callWithRealDescriptor.getResolvedCall(), receiver);
|
return invokeFunction(callWithRealDescriptor.getResolvedCall(), receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
||||||
ClassDescriptor superCallTarget = getSuperCallTarget(call);
|
ClassDescriptor superCallTarget = getSuperCallTarget(call);
|
||||||
|
|
||||||
@@ -2199,6 +2194,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareCoroutineArgumentForSuspendCall(
|
||||||
|
@NotNull ResolvedCall<?> resolvedCall,
|
||||||
|
@NotNull KtExpression continuationExpression
|
||||||
|
) {
|
||||||
|
StackValue coroutineInstanceValueForSuspensionPoint = getCoroutineInstanceValueForSuspensionPoint(resolvedCall);
|
||||||
|
StackValue coroutineInstanceValue =
|
||||||
|
coroutineInstanceValueForSuspensionPoint != null
|
||||||
|
? coroutineInstanceValueForSuspensionPoint
|
||||||
|
: getContinuationParameterFromEnclosingSuspendFunction(resolvedCall);
|
||||||
|
tempVariables.put(continuationExpression, coroutineInstanceValue);
|
||||||
|
}
|
||||||
|
|
||||||
private StackValue getContinuationParameterFromEnclosingSuspendFunction(@NotNull ResolvedCall<?> resolvedCall) {
|
private StackValue getContinuationParameterFromEnclosingSuspendFunction(@NotNull ResolvedCall<?> resolvedCall) {
|
||||||
FunctionDescriptor enclosingSuspendFunction =
|
FunctionDescriptor enclosingSuspendFunction =
|
||||||
bindingContext.get(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.getCall());
|
bindingContext.get(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.getCall());
|
||||||
@@ -3405,6 +3412,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
private StackValue generateAugmentedAssignment(KtBinaryExpression expression) {
|
private StackValue generateAugmentedAssignment(KtBinaryExpression expression) {
|
||||||
return StackValue.operation(Type.VOID_TYPE, adapter -> {
|
return StackValue.operation(Type.VOID_TYPE, adapter -> {
|
||||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
|
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
|
||||||
|
|
||||||
|
ResolvedCallWithRealDescriptor callWithRealDescriptor =
|
||||||
|
CoroutineCodegenUtilKt.replaceSuspensionFunctionWithRealDescriptor(
|
||||||
|
resolvedCall, state.getProject(), state.getBindingContext()
|
||||||
|
);
|
||||||
|
if (callWithRealDescriptor != null) {
|
||||||
|
prepareCoroutineArgumentForSuspendCall(resolvedCall, callWithRealDescriptor.getFakeContinuationExpression());
|
||||||
|
resolvedCall = callWithRealDescriptor.getResolvedCall();
|
||||||
|
}
|
||||||
|
|
||||||
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
|
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
|
||||||
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
|
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
|
||||||
KtExpression lhs = expression.getLeft();
|
KtExpression lhs = expression.getLeft();
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import helpers.*
|
||||||
|
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun suspendThere(v: A): A = suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume(v)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(var value: String) {
|
||||||
|
operator suspend fun plus(other: A) = suspendThere(A(value + other.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun usePlusAssign(): A {
|
||||||
|
var a = A("O")
|
||||||
|
a += A("K")
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var a = A("")
|
||||||
|
builder { a = usePlusAssign() }
|
||||||
|
return a.value
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import helpers.*
|
||||||
|
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun suspendThere(v: A): A = suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume(v)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(var value: String) {
|
||||||
|
operator suspend fun plusAssign(other: A) {
|
||||||
|
value = suspendThere(A(value + other.value)).value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun usePlusAssign(): A {
|
||||||
|
var a = A("O")
|
||||||
|
a += A("K")
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var a = A("")
|
||||||
|
builder { a = usePlusAssign() }
|
||||||
|
return a.value
|
||||||
|
}
|
||||||
-2
@@ -1,9 +1,7 @@
|
|||||||
// IGNORE_BACKEND: JVM
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
import helpers.*
|
import helpers.*
|
||||||
|
|
||||||
// TODO: looks like this is a bug in JVM backend
|
|
||||||
import kotlin.coroutines.experimental.*
|
import kotlin.coroutines.experimental.*
|
||||||
import kotlin.coroutines.experimental.intrinsics.*
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
+18
-12
@@ -5938,6 +5938,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlus.kt")
|
||||||
|
public void testSuspendOperatorPlus() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlus.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusAssign.kt")
|
||||||
|
public void testSuspendOperatorPlusAssign() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusAssign.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusCallFromLambda.kt")
|
||||||
|
public void testSuspendOperatorPlusCallFromLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusCallFromLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("tailrec.kt")
|
@TestMetadata("tailrec.kt")
|
||||||
public void testTailrec() throws Exception {
|
public void testTailrec() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
||||||
@@ -6145,18 +6163,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("augmentedAssignment.kt")
|
|
||||||
public void testAugmentedAssignment() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/augmentedAssignment.kt");
|
|
||||||
try {
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("dispatchResume.kt")
|
@TestMetadata("dispatchResume.kt")
|
||||||
public void testDispatchResume() throws Exception {
|
public void testDispatchResume() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
||||||
|
|||||||
@@ -5938,6 +5938,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlus.kt")
|
||||||
|
public void testSuspendOperatorPlus() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlus.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusAssign.kt")
|
||||||
|
public void testSuspendOperatorPlusAssign() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusAssign.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusCallFromLambda.kt")
|
||||||
|
public void testSuspendOperatorPlusCallFromLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusCallFromLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("tailrec.kt")
|
@TestMetadata("tailrec.kt")
|
||||||
public void testTailrec() throws Exception {
|
public void testTailrec() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
||||||
@@ -6145,18 +6163,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("augmentedAssignment.kt")
|
|
||||||
public void testAugmentedAssignment() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/augmentedAssignment.kt");
|
|
||||||
try {
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("dispatchResume.kt")
|
@TestMetadata("dispatchResume.kt")
|
||||||
public void testDispatchResume() throws Exception {
|
public void testDispatchResume() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
||||||
|
|||||||
@@ -5938,6 +5938,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlus.kt")
|
||||||
|
public void testSuspendOperatorPlus() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlus.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusAssign.kt")
|
||||||
|
public void testSuspendOperatorPlusAssign() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusAssign.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusCallFromLambda.kt")
|
||||||
|
public void testSuspendOperatorPlusCallFromLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusCallFromLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("tailrec.kt")
|
@TestMetadata("tailrec.kt")
|
||||||
public void testTailrec() throws Exception {
|
public void testTailrec() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
||||||
@@ -6141,18 +6159,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class SuspendFunctionAsCoroutine extends AbstractLightAnalysisModeTest {
|
public static class SuspendFunctionAsCoroutine extends AbstractLightAnalysisModeTest {
|
||||||
@TestMetadata("augmentedAssignment.kt")
|
|
||||||
public void ignoreAugmentedAssignment() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/augmentedAssignment.kt");
|
|
||||||
try {
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInSuspendFunctionAsCoroutine() throws Exception {
|
public void testAllFilesPresentInSuspendFunctionAsCoroutine() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-6
@@ -6514,6 +6514,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlus.kt")
|
||||||
|
public void testSuspendOperatorPlus() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlus.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusAssign.kt")
|
||||||
|
public void testSuspendOperatorPlusAssign() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusAssign.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendOperatorPlusCallFromLambda.kt")
|
||||||
|
public void testSuspendOperatorPlusCallFromLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/suspendOperatorPlusCallFromLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("tailrec.kt")
|
@TestMetadata("tailrec.kt")
|
||||||
public void testTailrec() throws Exception {
|
public void testTailrec() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/featureIntersection/tailrec.kt");
|
||||||
@@ -6703,12 +6721,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("augmentedAssignment.kt")
|
|
||||||
public void testAugmentedAssignment() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/augmentedAssignment.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("dispatchResume.kt")
|
@TestMetadata("dispatchResume.kt")
|
||||||
public void testDispatchResume() throws Exception {
|
public void testDispatchResume() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/dispatchResume.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user