From af601b5a907ad3982bc8e3e90c7b59caad912296 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 22 Nov 2012 15:13:18 +0400 Subject: [PATCH] Single-branch if-statements Single-branch if-expressions are now compiled to statements if the result is not used #KT-3036 In Progress --- .../jet/codegen/CodegenStatementVisitor.java | 5 ++ .../jet/codegen/ExpressionCodegen.java | 48 ++++++++++++------- .../codegen/statements/ifSingleBranch.kt | 9 ++++ compiler/testData/lineNumber/custom/ifThen.kt | 11 +++++ .../jetbrains/jet/codegen/LineNumberTest.java | 4 ++ .../jet/codegen/StatementGenTest.java | 4 ++ 6 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/codegen/statements/ifSingleBranch.kt create mode 100644 compiler/testData/lineNumber/custom/ifThen.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java index 52f865843bf..df66c45e6a0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java @@ -32,4 +32,9 @@ public class CodegenStatementVisitor extends JetVisitor public StackValue visitJetElement(JetElement element, StackValue receiver) { return element.accept(codegen, receiver); } + + @Override + public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) { + return codegen.generateIfExpression(expression, true); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e2edc2f1698..79bf6bbbe03 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -358,6 +358,10 @@ public class ExpressionCodegen extends JetVisitor implem @Override public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) { + return generateIfExpression(expression, false); + } + + /* package */ StackValue generateIfExpression(JetIfExpression expression, boolean isStatement) { Type asmType = expressionType(expression); JetExpression thenExpression = expression.getThen(); @@ -376,12 +380,12 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.onStack(asmType); } StackValue condition = gen(expression.getCondition()); - return generateSingleBranchIf(condition, elseExpression, false); + return generateSingleBranchIf(condition, expression, elseExpression, false, isStatement); } else { if (isEmptyExpression(elseExpression)) { StackValue condition = gen(expression.getCondition()); - return generateSingleBranchIf(condition, thenExpression, true); + return generateSingleBranchIf(condition, expression, thenExpression, true, isStatement); } } @@ -967,27 +971,37 @@ public class ExpressionCodegen extends JetVisitor implem throw new UnsupportedOperationException(); } - private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) { - Type expressionType = expressionType(expression); - Type targetType = expressionType; - if (!expressionType.equals(JET_TUPLE0_TYPE)) { - targetType = OBJECT_TYPE; - } - + private StackValue generateSingleBranchIf( + StackValue condition, + JetIfExpression ifExpression, + JetExpression expression, + boolean inverse, + boolean isStatement + ) { Label elseLabel = new Label(); condition.condJump(elseLabel, inverse, v); - gen(expression, expressionType); - StackValue.coerce(expressionType, targetType, v); + if (isStatement) { + gen(expression, Type.VOID_TYPE); + v.mark(elseLabel); + return StackValue.none(); + } + else { + Type type = expressionType(expression); + Type targetType = type.equals(JET_TUPLE0_TYPE) ? type : OBJECT_TYPE; - Label end = new Label(); - v.goTo(end); + gen(expression, targetType); - v.mark(elseLabel); - StackValue.putTuple0Instance(v); + Label end = new Label(); + v.goTo(end); - v.mark(end); - return StackValue.onStack(targetType); + markLineNumber(ifExpression); + v.mark(elseLabel); + StackValue.putTuple0Instance(v); + + v.mark(end); + return StackValue.onStack(targetType); + } } @Override diff --git a/compiler/testData/codegen/statements/ifSingleBranch.kt b/compiler/testData/codegen/statements/ifSingleBranch.kt new file mode 100644 index 00000000000..6ba8e14c210 --- /dev/null +++ b/compiler/testData/codegen/statements/ifSingleBranch.kt @@ -0,0 +1,9 @@ +fun foo() { + if (0 < 1) { + return + } + + if (1 < 2) else { + return + } +} diff --git a/compiler/testData/lineNumber/custom/ifThen.kt b/compiler/testData/lineNumber/custom/ifThen.kt new file mode 100644 index 00000000000..b83e386da20 --- /dev/null +++ b/compiler/testData/lineNumber/custom/ifThen.kt @@ -0,0 +1,11 @@ +fun foo() { + if (0 < 1) { + return + } + + val u: Unit = if (0 < 1) { + return + } +} + +// 2 3 6 7 6 diff --git a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java index 66737ba9662..779e0b24468 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java @@ -295,6 +295,10 @@ public class LineNumberTest extends TestCaseWithTmpdir { doTest(); } + public void testIfThen() { + doTestCustom(); + } + public void testStaticDelegate() { JetFile foo = createPsiFile("staticDelegate/foo.kt"); JetFile bar = createPsiFile("staticDelegate/bar.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java index cb7b94f7d93..0f1642600bf 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java @@ -36,4 +36,8 @@ public class StatementGenTest extends CodegenTestCase { private void assertNoGetStatic(@NotNull String text) { assertFalse(text, text.toLowerCase().contains("getstatic")); } + + public void testIfSingleBranch() { + doTest(); + } }