diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index a53c8791f80..d140d937507 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -24,20 +24,38 @@ public class Increment implements IntrinsicMethod { @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { - JetExpression operand = arguments.get(0); - while(operand instanceof JetParenthesizedExpression) { - operand = ((JetParenthesizedExpression)operand).getExpression(); + boolean nullable = expectedType.getSort() == Type.OBJECT; + if(nullable) { + expectedType = JetTypeMapper.unboxType(expectedType); } - if (operand instanceof JetReferenceExpression) { - final int index = codegen.indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) { - return StackValue.preIncrement(index, myDelta); + if(arguments.size() > 0) { + JetExpression operand = arguments.get(0); + while(operand instanceof JetParenthesizedExpression) { + operand = ((JetParenthesizedExpression)operand).getExpression(); } + if (operand instanceof JetReferenceExpression) { + final int index = codegen.indexOfLocal((JetReferenceExpression) operand); + if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) { + return StackValue.preIncrement(index, myDelta); + } + } + StackValue value = codegen.genQualified(receiver, operand); + value. dupReceiver(v); + value. dupReceiver(v); + + value.put(expectedType, v); + plusMinus(v, expectedType); + value.store(v); + value.put(expectedType, v); } - StackValue value = codegen.genQualified(receiver, operand); - value. dupReceiver(v); - value. dupReceiver(v); - value.put(expectedType, v); + else { + receiver.put(expectedType, v); + plusMinus(v, expectedType); + } + return StackValue.onStack(expectedType); + } + + private void plusMinus(InstructionAdapter v, Type expectedType) { if (expectedType == Type.LONG_TYPE) { v.lconst(myDelta); } @@ -51,8 +69,5 @@ public class Increment implements IntrinsicMethod { v.iconst(myDelta); } v.add(expectedType); - value.store(v); - value.put(expectedType, v); - return StackValue.onStack(expectedType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 6ccff8d02b3..79374780086 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -23,6 +23,7 @@ import java.util.*; */ public class IntrinsicMethods { private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus(); + private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus(); private static final IntrinsicMethod NUMBER_CAST = new NumberCast(); private static final IntrinsicMethod INV = new Inv(); private static final IntrinsicMethod TYPEINFO = new TypeInfo(); @@ -53,6 +54,7 @@ public class IntrinsicMethods { } for (String type : PRIMITIVE_NUMBER_TYPES) { + declareIntrinsicFunction(type, "plus", 0, UNARY_PLUS); declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS); declareIntrinsicFunction(type, "inv", 0, INV); declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java index 89d757c88ef..b4b1e287310 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; import org.objectweb.asm.Type; @@ -16,6 +17,10 @@ import java.util.List; public class Inv implements IntrinsicMethod { @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { + boolean nullable = expectedType.getSort() == Type.OBJECT; + if(nullable) { + expectedType = JetTypeMapper.unboxType(expectedType); + } receiver.put(expectedType, v); if(expectedType == Type.LONG_TYPE) { v.lconst(-1L); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java index b84d3f79fdf..4eb8ecb4d20 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; import org.objectweb.asm.Type; @@ -15,6 +16,10 @@ import java.util.List; public class UnaryMinus implements IntrinsicMethod { @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { + boolean nullable = expectedType.getSort() == Type.OBJECT; + if(nullable) { + expectedType = JetTypeMapper.unboxType(expectedType); + } if (arguments.size() == 1) { codegen.gen(arguments.get(0), expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java new file mode 100644 index 00000000000..2405ef3d8aa --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.JetTypeMapper; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author alex.tkachman + */ +public class UnaryPlus implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver) { + boolean nullable = expectedType.getSort() == Type.OBJECT; + if(nullable) { + expectedType = JetTypeMapper.unboxType(expectedType); + } + receiver.put(expectedType, v); + return StackValue.onStack(expectedType); + } +} diff --git a/compiler/testData/codegen/regressions/kt756.jet b/compiler/testData/codegen/regressions/kt756.jet new file mode 100644 index 00000000000..4cff1aecd11 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt756.jet @@ -0,0 +1,12 @@ +namespace demo_range + +fun Int?.plus() : Int = this.sure().plus() +fun Int?.dec() : Int = this.sure().dec() +fun Int?.inc() : Int = this.sure().inc() +fun Int?.minus() : Int = this.sure().minus() + +fun box() : String { + val x : Int? = 10 + System.out?.println(x?.inv())// * x?.plus() * x?.dec() * x?.minus() as Number) + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index c5616a811a0..0c7ad33b70b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -287,37 +287,31 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testKt711 () throws Exception { loadText("fun box() = if ((1 ?: 0) == 1) \"OK\" else \"fail\""); -// System.out.println(generateToText()); blackBox(); } public void testSureNonnull () throws Exception { loadText("fun box() = 10.sure().toString()"); -// System.out.println(generateToText()); assertFalse(generateToText().contains("IFNONNULL")); } public void testSureNullable () throws Exception { loadText("val a : Int? = 10; fun box() = a.sure().toString()"); -// System.out.println(generateToText()); assertTrue(generateToText().contains("IFNONNULL")); } public void testSafeNonnull () throws Exception { loadText("fun box() = 10?.toString()"); -// System.out.println(generateToText()); assertFalse(generateToText().contains("IFNULL")); } public void testSafeNullable () throws Exception { loadText("val a : Int? = 10; fun box() = a?.toString()"); -// System.out.println(generateToText()); assertTrue(generateToText().contains("IFNULL")); } public void testKt737() throws Exception { loadText("fun box() = if(3.compareTo(2) != 1) \"fail\" else if(5.byt.compareTo(10.lng) >= 0) \"fail\" else \"OK\""); -// System.out.println(generateToText()); assertEquals("OK", blackBox()); } @@ -334,27 +328,27 @@ public class PrimitiveTypesTest extends CodegenTestCase { " System.out?.println(f(six))\n" + " return \"OK\"" + "}"); -// System.out.println(generateToText()); blackBox(); } public void testKt752 () { blackBoxFile("regressions/kt752.jet"); -// System.out.println(generateToText()); } public void testKt753 () { blackBoxFile("regressions/kt753.jet"); -// System.out.println(generateToText()); } public void testKt684 () { blackBoxFile("regressions/kt684.jet"); -// System.out.println(generateToText()); + } + + public void testKt756 () { + blackBoxFile("regressions/kt756.jet"); + System.out.println(generateToText()); } public void testKt757 () { blackBoxFile("regressions/kt757.jet"); -// System.out.println(generateToText()); } }