Refine returns codegen for suspend functions
This change should make the logic a bit more simple. For all suspend functions/coroutines treat them in expression codegen like they return boxed version of the original type. Everything works fine then, except Unit type functions: their bodies must be generated just like they're VOID and then load Unit on stack manually.
This commit is contained in:
@@ -127,7 +127,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
public final FrameMap myFrameMap;
|
public final FrameMap myFrameMap;
|
||||||
public final MethodContext context;
|
public final MethodContext context;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final Type boxedReturnTypeForCoroutine;
|
|
||||||
|
|
||||||
private final CodegenStatementVisitor statementVisitor = new CodegenStatementVisitor(this);
|
private final CodegenStatementVisitor statementVisitor = new CodegenStatementVisitor(this);
|
||||||
private final MemberCodegen<?> parentCodegen;
|
private final MemberCodegen<?> parentCodegen;
|
||||||
@@ -161,14 +160,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
this.myFrameMap = frameMap;
|
this.myFrameMap = frameMap;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
FunctionDescriptor descriptorForCoroutine = getOriginalLambdaDescriptorForCoroutine(context);
|
FunctionDescriptor originalSuspendDescriptor = getOriginalSuspendDescriptor(context);
|
||||||
if (descriptorForCoroutine != null && descriptorForCoroutine.getReturnType() != null) {
|
if (originalSuspendDescriptor != null && originalSuspendDescriptor.getReturnType() != null) {
|
||||||
this.returnType = typeMapper.mapReturnType(descriptorForCoroutine);
|
this.returnType = getBoxedReturnTypeForSuspend(originalSuspendDescriptor);
|
||||||
this.boxedReturnTypeForCoroutine = getBoxedReturnTypeForCoroutine(descriptorForCoroutine);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.boxedReturnTypeForCoroutine = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parentCodegen = parentCodegen;
|
this.parentCodegen = parentCodegen;
|
||||||
@@ -176,18 +173,31 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Type getBoxedReturnTypeForCoroutine(FunctionDescriptor descriptorForCoroutine) {
|
private Type getBoxedReturnTypeForSuspend(FunctionDescriptor descriptorForSuspend) {
|
||||||
assert descriptorForCoroutine.getReturnType() != null : "Uninitialized coroutine return type";
|
assert descriptorForSuspend.getReturnType() != null : "Uninitialized suspend return type";
|
||||||
return AsmUtil.boxType(typeMapper.mapType(descriptorForCoroutine.getReturnType()));
|
return AsmUtil.boxType(typeMapper.mapType(descriptorForSuspend.getReturnType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static FunctionDescriptor getOriginalLambdaDescriptorForCoroutine(MethodContext context) {
|
private static FunctionDescriptor getOriginalSuspendDescriptor(MethodContext context) {
|
||||||
|
FunctionDescriptor originalCoroutineDescriptor = getOriginalCoroutineDescriptor(context);
|
||||||
|
if (originalCoroutineDescriptor != null) return originalCoroutineDescriptor;
|
||||||
|
|
||||||
|
if (context.getFunctionDescriptor().isSuspend()) {
|
||||||
|
return (FunctionDescriptor) CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(context.getFunctionDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static FunctionDescriptor getOriginalCoroutineDescriptor(MethodContext context) {
|
||||||
if ((context.getParentContext() instanceof ClosureContext) &&
|
if ((context.getParentContext() instanceof ClosureContext) &&
|
||||||
(context.getParentContext().closure != null) &&
|
(context.getParentContext().closure != null) &&
|
||||||
context.getParentContext().closure.isCoroutine()) {
|
context.getParentContext().closure.isCoroutine()) {
|
||||||
return ((ClosureContext) context.getParentContext()).getCoroutineDescriptor();
|
return ((ClosureContext) context.getParentContext()).getCoroutineDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +361,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
putStackValue(expr, type, value);
|
putStackValue(expr, type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putStackValue(KtElement expr, Type type, StackValue value) {
|
private void putStackValue(@Nullable KtElement expr, @NotNull Type type, @NotNull StackValue value) {
|
||||||
// for repl store the result of the last line into special field
|
// for repl store the result of the last line into special field
|
||||||
if (value.type != Type.VOID_TYPE && state.getReplSpecific().getShouldGenerateScriptResultValue()) {
|
if (value.type != Type.VOID_TYPE && state.getReplSpecific().getShouldGenerateScriptResultValue()) {
|
||||||
ScriptContext context = getScriptContext();
|
ScriptContext context = getScriptContext();
|
||||||
@@ -1775,7 +1785,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static CallableDescriptor unwrapOriginalLambdaDescriptorForCoroutine(@NotNull MethodContext context) {
|
private static CallableDescriptor unwrapOriginalLambdaDescriptorForCoroutine(@NotNull MethodContext context) {
|
||||||
FunctionDescriptor coroutine = getOriginalLambdaDescriptorForCoroutine(context);
|
FunctionDescriptor coroutine = getOriginalSuspendDescriptor(context);
|
||||||
if (coroutine != null) return coroutine;
|
if (coroutine != null) return coroutine;
|
||||||
return context.getFunctionDescriptor();
|
return context.getFunctionDescriptor();
|
||||||
}
|
}
|
||||||
@@ -2159,26 +2169,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type returnType = isNonLocalReturn ? nonLocalReturn.returnType : ExpressionCodegen.this.returnType;
|
Type returnType = isNonLocalReturn ? nonLocalReturn.returnType : ExpressionCodegen.this.returnType;
|
||||||
StackValue valueToReturn = returnedExpression != null ? gen(returnedExpression) : null;
|
StackValue valueToReturn = returnedExpression != null ? gen(returnedExpression) : StackValue.none();
|
||||||
|
|
||||||
if (returnedExpression != null && valueToReturn != null) {
|
putStackValue(returnedExpression, returnType, valueToReturn);
|
||||||
putStackValue(returnedExpression, returnType, valueToReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Label afterReturnLabel = new Label();
|
Label afterReturnLabel = new Label();
|
||||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
|
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
|
||||||
|
|
||||||
if (isNonLocalReturn) {
|
if (isNonLocalReturn) {
|
||||||
if (nonLocalReturn.boxedCoroutineReturnType != null && !nonLocalReturn.boxedCoroutineReturnType.equals(returnType)) {
|
|
||||||
StackValue.coerce(nonLocalReturn.returnType, nonLocalReturn.boxedCoroutineReturnType, v);
|
|
||||||
returnType = nonLocalReturn.boxedCoroutineReturnType;
|
|
||||||
}
|
|
||||||
|
|
||||||
InlineCodegenUtil.generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
InlineCodegenUtil.generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
||||||
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
|
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
emitLocalReturnInsn();
|
v.areturn(ExpressionCodegen.this.returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.mark(afterReturnLabel);
|
v.mark(afterReturnLabel);
|
||||||
@@ -2213,7 +2216,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
FunctionDescriptor containingFunction =
|
FunctionDescriptor containingFunction =
|
||||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
||||||
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
||||||
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL, null);
|
return new NonLocalReturnInfo(getReturnTypeForNonLocalReturn(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL);
|
||||||
} else {
|
} else {
|
||||||
//local
|
//local
|
||||||
return null;
|
return null;
|
||||||
@@ -2225,49 +2228,49 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
DeclarationDescriptor elementDescriptor = typeMapper.getBindingContext().get(DECLARATION_TO_DESCRIPTOR, element);
|
DeclarationDescriptor elementDescriptor = typeMapper.getBindingContext().get(DECLARATION_TO_DESCRIPTOR, element);
|
||||||
assert element != null : "Expression should be not null " + expression.getText();
|
assert element != null : "Expression should be not null " + expression.getText();
|
||||||
assert elementDescriptor != null : "Descriptor should be not null: " + element.getText();
|
assert elementDescriptor != null : "Descriptor should be not null: " + element.getText();
|
||||||
Type boxedCoroutineReturnType =
|
return new NonLocalReturnInfo(getReturnTypeForNonLocalReturn(elementDescriptor), expression.getLabelName());
|
||||||
elementDescriptor instanceof AnonymousFunctionDescriptor
|
|
||||||
&& ((AnonymousFunctionDescriptor) elementDescriptor).isCoroutine()
|
|
||||||
? getBoxedReturnTypeForCoroutine((FunctionDescriptor) elementDescriptor)
|
|
||||||
: null;
|
|
||||||
return new NonLocalReturnInfo(
|
|
||||||
typeMapper.mapReturnType((CallableDescriptor) elementDescriptor), expression.getLabelName(),
|
|
||||||
boxedCoroutineReturnType
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Type getReturnTypeForNonLocalReturn(DeclarationDescriptor elementDescriptor) {
|
||||||
|
return (elementDescriptor instanceof AnonymousFunctionDescriptor
|
||||||
|
&& ((AnonymousFunctionDescriptor) elementDescriptor).isCoroutine())
|
||||||
|
|| (elementDescriptor instanceof FunctionDescriptor && ((FunctionDescriptor) elementDescriptor).isSuspend())
|
||||||
|
? getBoxedReturnTypeForSuspend((FunctionDescriptor) elementDescriptor)
|
||||||
|
: typeMapper.mapReturnType((CallableDescriptor) elementDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
public void returnExpression(KtExpression expr) {
|
public void returnExpression(KtExpression expr) {
|
||||||
boolean isBlockedNamedFunction = expr instanceof KtBlockExpression && expr.getParent() instanceof KtNamedFunction;
|
boolean isBlockedNamedFunction = expr instanceof KtBlockExpression && expr.getParent() instanceof KtNamedFunction;
|
||||||
|
|
||||||
// If generating body for named block-bodied function, generate it as sequence of statements
|
FunctionDescriptor originalCoroutineDescriptor = getOriginalCoroutineDescriptor(context);
|
||||||
gen(expr, isBlockedNamedFunction ? Type.VOID_TYPE : returnType);
|
boolean isVoidCoroutineLambda =
|
||||||
|
originalCoroutineDescriptor != null && typeMapper.mapReturnType(originalCoroutineDescriptor).getSort() == Type.VOID;
|
||||||
|
|
||||||
|
// If generating body for named block-bodied function or Unit-typed coroutine lambda, generate it as sequence of statements
|
||||||
|
Type typeForExpression =
|
||||||
|
isBlockedNamedFunction || isVoidCoroutineLambda
|
||||||
|
? Type.VOID_TYPE
|
||||||
|
: returnType;
|
||||||
|
|
||||||
|
gen(expr, typeForExpression);
|
||||||
|
|
||||||
// If it does not end with return we should return something
|
// If it does not end with return we should return something
|
||||||
// because if we don't there can be VerifyError (specific cases with Nothing-typed expressions)
|
// because if we don't there can be VerifyError (specific cases with Nothing-typed expressions)
|
||||||
if (!endsWithReturn(expr)) {
|
if (!endsWithReturn(expr)) {
|
||||||
markLineNumber(expr, true);
|
markLineNumber(expr, true);
|
||||||
|
|
||||||
if (isLambdaVoidBody(expr, returnType)) {
|
if (isLambdaVoidBody(expr, typeForExpression)) {
|
||||||
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
|
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBlockedNamedFunction && !Type.VOID_TYPE.equals(expressionType(expr))) {
|
if (typeForExpression.getSort() == Type.VOID) {
|
||||||
StackValue.none().put(returnType, v);
|
StackValue.none().put(returnType, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitLocalReturnInsn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void emitLocalReturnInsn() {
|
|
||||||
if (boxedReturnTypeForCoroutine != null && !boxedReturnTypeForCoroutine.equals(returnType)) {
|
|
||||||
StackValue.coerce(returnType, boxedReturnTypeForCoroutine, v);
|
|
||||||
v.areturn(boxedReturnTypeForCoroutine);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.areturn(returnType);
|
v.areturn(returnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2783,6 +2786,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return new OperationStackValue(getSuspensionBoxedReturnTypeByResolvedCall(resolvedCall), ((OperationStackValue) result).getLambda());
|
return new OperationStackValue(getSuspensionBoxedReturnTypeByResolvedCall(resolvedCall), ((OperationStackValue) result).getLambda());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bindingContext.get(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.getCall()) != null) {
|
||||||
|
// Suspend function's calls inside another suspend function should behave like they leave values of correct type,
|
||||||
|
// while real methods return java/lang/Object.
|
||||||
|
// NB: They are always in return position at the moment.
|
||||||
|
// If we didn't do this, StackValue.coerce would add proper CHECKCAST that would've failed in case of callee function
|
||||||
|
// returning SUSPENDED marker, which is instance of java/lang/Object.
|
||||||
|
return new OperationStackValue(returnType, ((OperationStackValue) result).getLambda());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4713,12 +4725,10 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
|
|
||||||
private final String labelName;
|
private final String labelName;
|
||||||
private final Type boxedCoroutineReturnType;
|
|
||||||
|
|
||||||
private NonLocalReturnInfo(@NotNull Type type, @NotNull String name, @Nullable Type boxedCoroutineReturnType) {
|
private NonLocalReturnInfo(@NotNull Type type, @NotNull String name) {
|
||||||
returnType = type;
|
returnType = type;
|
||||||
labelName = name;
|
labelName = name;
|
||||||
this.boxedCoroutineReturnType = boxedCoroutineReturnType;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
|
suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume("OK")
|
||||||
|
CoroutineIntrinsics.SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
var wasResumeCalled = false
|
||||||
|
c.startCoroutine(object : Continuation<Unit> {
|
||||||
|
override fun resume(value: Unit) {
|
||||||
|
wasResumeCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resumeWithException(exception: Throwable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!wasResumeCalled) throw RuntimeException("fail 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
builder {
|
||||||
|
run {
|
||||||
|
if (result == "") return@builder
|
||||||
|
}
|
||||||
|
suspendHere()
|
||||||
|
throw RuntimeException("fail 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = "fail1"
|
||||||
|
|
||||||
|
builder {
|
||||||
|
run {
|
||||||
|
if (result == "") return@builder
|
||||||
|
}
|
||||||
|
result = suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
|
suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume("OK")
|
||||||
|
CoroutineIntrinsics.SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
var wasResumeCalled = false
|
||||||
|
c.startCoroutine(object : Continuation<Unit> {
|
||||||
|
override fun resume(value: Unit) {
|
||||||
|
wasResumeCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resumeWithException(exception: Throwable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!wasResumeCalled) throw RuntimeException("fail 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
builder {
|
||||||
|
if (result == "") return@builder
|
||||||
|
suspendHere()
|
||||||
|
throw RuntimeException("fail 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = "fail"
|
||||||
|
|
||||||
|
builder {
|
||||||
|
if (result == "") return@builder
|
||||||
|
result = suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
|
var result = "0"
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun suspendHere(x: Int): Unit {
|
||||||
|
run {
|
||||||
|
if (x == 0) return
|
||||||
|
if (x == 1) return@suspendHere
|
||||||
|
}
|
||||||
|
|
||||||
|
result = "OK"
|
||||||
|
return CoroutineIntrinsics.suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume(Unit)
|
||||||
|
CoroutineIntrinsics.SUSPENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
if (suspendHere(0) != Unit) throw RuntimeException("fail 1")
|
||||||
|
if (suspendHere(1) != Unit) throw RuntimeException("fail 2")
|
||||||
|
if (suspendHere(2) != Unit) throw RuntimeException("fail 3")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
|
var result = "0"
|
||||||
|
|
||||||
|
suspend fun suspendHere(x: Int): Unit {
|
||||||
|
if (x == 0) return
|
||||||
|
result = "OK"
|
||||||
|
return CoroutineIntrinsics.suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume(Unit)
|
||||||
|
CoroutineIntrinsics.SUSPENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
suspendHere(0)
|
||||||
|
suspendHere(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
public final class CoroutineNonLocalReturnKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class CoroutineUtilKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class EmptyContinuation {
|
||||||
|
public final static field INSTANCE: EmptyContinuation
|
||||||
|
private method <init>(): void
|
||||||
|
public method resume(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
|
||||||
|
public method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
public final class CoroutineReturnKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class CoroutineUtilKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class EmptyContinuation {
|
||||||
|
public final static field INSTANCE: EmptyContinuation
|
||||||
|
private method <init>(): void
|
||||||
|
public method resume(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
|
||||||
|
public method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void
|
||||||
|
}
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
public final class CoroutineUtilKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class EmptyContinuation {
|
||||||
|
public final static field INSTANCE: EmptyContinuation
|
||||||
|
private method <init>(): void
|
||||||
|
public method resume(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
|
||||||
|
public method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class SuspendNonLocalReturnKt {
|
||||||
|
private static @org.jetbrains.annotations.NotNull field result: java.lang.String
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method getResult(): java.lang.String
|
||||||
|
public final static method setResult(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method suspendHere(p0: int, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
public final class CoroutineUtilKt {
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class EmptyContinuation {
|
||||||
|
public final static field INSTANCE: EmptyContinuation
|
||||||
|
private method <init>(): void
|
||||||
|
public method resume(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
|
||||||
|
public method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class SuspendReturnKt {
|
||||||
|
private static @org.jetbrains.annotations.NotNull field result: java.lang.String
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
|
public final static @org.jetbrains.annotations.NotNull method getResult(): java.lang.String
|
||||||
|
public final static method setResult(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method suspendHere(p0: int, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
|
}
|
||||||
+33
@@ -4966,6 +4966,39 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitTypeReturn extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInUnitTypeReturn() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/unitTypeReturn"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineNonLocalReturn.kt")
|
||||||
|
public void testCoroutineNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineReturn.kt")
|
||||||
|
public void testCoroutineReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendNonLocalReturn.kt")
|
||||||
|
public void testSuspendNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendReturn.kt")
|
||||||
|
public void testSuspendReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||||
|
|||||||
@@ -4966,6 +4966,39 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitTypeReturn extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInUnitTypeReturn() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/unitTypeReturn"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineNonLocalReturn.kt")
|
||||||
|
public void testCoroutineNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineReturn.kt")
|
||||||
|
public void testCoroutineReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendNonLocalReturn.kt")
|
||||||
|
public void testSuspendNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendReturn.kt")
|
||||||
|
public void testSuspendReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||||
|
|||||||
+33
@@ -4966,6 +4966,39 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitTypeReturn extends AbstractLightAnalysisModeCodegenTest {
|
||||||
|
public void testAllFilesPresentInUnitTypeReturn() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/unitTypeReturn"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineNonLocalReturn.kt")
|
||||||
|
public void testCoroutineNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineReturn.kt")
|
||||||
|
public void testCoroutineReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendNonLocalReturn.kt")
|
||||||
|
public void testSuspendNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendReturn.kt")
|
||||||
|
public void testSuspendReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||||
|
|||||||
+39
@@ -5765,6 +5765,45 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class UnitTypeReturn extends AbstractJsCodegenBoxTest {
|
||||||
|
public void testAllFilesPresentInUnitTypeReturn() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/unitTypeReturn"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineNonLocalReturn.kt")
|
||||||
|
public void testCoroutineNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineReturn.kt")
|
||||||
|
public void testCoroutineReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/coroutineReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendNonLocalReturn.kt")
|
||||||
|
public void testSuspendNonLocalReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendNonLocalReturn.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("suspendReturn.kt")
|
||||||
|
public void testSuspendReturn() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn/suspendReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||||
|
|||||||
Reference in New Issue
Block a user