Fix handleResult call generation for statement-like last expression in a block

This commit is contained in:
Denis Zharkov
2016-06-07 13:56:12 +03:00
parent 3a5197d1ae
commit 692acc463a
3 changed files with 41 additions and 4 deletions
@@ -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");