put values of correct type on stack for checking if character is in range

This commit is contained in:
Dmitry Jemerov
2011-05-27 18:29:48 +04:00
parent 6dfa8ca8c6
commit 9969b8d7a4
6 changed files with 31 additions and 12 deletions
@@ -51,6 +51,7 @@ public class ExpressionCodegen extends JetVisitor {
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V"; private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
private static final Type OBJECT_TYPE = Type.getType(Object.class); 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 ITERATOR_TYPE = Type.getType(Iterator.class);
private static final Type THROWABLE_TYPE = Type.getType(Throwable.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) { private void generateRange(JetBinaryExpression expression) {
final Type leftType = expressionType(expression.getLeft()); final Type leftType = expressionType(expression.getLeft());
if (isIntPrimitive(leftType)) { if (JetTypeMapper.isIntPrimitive(leftType)) {
v.anew(INT_RANGE_TYPE); v.anew(INT_RANGE_TYPE);
v.dup(); v.dup();
gen(expression.getLeft(), Type.INT_TYPE); gen(expression.getLeft(), Type.INT_TYPE);
@@ -1058,11 +1059,7 @@ public class ExpressionCodegen extends JetVisitor {
} }
private static boolean isNumberPrimitive(Type type) { private static boolean isNumberPrimitive(Type type) {
return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE; return JetTypeMapper.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;
} }
private static int opcodeForMethod(final String name) { private static int opcodeForMethod(final String name) {
@@ -1242,7 +1239,7 @@ public class ExpressionCodegen extends JetVisitor {
int increment = op.getName().equals("inc") ? 1 : -1; int increment = op.getName().equals("inc") ? 1 : -1;
if (operand instanceof JetReferenceExpression) { if (operand instanceof JetReferenceExpression) {
final int index = indexOfLocal((JetReferenceExpression) operand); final int index = indexOfLocal((JetReferenceExpression) operand);
if (index >= 0 && isIntPrimitive(asmType)) { if (index >= 0 && JetTypeMapper.isIntPrimitive(asmType)) {
v.iinc(index, increment); v.iinc(index, increment);
return StackValue.local(index, asmType); return StackValue.local(index, asmType);
} }
@@ -1617,7 +1614,7 @@ public class ExpressionCodegen extends JetVisitor {
else if (condition instanceof JetWhenConditionInRange) { else if (condition instanceof JetWhenConditionInRange) {
JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression(); JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression();
gen(range, RANGE_TYPE); 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"); v.invokeinterface(CLASS_RANGE, "contains", "(Ljava/lang/Comparable;)Z");
myStack.push(new StackValue.OnStack(Type.BOOLEAN_TYPE)); myStack.push(new StackValue.OnStack(Type.BOOLEAN_TYPE));
} }
@@ -40,6 +40,10 @@ public class JetTypeMapper {
return qName.replace(".", "/"); 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) { public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass); PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass);
if (declaration instanceof PsiClass) { if (declaration instanceof PsiClass) {
@@ -75,8 +75,9 @@ public abstract class StackValue {
return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type); return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type);
} }
private static void box(final Type type, InstructionAdapter v) { private static void box(final Type type, final Type toType, InstructionAdapter v) {
if (type == Type.INT_TYPE) { // 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;"); v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
} }
else if (type == Type.BOOLEAN_TYPE) { else if (type == Type.BOOLEAN_TYPE) {
@@ -131,7 +132,7 @@ public abstract class StackValue {
protected void coerce(Type type, InstructionAdapter v) { protected void coerce(Type type, InstructionAdapter v) {
if (type.getSort() == Type.OBJECT) { 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) { else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) {
unbox(type, v); unbox(type, v);
@@ -0,0 +1,4 @@
fun isDigit(a: Char) = when(a) {
in '0'..'9' => "digit"
else => "something"
}
@@ -155,7 +155,12 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
protected Method generateFunction() { protected Method generateFunction() {
Class aClass = generateNamespaceClass(); 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) { protected Method generateFunction(String name) {
@@ -42,6 +42,14 @@ public class PatternMatchingTest extends CodegenTestCase {
assertEquals("something", foo.invoke(null, 19)); 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 { public void testWildcardPattern() throws Exception {
loadText("fun foo(x: String) = when(x) { is * => \"something\" }"); loadText("fun foo(x: String) = when(x) { is * => \"something\" }");
Method foo = generateFunction(); Method foo = generateFunction();