diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index cc0a20b79f3..0a2289ae946 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -51,6 +51,7 @@ public class ExpressionCodegen extends JetVisitor { private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V"; private static final Type OBJECT_TYPE = Type.getType(Object.class); + private static final Type INTEGER_TYPE = Type.getType(Integer.class); private static final Type ITERATOR_TYPE = Type.getType(Iterator.class); private static final Type THROWABLE_TYPE = Type.getType(Throwable.class); @@ -1026,7 +1027,7 @@ public class ExpressionCodegen extends JetVisitor { private void generateRange(JetBinaryExpression expression) { final Type leftType = expressionType(expression.getLeft()); - if (isIntPrimitive(leftType)) { + if (JetTypeMapper.isIntPrimitive(leftType)) { v.anew(INT_RANGE_TYPE); v.dup(); gen(expression.getLeft(), Type.INT_TYPE); @@ -1058,11 +1059,7 @@ public class ExpressionCodegen extends JetVisitor { } private static boolean isNumberPrimitive(Type type) { - return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE; - } - - private static boolean isIntPrimitive(Type type) { - return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE; + return JetTypeMapper.isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE; } private static int opcodeForMethod(final String name) { @@ -1242,7 +1239,7 @@ public class ExpressionCodegen extends JetVisitor { int increment = op.getName().equals("inc") ? 1 : -1; if (operand instanceof JetReferenceExpression) { final int index = indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(asmType)) { + if (index >= 0 && JetTypeMapper.isIntPrimitive(asmType)) { v.iinc(index, increment); return StackValue.local(index, asmType); } @@ -1617,7 +1614,7 @@ public class ExpressionCodegen extends JetVisitor { else if (condition instanceof JetWhenConditionInRange) { JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression(); gen(range, RANGE_TYPE); - new StackValue.Local(subjectLocal, subjectType).put(OBJECT_TYPE, v); + new StackValue.Local(subjectLocal, subjectType).put(INTEGER_TYPE, v); v.invokeinterface(CLASS_RANGE, "contains", "(Ljava/lang/Comparable;)Z"); myStack.push(new StackValue.OnStack(Type.BOOLEAN_TYPE)); } diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index aca57213aa9..db398232569 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -40,6 +40,10 @@ public class JetTypeMapper { return qName.replace(".", "/"); } + static boolean isIntPrimitive(Type type) { + return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE; + } + public String jvmName(ClassDescriptor jetClass, OwnerKind kind) { PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass); if (declaration instanceof PsiClass) { diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 818986d7a4e..071843bc48c 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -75,8 +75,9 @@ public abstract class StackValue { return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type); } - private static void box(final Type type, InstructionAdapter v) { - if (type == Type.INT_TYPE) { + private static void box(final Type type, final Type toType, InstructionAdapter v) { + // TODO handle toType correctly + if (type == Type.INT_TYPE || (JetTypeMapper.isIntPrimitive(type) && toType.getInternalName().equals("java/lang/Integer"))) { v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (type == Type.BOOLEAN_TYPE) { @@ -131,7 +132,7 @@ public abstract class StackValue { protected void coerce(Type type, InstructionAdapter v) { if (type.getSort() == Type.OBJECT) { - box(this.type, v); + box(this.type, type, v); } else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) { unbox(type, v); diff --git a/idea/testData/codegen/patternMatching/rangeChar.jet b/idea/testData/codegen/patternMatching/rangeChar.jet new file mode 100644 index 00000000000..744855a20eb --- /dev/null +++ b/idea/testData/codegen/patternMatching/rangeChar.jet @@ -0,0 +1,4 @@ +fun isDigit(a: Char) = when(a) { + in '0'..'9' => "digit" + else => "something" +} diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index b8d2823880c..10aeafe3fb4 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -155,7 +155,12 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { protected Method generateFunction() { Class aClass = generateNamespaceClass(); - return aClass.getMethods()[0]; + try { + return aClass.getMethods()[0]; + } catch (Error e) { + System.out.println(generateToText()); + throw e; + } } protected Method generateFunction(String name) { diff --git a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java index 5ac5d30fb4c..bfd4208b3c6 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java @@ -42,6 +42,14 @@ public class PatternMatchingTest extends CodegenTestCase { assertEquals("something", foo.invoke(null, 19)); } + public void testRangeChar() throws Exception { + loadFile(); + System.out.println(generateToText()); + Method foo = generateFunction(); + assertEquals("digit", foo.invoke(null, '0')); + assertEquals("something", foo.invoke(null, 'A')); + } + public void testWildcardPattern() throws Exception { loadText("fun foo(x: String) = when(x) { is * => \"something\" }"); Method foo = generateFunction();