KT-756 incorrect intrinsics on nullable numbers

This commit is contained in:
Alex Tkachman
2011-12-06 15:03:26 +02:00
parent 29ebb124c8
commit ecb323a13e
7 changed files with 85 additions and 25 deletions
@@ -24,20 +24,38 @@ public class Increment implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> 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);
}
}
@@ -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);
@@ -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<JetExpression> 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);
@@ -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<JetExpression> 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);
}
@@ -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<JetExpression> arguments, StackValue receiver) {
boolean nullable = expectedType.getSort() == Type.OBJECT;
if(nullable) {
expectedType = JetTypeMapper.unboxType(expectedType);
}
receiver.put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -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"
}
@@ -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());
}
}