From 70f67c7993b9eeeb56e4b2499655e5ddf68a87fe Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 6 Feb 2013 16:37:06 +0400 Subject: [PATCH] Fix elvis expression in case of nullable generic --- .../jet/codegen/ExpressionCodegen.java | 39 +++++++++---------- .../testData/codegen/box/elvis/genericNull.kt | 8 ++++ .../testData/codegen/box/elvis/primitive.kt | 6 +++ .../BlackBoxCodegenTestGenerated.java | 21 +++++++++- 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/codegen/box/elvis/genericNull.kt create mode 100644 compiler/testData/codegen/box/elvis/primitive.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 6ba46a85e06..31132f968f4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2456,27 +2456,26 @@ public class ExpressionCodegen extends JetVisitor implem } private StackValue generateElvis(JetBinaryExpression expression) { - final Type exprType = expressionType(expression); - JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft()); - assert type != null; - final Type leftType = asmType(type); - if (type.isNullable()) { - gen(expression.getLeft(), leftType); - v.dup(); - Label end = new Label(); - Label ifNull = new Label(); - v.ifnull(ifNull); - StackValue.onStack(leftType).put(exprType, v); - v.goTo(end); - v.mark(ifNull); - v.pop(); - gen(expression.getRight(), exprType); - v.mark(end); - } - else { - gen(expression.getLeft(), leftType); - StackValue.onStack(leftType).put(exprType, v); + Type exprType = expressionType(expression); + Type leftType = expressionType(expression.getLeft()); + + gen(expression.getLeft(), leftType); + + if (isPrimitive(leftType)) { + return StackValue.onStack(leftType); } + + v.dup(); + Label ifNull = new Label(); + v.ifnull(ifNull); + StackValue.onStack(leftType).put(exprType, v); + Label end = new Label(); + v.goTo(end); + v.mark(ifNull); + v.pop(); + gen(expression.getRight(), exprType); + v.mark(end); + return StackValue.onStack(exprType); } diff --git a/compiler/testData/codegen/box/elvis/genericNull.kt b/compiler/testData/codegen/box/elvis/genericNull.kt new file mode 100644 index 00000000000..909435bef07 --- /dev/null +++ b/compiler/testData/codegen/box/elvis/genericNull.kt @@ -0,0 +1,8 @@ +fun foo(t: T) { + (t ?: 42).toInt() +} + +fun box(): String { + foo(null) + return "OK" +} diff --git a/compiler/testData/codegen/box/elvis/primitive.kt b/compiler/testData/codegen/box/elvis/primitive.kt new file mode 100644 index 00000000000..bd3edd1a725 --- /dev/null +++ b/compiler/testData/codegen/box/elvis/primitive.kt @@ -0,0 +1,6 @@ +fun box(): String { + if ((42 ?: 239) != 42) return "Fail Int" + if ((42.toLong() ?: 239.toLong()) != 42.toLong()) return "Fail Long" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index eb6abe1533e..81dc550c30e 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/box") -@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) +@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBox() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box"), "kt", true); @@ -1376,6 +1376,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/elvis") + public static class Elvis extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInElvis() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/elvis"), "kt", true); + } + + @TestMetadata("genericNull.kt") + public void testGenericNull() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/elvis/genericNull.kt"); + } + + @TestMetadata("primitive.kt") + public void testPrimitive() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/box/elvis/primitive.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/box/enum") public static class Enum extends AbstractBlackBoxCodegenTest { @TestMetadata("abstractMethodInEnum.kt") @@ -3347,6 +3365,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { suite.addTest(Closures.innerSuite()); suite.addTestSuite(ControlStructures.class); suite.addTest(DefaultArguments.innerSuite()); + suite.addTestSuite(Elvis.class); suite.addTestSuite(Enum.class); suite.addTestSuite(ExtensionFunctions.class); suite.addTestSuite(ExtensionProperties.class);