Fix last if-statement in block codegen

#KT-3203 Fixed
This commit is contained in:
Alexander Udalov
2013-01-09 20:27:13 +04:00
parent 293b272a22
commit 4cebd3f75b
4 changed files with 56 additions and 11 deletions
@@ -1045,7 +1045,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitBlockExpression(JetBlockExpression expression, StackValue receiver) {
List<JetElement> statements = expression.getStatements();
return generateBlock(statements);
JetType unitType = KotlinBuiltIns.getInstance().getUnitType();
boolean lastStatementIsExpression = !unitType.equals(bindingContext.get(EXPRESSION_TYPE, expression));
return generateBlock(statements, lastStatementIsExpression);
}
@Override
@@ -1069,7 +1071,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
//noinspection ConstantConditions
if (bindingContext.get(BindingContext.BLOCK, expression)) {
//noinspection ConstantConditions
return generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements());
return gen(expression.getFunctionLiteral().getBodyExpression());
}
else {
return genClosure(expression);
@@ -1165,7 +1167,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
private StackValue generateBlock(List<JetElement> statements) {
private StackValue generateBlock(List<JetElement> statements, boolean lastStatementIsExpression) {
final Label blockEnd = new Label();
List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList();
@@ -1197,9 +1199,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
generateLocalFunctionDeclaration((JetNamedFunction) statement, leaveTasks);
}
boolean isStatement = iterator.hasNext() || !isInsideNonUnitFunction();
boolean isExpression = !iterator.hasNext() && lastStatementIsExpression;
StackValue result = isStatement ? genStatement(statement) : gen(statement);
StackValue result = isExpression ? gen(statement) : genStatement(statement);
if (!iterator.hasNext()) {
answer = result;
@@ -1218,12 +1220,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return answer;
}
private boolean isInsideNonUnitFunction() {
DeclarationDescriptor descriptor = context.getContextDescriptor();
JetType unit = KotlinBuiltIns.getInstance().getUnitType();
return descriptor instanceof CallableDescriptor && !unit.equals(((CallableDescriptor) descriptor).getReturnType());
}
private void generateLocalVariableDeclaration(
@NotNull JetVariableDeclaration variableDeclaration,
final @NotNull Label blockEnd,
@@ -0,0 +1,19 @@
fun testIf() {
val condition = true
val result = if (condition) {
val hello: String? = "hello"
if (hello == null) {
false
}
else {
true
}
}
else true
if (!result) throw AssertionError("result is false")
}
fun box(): String {
testIf()
return "OK"
}
@@ -0,0 +1,20 @@
fun check1() {
val result = if (true) {
if (true) 1 else 2
}
else 3
if (result != 1) throw AssertionError("result: $result")
}
fun check2() {
val result = if (true)
if (true) 1 else 2
else 3
if (result != 1) throw AssertionError("result: $result")
}
fun box(): String {
check1()
check2()
return "OK"
}
@@ -476,4 +476,14 @@ public class ControlStructuresTest extends CodegenTestCase {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt3087.kt");
}
public void testKt3203_1() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt3203_1.kt");
}
public void testKt3203_2() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt3203_2.kt");
}
}