KT-416
This commit is contained in:
@@ -1238,29 +1238,44 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
@Override
|
||||
public StackValue visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, StackValue receiver) {
|
||||
genToJVMStack(expression.getReceiverExpression());
|
||||
Label ifnull = new Label();
|
||||
Label end = new Label();
|
||||
v.dup();
|
||||
v.ifnull(ifnull);
|
||||
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
|
||||
StackValue propValue = genQualified(StackValue.onStack(typeMapper.mapType(receiverType)), expression.getSelectorExpression());
|
||||
Type type = propValue.type;
|
||||
propValue.put(type, v);
|
||||
if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) {
|
||||
StackValue.valueOf(v, type);
|
||||
type = JetTypeMapper.boxType(type);
|
||||
}
|
||||
v.goTo(end);
|
||||
JetExpression expr = expression.getReceiverExpression();
|
||||
JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
|
||||
Type receiverType = typeMapper.mapType(receiverJetType);
|
||||
gen(expr, receiverType);
|
||||
if(receiverType.getSort() != Type.OBJECT && receiverType.getSort() != Type.ARRAY) {
|
||||
StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
|
||||
Type type = propValue.type;
|
||||
propValue.put(type, v);
|
||||
if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) {
|
||||
StackValue.valueOf(v, type);
|
||||
type = JetTypeMapper.boxType(type);
|
||||
}
|
||||
|
||||
v.mark(ifnull);
|
||||
v.pop();
|
||||
if(!propValue.type.equals(Type.VOID_TYPE)) {
|
||||
v.aconst(null);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
v.mark(end);
|
||||
else {
|
||||
Label ifnull = new Label();
|
||||
Label end = new Label();
|
||||
v.dup();
|
||||
v.ifnull(ifnull);
|
||||
StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
|
||||
Type type = propValue.type;
|
||||
propValue.put(type, v);
|
||||
if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) {
|
||||
StackValue.valueOf(v, type);
|
||||
type = JetTypeMapper.boxType(type);
|
||||
}
|
||||
v.goTo(end);
|
||||
|
||||
return StackValue.onStack(type);
|
||||
v.mark(ifnull);
|
||||
v.pop();
|
||||
if(!propValue.type.equals(Type.VOID_TYPE)) {
|
||||
v.aconst(null);
|
||||
}
|
||||
v.mark(end);
|
||||
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
@@ -415,6 +416,34 @@ public class JetTypeMapper {
|
||||
throw new UnsupportedOperationException("Unknown type " + jetType);
|
||||
}
|
||||
|
||||
public static Type unboxType(final Type type) {
|
||||
if (type == JL_INTEGER_TYPE) {
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
else if (type == JL_BOOLEAN_TYPE) {
|
||||
return Type.BOOLEAN_TYPE;
|
||||
}
|
||||
else if (type == JL_CHAR_TYPE) {
|
||||
return Type.CHAR_TYPE;
|
||||
}
|
||||
else if (type == JL_SHORT_TYPE) {
|
||||
return Type.SHORT_TYPE;
|
||||
}
|
||||
else if (type == JL_LONG_TYPE) {
|
||||
return Type.LONG_TYPE;
|
||||
}
|
||||
else if (type == JL_BYTE_TYPE) {
|
||||
return Type.BYTE_TYPE;
|
||||
}
|
||||
else if (type == JL_FLOAT_TYPE) {
|
||||
return Type.FLOAT_TYPE;
|
||||
}
|
||||
else if (type == JL_DOUBLE_TYPE) {
|
||||
return Type.DOUBLE_TYPE;
|
||||
}
|
||||
throw new UnsupportedOperationException("Unboxing: " + type);
|
||||
}
|
||||
|
||||
public static Type boxType(Type asmType) {
|
||||
switch (asmType.getSort()) {
|
||||
case Type.VOID:
|
||||
|
||||
@@ -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;
|
||||
@@ -21,6 +22,10 @@ public class BinaryOp 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) {
|
||||
// intrinsic is called as an ordinary function
|
||||
if (receiver != null) {
|
||||
@@ -33,6 +38,10 @@ public class BinaryOp implements IntrinsicMethod {
|
||||
codegen.gen(arguments.get(1), expectedType);
|
||||
}
|
||||
v.visitInsn(expectedType.getOpcode(opcode));
|
||||
|
||||
if(nullable) {
|
||||
StackValue.onStack(expectedType).put(expectedType = JetTypeMapper.boxType(expectedType), v);
|
||||
}
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fun box() : String {
|
||||
var a = 10
|
||||
return if(a?.plus(10) == 20) "OK" else "fail"
|
||||
}
|
||||
@@ -207,4 +207,9 @@ public class ControlStructuresTest extends CodegenTestCase {
|
||||
public void testKt299() throws Exception {
|
||||
blackBoxFile("regressions/kt299.jet");
|
||||
}
|
||||
|
||||
public void testKt416() throws Exception {
|
||||
blackBoxFile("regressions/kt416.jet");
|
||||
System.out.println(generateToText());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user