Fix handleResult call generation for statement-like last expression in a block
This commit is contained in:
@@ -1619,12 +1619,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.mark(labelBeforeLastExpression);
|
||||
}
|
||||
|
||||
// Note that this result value is potentially unused (in case of handleResult coroutine call)
|
||||
StackValue result = isExpression ? gen(possiblyLabeledStatement) : genStatement(possiblyLabeledStatement);
|
||||
|
||||
if (!iterator.hasNext()) {
|
||||
answer = result;
|
||||
StackValue handleResultValue = !(possiblyLabeledStatement instanceof KtReturnExpression)
|
||||
? genControllerHandleResultCallIfNeeded(possiblyLabeledStatement, result)
|
||||
? genControllerHandleResultCallIfNeeded(possiblyLabeledStatement, possiblyLabeledStatement)
|
||||
: null;
|
||||
if (handleResultValue != null) {
|
||||
answer = handleResultValue;
|
||||
@@ -1652,7 +1653,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private StackValue genControllerHandleResultCallIfNeeded(@NotNull KtExpression callOwner, @Nullable StackValue valueToReturn) {
|
||||
private StackValue genControllerHandleResultCallIfNeeded(@NotNull KtExpression callOwner, @Nullable KtExpression valueToReturn) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(RETURN_HANDLE_RESULT_RESOLVED_CALL, callOwner);
|
||||
|
||||
if (resolvedCall != null) {
|
||||
@@ -1663,7 +1664,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
tempVariables.put(argumentExpression, StackValue.unit());
|
||||
}
|
||||
else {
|
||||
tempVariables.put(argumentExpression, valueToReturn);
|
||||
assert valueToReturn != null : "valueReturn expected to be not null for non-unit types";
|
||||
tempVariables.put(argumentExpression, gen(valueToReturn));
|
||||
}
|
||||
|
||||
tempVariables.put(
|
||||
@@ -1967,7 +1969,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type returnType = isNonLocalReturn ? nonLocalReturn.returnType : ExpressionCodegen.this.returnType;
|
||||
StackValue valueToReturn = returnedExpression != null ? gen(returnedExpression) : null;
|
||||
StackValue handleResultValue = genControllerHandleResultCallIfNeeded(expression, valueToReturn);
|
||||
StackValue handleResultValue = genControllerHandleResultCallIfNeeded(expression, returnedExpression);
|
||||
|
||||
if (handleResultValue != null) {
|
||||
handleResultValue.put(Type.VOID_TYPE, v);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
var globalResult = ""
|
||||
class Controller {
|
||||
suspend fun suspendWithValue(v: String, x: Continuation<String>) {
|
||||
x.resume(v)
|
||||
}
|
||||
|
||||
operator fun handleResult(x: String, c: Continuation<Nothing>) {
|
||||
globalResult = x
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||
c(Controller()).resume(Unit)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
var condition = true
|
||||
|
||||
builder {
|
||||
if (condition) {
|
||||
suspendWithValue("OK")
|
||||
} else {
|
||||
suspendWithValue("fail 1")
|
||||
}
|
||||
}
|
||||
|
||||
return globalResult
|
||||
}
|
||||
@@ -4177,6 +4177,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("statementLikeLastExpression.kt")
|
||||
public void testStatementLikeLastExpression() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/statementLikeLastExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("suspendDelegation.kt")
|
||||
public void testSuspendDelegation() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendDelegation.kt");
|
||||
|
||||
Reference in New Issue
Block a user