From 232fc89cca08dea8648c8ee1b6cb274a40876cf5 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Mon, 5 Sep 2011 08:18:51 +0200 Subject: [PATCH] fix for KT-80 --- .../jet/codegen/ExpressionCodegen.java | 57 +++++++++++++++++-- .../org/jetbrains/jet/codegen/StackValue.java | 14 ++++- .../codegen/patternMatching/range.jet | 13 ++++- .../jet/codegen/PatternMatchingTest.java | 4 ++ 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f5cd80ccf2b..493730ebc98 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -809,7 +809,7 @@ public class ExpressionCodegen extends JetVisitor { v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, functionDescriptor.getName(), typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getDescriptor()); StackValue.onStack(typeMapper.mapType(functionDescriptor.getReturnType())).coerce(type, v); } - + public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, boolean forceInterface) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; @@ -1990,11 +1990,42 @@ public class ExpressionCodegen extends JetVisitor { @Nullable Label nextEntry) { StackValue conditionValue; if (condition instanceof JetWhenConditionInRange) { - JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression(); - gen(range, RANGE_TYPE); - new StackValue.Local(subjectLocal, subjectType).put(INTEGER_TYPE, v); - v.invokeinterface(CLASS_RANGE, "contains", "(Ljava/lang/Comparable;)Z"); - conditionValue = new StackValue.OnStack(Type.BOOLEAN_TYPE); + JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition; + JetExpression rangeExpression = conditionInRange.getRangeExpression(); + if(isIntRangeExpr(rangeExpression)) { + v.iconst(1); + //noinspection ConstantConditions + new StackValue.Local(subjectLocal, subjectType).put(Type.INT_TYPE, v); + JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression; + gen(binaryExpression.getLeft(), Type.INT_TYPE); + Label lok = new Label(); + v.ificmpge(lok); + v.pop(); + v.iconst(0); + v.mark(lok); + + v.iconst(1); + new StackValue.Local(subjectLocal, subjectType).put(Type.INT_TYPE, v); + gen(binaryExpression.getRight(), Type.INT_TYPE); + Label rok = new Label(); + v.ificmple(rok); + v.pop(); + v.iconst(0); + v.mark(rok); + + v.and(Type.INT_TYPE); + if(conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN) { + v.iconst(1); + v.xor(Type.INT_TYPE); + } + } + else { + FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); + genToJVMStack(rangeExpression); + new StackValue.Local(subjectLocal, subjectType).put(JetTypeMapper.TYPE_OBJECT, v); + invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); + } + return StackValue.onStack(Type.BOOLEAN_TYPE); } else if (condition instanceof JetWhenConditionIsPattern) { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; @@ -2032,6 +2063,20 @@ public class ExpressionCodegen extends JetVisitor { return conditionValue; } + private boolean isIntRangeExpr(JetExpression rangeExpression) { + if(rangeExpression instanceof JetBinaryExpression) { + JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression; + if (binaryExpression.getOperationReference().getReferencedNameElementType() == JetTokens.RANGE) { + JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, rangeExpression); + final DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); + if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses + return true; + } + } + } + return false ; + } + @Override public StackValue visitTupleExpression(JetTupleExpression expression, StackValue receiver) { final List entries = expression.getEntries(); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 9a7269853a0..6ff96e485c3 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -275,7 +275,19 @@ public abstract class StackValue { @Override public void put(Type type, InstructionAdapter v) { - v.aconst(value); + if(value instanceof Integer) + v.iconst((Integer) value); + else + if(value instanceof Long) + v.lconst((Long) value); + else + if(value instanceof Float) + v.fconst((Float) value); + else + if(value instanceof Double) + v.dconst((Double) value); + else + v.aconst(value); coerce(type, v); } diff --git a/idea/testData/codegen/patternMatching/range.jet b/idea/testData/codegen/patternMatching/range.jet index 329a4234971..5010f350b68 100644 --- a/idea/testData/codegen/patternMatching/range.jet +++ b/idea/testData/codegen/patternMatching/range.jet @@ -1,4 +1,11 @@ -fun isDigit(a: Int) = when(a) { - in 0..9 => "digit" - else => "something" +fun isDigit(a: Int) : String { + val aa = java.util.ArrayList () + aa.add(239) + + return when(a) { + in aa => "array list" + in 0..9 => "digit" + !in 0..100 => "not small" + else => "something" + } } diff --git a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java index 98a29598db0..29637ec910a 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java @@ -39,8 +39,12 @@ public class PatternMatchingTest extends CodegenTestCase { loadFile(); System.out.println(generateToText()); Method foo = generateFunction(); + assertEquals("array list", foo.invoke(null, 239)); + assertEquals("digit", foo.invoke(null, 0)); assertEquals("digit", foo.invoke(null, 9)); + assertEquals("digit", foo.invoke(null, 5)); assertEquals("something", foo.invoke(null, 19)); + assertEquals("not small", foo.invoke(null, 190)); } public void testRangeChar() throws Exception {