KT-756 incorrect intrinsics on nullable numbers
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user