Minor. Simplify coroutine related code in ExpressionCodegen
After previous change (treating suspend function as they return j/l/Object) most of existing hacks concerning suspend functions' return type became unnecessary
This commit is contained in:
@@ -60,6 +60,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
@@ -156,24 +157,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
this.v = new InstructionAdapter(mv);
|
||||
this.myFrameMap = frameMap;
|
||||
this.context = context;
|
||||
|
||||
FunctionDescriptor originalSuspendDescriptor = getOriginalSuspendDescriptor(context);
|
||||
if (originalSuspendDescriptor != null && originalSuspendDescriptor.getReturnType() != null) {
|
||||
this.returnType = getBoxedReturnTypeForSuspend(originalSuspendDescriptor);
|
||||
}
|
||||
else {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
this.returnType = returnType;
|
||||
|
||||
this.parentCodegen = parentCodegen;
|
||||
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Type getBoxedReturnTypeForSuspend(FunctionDescriptor descriptorForSuspend) {
|
||||
return AsmTypes.OBJECT_TYPE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FunctionDescriptor getOriginalSuspendDescriptor(MethodContext context) {
|
||||
FunctionDescriptor originalCoroutineDescriptor = getOriginalCoroutineDescriptor(context);
|
||||
@@ -2236,7 +2225,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor containingFunction =
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
||||
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
||||
return new NonLocalReturnInfo(getReturnTypeForNonLocalReturn(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL);
|
||||
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL);
|
||||
} else {
|
||||
//local
|
||||
return null;
|
||||
@@ -2248,25 +2237,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
DeclarationDescriptor elementDescriptor = typeMapper.getBindingContext().get(DECLARATION_TO_DESCRIPTOR, element);
|
||||
assert element != null : "Expression should be not null " + expression.getText();
|
||||
assert elementDescriptor != null : "Descriptor should be not null: " + element.getText();
|
||||
return new NonLocalReturnInfo(getReturnTypeForNonLocalReturn(elementDescriptor), expression.getLabelName());
|
||||
return new NonLocalReturnInfo(typeMapper.mapReturnType((CallableDescriptor) elementDescriptor), expression.getLabelName());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Type getReturnTypeForNonLocalReturn(DeclarationDescriptor elementDescriptor) {
|
||||
return elementDescriptor instanceof FunctionDescriptor && ((FunctionDescriptor) elementDescriptor).isSuspend()
|
||||
? getBoxedReturnTypeForSuspend((FunctionDescriptor) elementDescriptor)
|
||||
: typeMapper.mapReturnType((CallableDescriptor) elementDescriptor);
|
||||
}
|
||||
|
||||
public void returnExpression(KtExpression expr) {
|
||||
boolean isBlockedNamedFunction = expr instanceof KtBlockExpression && expr.getParent() instanceof KtNamedFunction;
|
||||
|
||||
FunctionDescriptor originalCoroutineDescriptor = getOriginalCoroutineDescriptor(context);
|
||||
boolean isVoidCoroutineLambda =
|
||||
originalCoroutineDescriptor != null && typeMapper.mapReturnType(originalCoroutineDescriptor).getSort() == Type.VOID;
|
||||
originalCoroutineDescriptor != null && TypeSignatureMappingKt.hasVoidReturnType(originalCoroutineDescriptor);
|
||||
|
||||
// If generating body for named block-bodied function or Unit-typed coroutine lambda, generate it as sequence of statements
|
||||
Type typeForExpression =
|
||||
@@ -2796,21 +2778,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Callable callable = resolveToCallable(fd, superCallTarget != null, resolvedCall);
|
||||
|
||||
|
||||
StackValue result = callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
||||
|
||||
if (resolvedCall.getResultingDescriptor() instanceof FunctionDescriptor &&
|
||||
((FunctionDescriptor) resolvedCall.getResultingDescriptor()).isSuspend() &&
|
||||
!CoroutineCodegenUtilKt.isSuspensionPointInStateMachine(resolvedCall, bindingContext)) {
|
||||
// Suspend function's tail 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 callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
||||
}
|
||||
|
||||
private StackValue getContinuationParameterFromEnclosingSuspendFunction(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
@@ -377,6 +378,12 @@ public class KotlinTypeMapper {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
|
||||
if (descriptor instanceof SimpleFunctionDescriptor && ((SimpleFunctionDescriptor) descriptor).isSuspend() &&
|
||||
((SimpleFunctionDescriptor) descriptor).getUserData(
|
||||
CoroutineCodegenUtilKt.INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) == null) {
|
||||
return mapReturnType(CoroutineCodegenUtilKt.createJvmSuspendFunctionView((SimpleFunctionDescriptor) descriptor), sw);
|
||||
}
|
||||
|
||||
if (TypeSignatureMappingKt.hasVoidReturnType(descriptor)) {
|
||||
if (sw != null) {
|
||||
sw.writeAsmType(Type.VOID_TYPE);
|
||||
|
||||
Reference in New Issue
Block a user