Fix last if-statement in block codegen
#KT-3203 Fixed
This commit is contained in:
@@ -1045,7 +1045,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
@Override
|
@Override
|
||||||
public StackValue visitBlockExpression(JetBlockExpression expression, StackValue receiver) {
|
public StackValue visitBlockExpression(JetBlockExpression expression, StackValue receiver) {
|
||||||
List<JetElement> statements = expression.getStatements();
|
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
|
@Override
|
||||||
@@ -1069,7 +1071,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (bindingContext.get(BindingContext.BLOCK, expression)) {
|
if (bindingContext.get(BindingContext.BLOCK, expression)) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
return generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements());
|
return gen(expression.getFunctionLiteral().getBodyExpression());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return genClosure(expression);
|
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();
|
final Label blockEnd = new Label();
|
||||||
|
|
||||||
List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList();
|
List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList();
|
||||||
@@ -1197,9 +1199,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
generateLocalFunctionDeclaration((JetNamedFunction) statement, leaveTasks);
|
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()) {
|
if (!iterator.hasNext()) {
|
||||||
answer = result;
|
answer = result;
|
||||||
@@ -1218,12 +1220,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
return answer;
|
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(
|
private void generateLocalVariableDeclaration(
|
||||||
@NotNull JetVariableDeclaration variableDeclaration,
|
@NotNull JetVariableDeclaration variableDeclaration,
|
||||||
final @NotNull Label blockEnd,
|
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);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt3087.kt");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user