Support local suspend functions
Treat them like lambdas. This means: 1) Like local suspend lambdas, which become "non-suspend" after creating jvmSuspendView, they do this as well 2) They both are generated with the same codegen. 3) They are treated differently only on front-end side. #KT-20364: Fixed
This commit is contained in:
@@ -23,9 +23,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.kotlin.codegen.context.*;
|
import org.jetbrains.kotlin.codegen.context.*;
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenForLambda;
|
import org.jetbrains.kotlin.codegen.coroutines.*;
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor;
|
|
||||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||||
import org.jetbrains.kotlin.codegen.inline.*;
|
import org.jetbrains.kotlin.codegen.inline.*;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.*;
|
import org.jetbrains.kotlin.codegen.intrinsics.*;
|
||||||
@@ -1238,7 +1236,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public StackValue genCoroutineInstanceForSuspendLambda(@NotNull FunctionDescriptor suspendFunction) {
|
public StackValue genCoroutineInstanceForSuspendLambda(@NotNull FunctionDescriptor suspendFunction) {
|
||||||
if (!(suspendFunction instanceof AnonymousFunctionDescriptor)) return null;
|
if (!CoroutineCodegenUtilKt.isSuspendLambdaOrLocalFunction(suspendFunction)) return null;
|
||||||
|
|
||||||
ClassDescriptor suspendLambdaClassDescriptor = bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, suspendFunction);
|
ClassDescriptor suspendLambdaClassDescriptor = bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, suspendFunction);
|
||||||
assert suspendLambdaClassDescriptor != null : "Coroutine class descriptor should not be null";
|
assert suspendLambdaClassDescriptor != null : "Coroutine class descriptor should not be null";
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
|
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
|
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
@@ -704,6 +705,18 @@ public abstract class StackValue {
|
|||||||
return codegen.generateReceiverValue(receiverValue, false);
|
return codegen.generateReceiverValue(receiverValue, false);
|
||||||
}
|
}
|
||||||
else if (isLocalFunCall(callableMethod) && !isExtension) {
|
else if (isLocalFunCall(callableMethod) && !isExtension) {
|
||||||
|
if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||||
|
SimpleFunctionDescriptor initial =
|
||||||
|
CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction((SimpleFunctionDescriptor) descriptor);
|
||||||
|
if (initial != null && initial.isSuspend()) {
|
||||||
|
StackValue value = codegen.findLocalOrCapturedValue(initial.getOriginal());
|
||||||
|
assert value != null : "Local suspend fun should be found in locals or in captured params: " +
|
||||||
|
descriptor +
|
||||||
|
" initial local suspend fun: " +
|
||||||
|
initial;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
StackValue value = codegen.findLocalOrCapturedValue(descriptor.getOriginal());
|
StackValue value = codegen.findLocalOrCapturedValue(descriptor.getOriginal());
|
||||||
assert value != null : "Local fun should be found in locals or in captured params: " + descriptor;
|
assert value != null : "Local fun should be found in locals or in captured params: " + descriptor;
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
+22
-3
@@ -506,7 +506,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
|
|
||||||
String nameForClassOrPackageMember = getNameForClassOrPackageMember(functionDescriptor);
|
String nameForClassOrPackageMember = getNameForClassOrPackageMember(functionDescriptor);
|
||||||
|
|
||||||
if (functionDescriptor instanceof SimpleFunctionDescriptor && functionDescriptor.isSuspend()) {
|
if (functionDescriptor instanceof SimpleFunctionDescriptor && functionDescriptor.isSuspend() &&
|
||||||
|
!functionDescriptor.getVisibility().equals(Visibilities.LOCAL)) {
|
||||||
SimpleFunctionDescriptor jvmSuspendFunctionView =
|
SimpleFunctionDescriptor jvmSuspendFunctionView =
|
||||||
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(
|
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(
|
||||||
(SimpleFunctionDescriptor) functionDescriptor
|
(SimpleFunctionDescriptor) functionDescriptor
|
||||||
@@ -563,11 +564,29 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
|||||||
else {
|
else {
|
||||||
String name = inventAnonymousClassName();
|
String name = inventAnonymousClassName();
|
||||||
ClassDescriptor classDescriptor = recordClassForFunction(function, functionDescriptor, name, null);
|
ClassDescriptor classDescriptor = recordClassForFunction(function, functionDescriptor, name, null);
|
||||||
recordClosure(classDescriptor, name);
|
MutableClosure closure = recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
classStack.push(classDescriptor);
|
classStack.push(classDescriptor);
|
||||||
functionsStack.push(functionDescriptor);
|
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
|
|
||||||
|
if (functionDescriptor instanceof SimpleFunctionDescriptor && functionDescriptor.isSuspend()) {
|
||||||
|
SimpleFunctionDescriptor jvmSuspendFunctionView =
|
||||||
|
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(
|
||||||
|
(SimpleFunctionDescriptor) functionDescriptor,
|
||||||
|
/*bindingContext*/ null,
|
||||||
|
/*dropSuspend*/ true
|
||||||
|
);
|
||||||
|
|
||||||
|
bindingTrace.record(
|
||||||
|
CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW,
|
||||||
|
functionDescriptor,
|
||||||
|
jvmSuspendFunctionView
|
||||||
|
);
|
||||||
|
closure.setSuspend(true);
|
||||||
|
closure.setSuspendLambda();
|
||||||
|
}
|
||||||
|
|
||||||
|
functionsStack.push(functionDescriptor);
|
||||||
super.visitNamedFunction(function);
|
super.visitNamedFunction(function);
|
||||||
functionsStack.pop();
|
functionsStack.pop();
|
||||||
nameStack.pop();
|
nameStack.pop();
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
@@ -330,7 +327,7 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
declaration: KtElement,
|
declaration: KtElement,
|
||||||
classBuilder: ClassBuilder
|
classBuilder: ClassBuilder
|
||||||
): ClosureCodegen? {
|
): ClosureCodegen? {
|
||||||
if (declaration !is KtFunctionLiteral || !originalSuspendLambdaDescriptor.isSuspendLambda) return null
|
if (!originalSuspendLambdaDescriptor.isSuspendLambdaOrLocalFunction()) return null
|
||||||
|
|
||||||
return CoroutineCodegenForLambda(
|
return CoroutineCodegenForLambda(
|
||||||
expressionCodegen,
|
expressionCodegen,
|
||||||
|
|||||||
+17
-2
@@ -26,8 +26,10 @@ import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker
|
|||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.codegen.topLevelClassAsmType
|
import org.jetbrains.kotlin.codegen.topLevelClassAsmType
|
||||||
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
|
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
|
||||||
|
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -182,7 +184,7 @@ fun ResolvedCall<*>.isSuspendNoInlineCall(codegen: ExpressionCodegen): Boolean {
|
|||||||
?.let { it.isCrossinline || (!it.isNoinline && codegen.context.functionDescriptor.isInline) } == true
|
?.let { it.isCrossinline || (!it.isNoinline && codegen.context.functionDescriptor.isInline) } == true
|
||||||
|
|
||||||
val functionDescriptor = resultingDescriptor as? FunctionDescriptor ?: return false
|
val functionDescriptor = resultingDescriptor as? FunctionDescriptor ?: return false
|
||||||
if (!functionDescriptor.isSuspend) return false
|
if (!functionDescriptor.unwrapInitialDescriptorForSuspendFunction().isSuspend) return false
|
||||||
if (functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() || functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) return true
|
if (functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() || functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) return true
|
||||||
return !(functionDescriptor.isInline || isInlineLambda)
|
return !(functionDescriptor.isInline || isInlineLambda)
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,11 @@ fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
|
|||||||
// and return type Any?
|
// and return type Any?
|
||||||
// This function returns a function descriptor reflecting how the suspend function looks from point of view of JVM
|
// This function returns a function descriptor reflecting how the suspend function looks from point of view of JVM
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, bindingContext: BindingContext? = null): D {
|
fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||||
|
function: D,
|
||||||
|
bindingContext: BindingContext? = null,
|
||||||
|
dropSuspend: Boolean = false
|
||||||
|
): D {
|
||||||
assert(function.isSuspend) {
|
assert(function.isSuspend) {
|
||||||
"Suspended function is expected, but $function was found"
|
"Suspended function is expected, but $function was found"
|
||||||
}
|
}
|
||||||
@@ -220,6 +226,9 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, bind
|
|||||||
setPreserveSourceElement()
|
setPreserveSourceElement()
|
||||||
setReturnType(function.builtIns.nullableAnyType)
|
setReturnType(function.builtIns.nullableAnyType)
|
||||||
setValueParameters(it.valueParameters + continuationParameter)
|
setValueParameters(it.valueParameters + continuationParameter)
|
||||||
|
if (dropSuspend) {
|
||||||
|
setDropSuspend()
|
||||||
|
}
|
||||||
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it)
|
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,3 +442,9 @@ fun InstructionAdapter.invokeDoResumeWithUnit(thisName: String) {
|
|||||||
|
|
||||||
fun Method.getImplForOpenMethod(ownerInternalName: String) =
|
fun Method.getImplForOpenMethod(ownerInternalName: String) =
|
||||||
Method("$name\$suspendImpl", returnType, arrayOf(Type.getObjectType(ownerInternalName)) + argumentTypes)
|
Method("$name\$suspendImpl", returnType, arrayOf(Type.getObjectType(ownerInternalName)) + argumentTypes)
|
||||||
|
|
||||||
|
fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when (this) {
|
||||||
|
is AnonymousFunctionDescriptor -> this.isSuspendLambda
|
||||||
|
is SimpleFunctionDescriptor -> this.visibility == Visibilities.LOCAL
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
@@ -170,7 +170,8 @@ public class KotlinTypeMapper {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean publicFacade) {
|
private Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean publicFacade) {
|
||||||
if (isLocalFunction(descriptor)) {
|
if (isLocalFunction(descriptor)) {
|
||||||
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
|
return asmTypeForAnonymousClass(bindingContext,
|
||||||
|
CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction((FunctionDescriptor) descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof ConstructorDescriptor) {
|
if (descriptor instanceof ConstructorDescriptor) {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ object ModifierCheckerCore {
|
|||||||
INLINE_KEYWORD to EnumSet.of(FUNCTION, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, CLASS_ONLY),
|
INLINE_KEYWORD to EnumSet.of(FUNCTION, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, CLASS_ONLY),
|
||||||
NOINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
NOINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
||||||
TAILREC_KEYWORD to EnumSet.of(FUNCTION),
|
TAILREC_KEYWORD to EnumSet.of(FUNCTION),
|
||||||
SUSPEND_KEYWORD to EnumSet.of(MEMBER_FUNCTION, TOP_LEVEL_FUNCTION),
|
SUSPEND_KEYWORD to EnumSet.of(MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, LOCAL_FUNCTION),
|
||||||
EXTERNAL_KEYWORD to EnumSet.of(FUNCTION, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, CLASS),
|
EXTERNAL_KEYWORD to EnumSet.of(FUNCTION, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, CLASS),
|
||||||
ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS),
|
ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS),
|
||||||
CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// IGNORE_BACKEND_WITHOUT_CHECK: JVM, JS, NATIVE
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
val local = suspend fun() = "OK"
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(a: String, b: String): String {
|
||||||
|
suspend fun local() = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume(a + b)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal("O", "K")
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
val a = "O"
|
||||||
|
val b = "K"
|
||||||
|
suspend fun local() = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume(a + b)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
suspend fun String.local() = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume(this)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return "OK".local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
suspend infix fun String.local(a: String) = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume(this + a)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return "O" local "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
val l: suspend () -> String = {
|
||||||
|
suspend fun local() = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume("OK")
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
local()
|
||||||
|
}
|
||||||
|
return l()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
suspend fun local(): String {
|
||||||
|
suspend fun local(): String {
|
||||||
|
suspend fun local(): String {
|
||||||
|
suspend fun local(): String {
|
||||||
|
suspend fun local(): String {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
suspend fun local() = "OK"
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(): String {
|
||||||
|
suspend fun local() = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume("OK")
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal()
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
var result = "FAIL"
|
||||||
|
var i = 0
|
||||||
|
var finished = false
|
||||||
|
|
||||||
|
var proceed: () -> Unit = {}
|
||||||
|
|
||||||
|
suspend fun suspendHere() = suspendCoroutine<Unit> {c ->
|
||||||
|
i++
|
||||||
|
proceed = { c.resume(Unit) }
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun callLocal() {
|
||||||
|
suspend fun local() {
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
local()
|
||||||
|
local()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
val continuation = object: Continuation<Unit> {
|
||||||
|
override val context: CoroutineContext
|
||||||
|
get() = EmptyCoroutineContext
|
||||||
|
|
||||||
|
override fun resume(value: Unit) {
|
||||||
|
proceed = {
|
||||||
|
result = "OK"
|
||||||
|
finished = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resumeWithException(exception: Throwable) {
|
||||||
|
throw exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.startCoroutine(continuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
callLocal()
|
||||||
|
}
|
||||||
|
for (counter in 0 until 10) {
|
||||||
|
if (i != counter + 1) return "Expected ${counter + 1}, got $i"
|
||||||
|
proceed()
|
||||||
|
}
|
||||||
|
if (i != 10) return "FAIL $i"
|
||||||
|
if (finished) return "resume on root continuation is called"
|
||||||
|
proceed()
|
||||||
|
if (!finished) return "resume on root continuation is not called"
|
||||||
|
return result
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun callLocal(a: String, b: String): String {
|
||||||
|
suspend fun local(a: String, b: String) = suspendCoroutineOrReturn<String> {
|
||||||
|
it.resume(a + b)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
return local(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "FAIL"
|
||||||
|
builder {
|
||||||
|
res = callLocal("O", "K")
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
Vendored
+3
-3
@@ -58,7 +58,7 @@ fun String.test() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SuperInterface.fun1() {
|
suspend fun SuperInterface.fun1() {
|
||||||
superFun()
|
superFun()
|
||||||
superExtFun()
|
superExtFun()
|
||||||
with("") {
|
with("") {
|
||||||
@@ -66,7 +66,7 @@ fun String.test() {
|
|||||||
superExtFun()
|
superExtFun()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun RestrictedController.fun2() {
|
suspend fun RestrictedController.fun2() {
|
||||||
superFun()
|
superFun()
|
||||||
superExtFun()
|
superExtFun()
|
||||||
memberFun()
|
memberFun()
|
||||||
@@ -78,7 +78,7 @@ fun String.test() {
|
|||||||
memberExtFun()
|
memberExtFun()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SubClass.fun3() {
|
suspend fun SubClass.fun3() {
|
||||||
superFun()
|
superFun()
|
||||||
superExtFun()
|
superExtFun()
|
||||||
memberFun()
|
memberFun()
|
||||||
|
|||||||
+3
-3
@@ -76,7 +76,7 @@ fun A.test() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SuperInterface.fun1() {
|
suspend fun SuperInterface.fun1() {
|
||||||
extAny()
|
extAny()
|
||||||
memExtAny()
|
memExtAny()
|
||||||
extSuper()
|
extSuper()
|
||||||
@@ -88,7 +88,7 @@ fun A.test() {
|
|||||||
memExtSuper()
|
memExtSuper()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun RestrictedController.fun2() {
|
suspend fun RestrictedController.fun2() {
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extAny<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extAny<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>memExtAny<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>memExtAny<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extSuper<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extSuper<!>()
|
||||||
@@ -105,7 +105,7 @@ fun A.test() {
|
|||||||
memExt()
|
memExt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SubClass.fun3() {
|
suspend fun SubClass.fun3() {
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extAny<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extAny<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>memExtAny<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>memExtAny<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extSuper<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>extSuper<!>()
|
||||||
|
|||||||
Vendored
+3
-3
@@ -43,7 +43,7 @@ fun A.test() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SuperInterface.fun1() {
|
suspend fun SuperInterface.fun1() {
|
||||||
topLevel()
|
topLevel()
|
||||||
member()
|
member()
|
||||||
with(A()) {
|
with(A()) {
|
||||||
@@ -51,7 +51,7 @@ fun A.test() {
|
|||||||
member()
|
member()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun RestrictedController.fun2() {
|
suspend fun RestrictedController.fun2() {
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>topLevel<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>topLevel<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
||||||
with(A()) {
|
with(A()) {
|
||||||
@@ -59,7 +59,7 @@ fun A.test() {
|
|||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun SubClass.fun3() {
|
suspend fun SubClass.fun3() {
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>topLevel<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>topLevel<!>()
|
||||||
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
<!ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL!>member<!>()
|
||||||
with(A()) {
|
with(A()) {
|
||||||
|
|||||||
+3
-3
@@ -2,16 +2,16 @@ suspend fun baz() = 1
|
|||||||
suspend fun unit() {}
|
suspend fun unit() {}
|
||||||
|
|
||||||
suspend fun foo() {
|
suspend fun foo() {
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun bar() {
|
suspend fun bar() {
|
||||||
baz()
|
baz()
|
||||||
return unit()
|
return unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun foobar1(): Int {
|
suspend fun foobar1(): Int {
|
||||||
return baz()
|
return baz()
|
||||||
}
|
}
|
||||||
|
|
||||||
<!WRONG_MODIFIER_TARGET!>suspend<!> fun foobar2() {
|
suspend fun foobar2() {
|
||||||
return unit()
|
return unit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+93
@@ -6557,6 +6557,99 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalFunctions extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Anonymous extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void ignoreSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAnonymous() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/anonymous"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Named extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInNamed() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/named"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedParameters.kt")
|
||||||
|
public void testCapturedParameters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedParameters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedVariables.kt")
|
||||||
|
public void testCapturedVariables() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedVariables.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extension.kt")
|
||||||
|
public void testExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/extension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("infix.kt")
|
||||||
|
public void testInfix() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/infix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("insideLambda.kt")
|
||||||
|
public void testInsideLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/insideLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedLocals.kt")
|
||||||
|
public void testNestedLocals() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/nestedLocals.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleSuspensionPoint.kt")
|
||||||
|
public void testSimpleSuspensionPoint() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simpleSuspensionPoint.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stateMachine.kt")
|
||||||
|
public void testStateMachine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/stateMachine.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withArguments.kt")
|
||||||
|
public void testWithArguments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/withArguments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+93
@@ -6557,6 +6557,99 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalFunctions extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Anonymous extends AbstractBlackBoxCodegenTest {
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void ignoreSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAnonymous() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/anonymous"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Named extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInNamed() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/named"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedParameters.kt")
|
||||||
|
public void testCapturedParameters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedParameters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedVariables.kt")
|
||||||
|
public void testCapturedVariables() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedVariables.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extension.kt")
|
||||||
|
public void testExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/extension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("infix.kt")
|
||||||
|
public void testInfix() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/infix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("insideLambda.kt")
|
||||||
|
public void testInsideLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/insideLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedLocals.kt")
|
||||||
|
public void testNestedLocals() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/nestedLocals.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleSuspensionPoint.kt")
|
||||||
|
public void testSimpleSuspensionPoint() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simpleSuspensionPoint.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stateMachine.kt")
|
||||||
|
public void testStateMachine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/stateMachine.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withArguments.kt")
|
||||||
|
public void testWithArguments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/withArguments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+93
@@ -6557,6 +6557,99 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalFunctions extends AbstractLightAnalysisModeTest {
|
||||||
|
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Anonymous extends AbstractLightAnalysisModeTest {
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void ignoreSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAnonymous() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/anonymous"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Named extends AbstractLightAnalysisModeTest {
|
||||||
|
public void testAllFilesPresentInNamed() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/named"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedParameters.kt")
|
||||||
|
public void testCapturedParameters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedParameters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedVariables.kt")
|
||||||
|
public void testCapturedVariables() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedVariables.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extension.kt")
|
||||||
|
public void testExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/extension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("infix.kt")
|
||||||
|
public void testInfix() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/infix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("insideLambda.kt")
|
||||||
|
public void testInsideLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/insideLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedLocals.kt")
|
||||||
|
public void testNestedLocals() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/nestedLocals.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleSuspensionPoint.kt")
|
||||||
|
public void testSimpleSuspensionPoint() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simpleSuspensionPoint.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stateMachine.kt")
|
||||||
|
public void testStateMachine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/stateMachine.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withArguments.kt")
|
||||||
|
public void testWithArguments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/withArguments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -144,6 +144,9 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
CopyBuilder<D> setDropOriginalInContainingParts();
|
CopyBuilder<D> setDropOriginalInContainingParts();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
CopyBuilder<D> setDropSuspend();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
CopyBuilder<D> setHiddenToOvercomeSignatureClash();
|
CopyBuilder<D> setHiddenToOvercomeSignatureClash();
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -372,6 +372,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
|
private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
|
||||||
private Boolean newHasSynthesizedParameterNames = null;
|
private Boolean newHasSynthesizedParameterNames = null;
|
||||||
protected boolean justForTypeSubstitution = false;
|
protected boolean justForTypeSubstitution = false;
|
||||||
|
private boolean dropSuspend = false;
|
||||||
|
|
||||||
public CopyConfiguration(
|
public CopyConfiguration(
|
||||||
@NotNull TypeSubstitution substitution,
|
@NotNull TypeSubstitution substitution,
|
||||||
@@ -500,6 +501,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public CopyConfiguration setDropSuspend() {
|
||||||
|
this.dropSuspend = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public CopyConfiguration setHiddenToOvercomeSignatureClash() {
|
public CopyConfiguration setHiddenToOvercomeSignatureClash() {
|
||||||
@@ -664,7 +672,11 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
|||||||
substitutedDescriptor.setExternal(isExternal);
|
substitutedDescriptor.setExternal(isExternal);
|
||||||
substitutedDescriptor.setInline(isInline);
|
substitutedDescriptor.setInline(isInline);
|
||||||
substitutedDescriptor.setTailrec(isTailrec);
|
substitutedDescriptor.setTailrec(isTailrec);
|
||||||
substitutedDescriptor.setSuspend(isSuspend);
|
if (configuration.dropSuspend) {
|
||||||
|
substitutedDescriptor.setSuspend(false);
|
||||||
|
} else {
|
||||||
|
substitutedDescriptor.setSuspend(isSuspend);
|
||||||
|
}
|
||||||
substitutedDescriptor.setExpect(isExpect);
|
substitutedDescriptor.setExpect(isExpect);
|
||||||
substitutedDescriptor.setActual(isActual);
|
substitutedDescriptor.setActual(isActual);
|
||||||
substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
|
substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
|
||||||
|
|||||||
+6
@@ -168,6 +168,12 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CopyBuilder<SimpleFunctionDescriptor> setDropSuspend() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public CopyBuilder<SimpleFunctionDescriptor> setHiddenToOvercomeSignatureClash() {
|
public CopyBuilder<SimpleFunctionDescriptor> setHiddenToOvercomeSignatureClash() {
|
||||||
|
|||||||
+93
@@ -7852,6 +7852,99 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalFunctions extends AbstractJsCodegenBoxTest {
|
||||||
|
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Anonymous extends AbstractJsCodegenBoxTest {
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void ignoreSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/anonymous/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAnonymous() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/anonymous"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Named extends AbstractJsCodegenBoxTest {
|
||||||
|
public void testAllFilesPresentInNamed() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/localFunctions/named"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedParameters.kt")
|
||||||
|
public void testCapturedParameters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedParameters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("capturedVariables.kt")
|
||||||
|
public void testCapturedVariables() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/capturedVariables.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extension.kt")
|
||||||
|
public void testExtension() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/extension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("infix.kt")
|
||||||
|
public void testInfix() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/infix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("insideLambda.kt")
|
||||||
|
public void testInsideLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/insideLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedLocals.kt")
|
||||||
|
public void testNestedLocals() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/nestedLocals.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleSuspensionPoint.kt")
|
||||||
|
public void testSimpleSuspensionPoint() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/simpleSuspensionPoint.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stateMachine.kt")
|
||||||
|
public void testStateMachine() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/stateMachine.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withArguments.kt")
|
||||||
|
public void testWithArguments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/localFunctions/named/withArguments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user